Major Refactor (#2)
* Major reworks * More refactoring * Refactor feature complete! * Comments * Add versioning
This commit is contained in:
146
discord/channel.go
Normal file
146
discord/channel.go
Normal file
@ -0,0 +1,146 @@
|
||||
package discord
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/yeslayla/birdbot/core"
|
||||
)
|
||||
|
||||
// NewChannelFromID creates a channel from a given ID
|
||||
func (discord *Discord) NewChannelFromID(ID string) *core.Channel {
|
||||
channel, err := discord.session.Channel(ID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &core.Channel{
|
||||
ID: ID,
|
||||
Name: channel.Name,
|
||||
Verified: true,
|
||||
}
|
||||
}
|
||||
|
||||
// NewChannelFromName creates a channel object with its name
|
||||
func (discord *Discord) NewChannelFromName(channel_name string) (*core.Channel, error) {
|
||||
|
||||
// Grab channels to query
|
||||
channels, err := discord.session.GuildChannels(discord.guildID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list channels when creating new channel: '%s': %v", channel_name, err)
|
||||
}
|
||||
for _, channel := range channels {
|
||||
|
||||
// Found channel!
|
||||
if channel.Name == channel_name {
|
||||
|
||||
// Channel already exists!
|
||||
return &core.Channel{
|
||||
Name: channel.Name,
|
||||
ID: channel.ID,
|
||||
Verified: true,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Since a channel was not found, create one
|
||||
channel, err := discord.session.GuildChannelCreate(discord.guildID, channel_name, discordgo.ChannelTypeGuildText)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to created channel '%s': %v", channel_name, err)
|
||||
}
|
||||
|
||||
log.Printf("Created channel: '%s'", channel_name)
|
||||
return &core.Channel{
|
||||
Name: channel.Name,
|
||||
ID: channel.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetVerifiedChannel looks up channel data and returns a verified objec
|
||||
func (discord *Discord) GetVerifiedChannel(channel *core.Channel) *core.Channel {
|
||||
if channel.ID != "" {
|
||||
return discord.NewChannelFromID(channel.ID)
|
||||
}
|
||||
if channel.Name != "" {
|
||||
channel, err := discord.NewChannelFromName(channel.Name)
|
||||
if err != nil {
|
||||
log.Println("Failed to verify channel by name: ", err)
|
||||
}
|
||||
return channel
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteChannel deletes a channel
|
||||
func (discord *Discord) DeleteChannel(channel *core.Channel) (bool, error) {
|
||||
if channel.Verified == false {
|
||||
channel = discord.GetVerifiedChannel(channel)
|
||||
}
|
||||
|
||||
_, err := discord.session.ChannelDelete(channel.ID)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to delete channel: %v", err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// getChannelID returns a channel ID from its name
|
||||
func (discord *Discord) getChannelID(channel_name string) (string, error) {
|
||||
|
||||
// Get list of all channels
|
||||
channels, err := discord.session.GuildChannels(discord.guildID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to list channels when getting channel id: '%s': %v", channel_name, err)
|
||||
}
|
||||
|
||||
// Loop through to find channel
|
||||
for _, ch := range channels {
|
||||
|
||||
// Find and return ID!
|
||||
if ch.Name == channel_name {
|
||||
return ch.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("failed to get channel id for '%s': channel not found", channel_name)
|
||||
}
|
||||
|
||||
// SendMessage sends a message to a given channel
|
||||
func (discord *Discord) SendMessage(channel *core.Channel, message string) error {
|
||||
if channel.Verified == false {
|
||||
channel = discord.GetVerifiedChannel(channel)
|
||||
}
|
||||
|
||||
_, err := discord.session.ChannelMessageSend(channel.ID, message)
|
||||
return err
|
||||
}
|
||||
|
||||
// MoveChannelToCategory places a channel in a given category
|
||||
func (discord *Discord) MoveChannelToCategory(channel *core.Channel, categoryID string) error {
|
||||
if channel.Verified == false {
|
||||
channel = discord.GetVerifiedChannel(channel)
|
||||
}
|
||||
|
||||
// Move to archive category
|
||||
if _, err := discord.session.ChannelEdit(channel.ID, &discordgo.ChannelEdit{
|
||||
ParentID: categoryID,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to move channel to archive category: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ArchiveChannel archives a channel
|
||||
func (discord *Discord) ArchiveChannel(channel *core.Channel) error {
|
||||
if channel.Verified == false {
|
||||
channel = discord.GetVerifiedChannel(channel)
|
||||
}
|
||||
|
||||
_, err := discord.session.ChannelEdit(channel.ID, &discordgo.ChannelEdit{
|
||||
Archived: core.Bool(true),
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
97
discord/discord.go
Normal file
97
discord/discord.go
Normal file
@ -0,0 +1,97 @@
|
||||
package discord
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/yeslayla/birdbot/core"
|
||||
)
|
||||
|
||||
type Discord struct {
|
||||
mock.Mock
|
||||
|
||||
guildID string
|
||||
session *discordgo.Session
|
||||
|
||||
// Signal for shutdown
|
||||
stop chan os.Signal
|
||||
}
|
||||
|
||||
// New creates a new Discord session
|
||||
func New(guildID string, token string) *Discord {
|
||||
|
||||
// Create Discord Session
|
||||
session, err := discordgo.New(fmt.Sprint("Bot ", token))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create Discord session: %v", err)
|
||||
}
|
||||
|
||||
return &Discord{
|
||||
session: session,
|
||||
guildID: guildID,
|
||||
}
|
||||
}
|
||||
|
||||
// Run opens the Discod session until exit
|
||||
func (discord *Discord) Run() error {
|
||||
|
||||
if err := discord.session.Open(); err != nil {
|
||||
return fmt.Errorf("failed to open Discord session: %v", err)
|
||||
}
|
||||
defer discord.session.Close()
|
||||
|
||||
// Keep alive
|
||||
discord.stop = make(chan os.Signal, 1)
|
||||
signal.Notify(discord.stop, os.Interrupt)
|
||||
<-discord.stop
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop tells the Discord session to exit
|
||||
func (discord *Discord) Stop() {
|
||||
discord.stop <- os.Kill
|
||||
}
|
||||
|
||||
// OnReady registers a handler for when the Discord session is ready
|
||||
func (discord *Discord) OnReady(handler func(*Discord)) {
|
||||
discord.session.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
|
||||
handler(discord)
|
||||
})
|
||||
}
|
||||
|
||||
// OnEventCreate registers a handler when a guild scheduled event is created
|
||||
func (discord *Discord) OnEventCreate(handler func(*Discord, *core.Event)) {
|
||||
discord.session.AddHandler(func(s *discordgo.Session, r *discordgo.GuildScheduledEventCreate) {
|
||||
if r.GuildID != discord.guildID {
|
||||
return
|
||||
}
|
||||
event := NewEvent(r.GuildScheduledEvent)
|
||||
handler(discord, event)
|
||||
})
|
||||
}
|
||||
|
||||
// OnEventDelete registers a handler when a guild scheduled event is deleted
|
||||
func (discord *Discord) OnEventDelete(handler func(*Discord, *core.Event)) {
|
||||
discord.session.AddHandler(func(s *discordgo.Session, r *discordgo.GuildScheduledEventDelete) {
|
||||
if r.GuildID != discord.guildID {
|
||||
return
|
||||
}
|
||||
event := NewEvent(r.GuildScheduledEvent)
|
||||
handler(discord, event)
|
||||
})
|
||||
}
|
||||
|
||||
// OnEventUpdate registers a handler when a guild scheduled event is updated
|
||||
func (discord *Discord) OnEventUpdate(handler func(*Discord, *core.Event)) {
|
||||
discord.session.AddHandler(func(s *discordgo.Session, r *discordgo.GuildScheduledEventUpdate) {
|
||||
if r.GuildID != discord.guildID {
|
||||
return
|
||||
}
|
||||
event := NewEvent(r.GuildScheduledEvent)
|
||||
handler(discord, event)
|
||||
})
|
||||
}
|
28
discord/event.go
Normal file
28
discord/event.go
Normal file
@ -0,0 +1,28 @@
|
||||
package discord
|
||||
|
||||
import (
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/yeslayla/birdbot/core"
|
||||
)
|
||||
|
||||
// NewEvent converts a discordgo.GuildScheduledEvent to birdbot event
|
||||
func NewEvent(guildEvent *discordgo.GuildScheduledEvent) *core.Event {
|
||||
event := &core.Event{
|
||||
Name: guildEvent.Name,
|
||||
ID: guildEvent.ID,
|
||||
Organizer: &core.User{
|
||||
ID: guildEvent.CreatorID,
|
||||
},
|
||||
DateTime: guildEvent.ScheduledStartTime,
|
||||
}
|
||||
|
||||
event.Completed = guildEvent.Status == discordgo.GuildScheduledEventStatusCompleted
|
||||
|
||||
if guildEvent.EntityType != discordgo.GuildScheduledEventEntityTypeExternal {
|
||||
event.Location = core.REMOTE_LOCATION
|
||||
} else {
|
||||
event.Location = guildEvent.EntityMetadata.Location
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
20
discord/user.go
Normal file
20
discord/user.go
Normal file
@ -0,0 +1,20 @@
|
||||
package discord
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/yeslayla/birdbot/core"
|
||||
)
|
||||
|
||||
// NewUser creates a new user object from a discordgo.User object
|
||||
func NewUser(user *discordgo.User) *core.User {
|
||||
if user == nil {
|
||||
log.Print("Cannot user object, user is nil!")
|
||||
return nil
|
||||
}
|
||||
|
||||
return &core.User{
|
||||
ID: user.ID,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user