From bbcf6ef6cf2634c589937c1b554d535236423afa Mon Sep 17 00:00:00 2001 From: Piper Pentagram Date: Fri, 8 Nov 2024 16:26:05 -0800 Subject: [PATCH 1/2] Create discord package and connect/disconnect handlers This change moves the discord session singleton to the internal/discord package, and implements basic Connect/Disconnect handlers. --- internal/discord/discord.go | 64 ++++++++++++++++++++++++++++++++++++ internal/discord/handlers.go | 21 ++++++++++++ internal/state/state.go | 7 ++-- main.go | 23 +++---------- start.sh | 2 +- 5 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 internal/discord/discord.go create mode 100644 internal/discord/handlers.go diff --git a/internal/discord/discord.go b/internal/discord/discord.go new file mode 100644 index 0000000..387b97e --- /dev/null +++ b/internal/discord/discord.go @@ -0,0 +1,64 @@ +package discord + +import ( + "errors" + "fmt" + + "github.com/bwmarrin/discordgo" + "gitlab.com/whom/bingobot/internal/logging" +) + +type Session struct { + connected bool + s *discordgo.Session +} + +var ( + session *Session + + ErrNotConnected = errors.New("session not connected") +) + +func Connect(token string) error { + // throw away err because discordgo.New() actually can't return an error. + // https://github.com/bwmarrin/discordgo/blob/da9e191069d09e1b467145f5758d9b11cb9cca0d/discord.go#L32 + s, _ := discordgo.New("Bot " + token) + + session = &Session{ + s: s, + } + + addHandlers() + + err := session.s.Open() + + if err != nil { + return fmt.Errorf("failed to open discord session: %s", err) + } + + return nil +} + +func Close() { + err := session.s.Close() + + if err != nil { + // don't bubble up this error because we can't do anything about it and + // the bot is exiting anyway. + logging.Error("could not close discord session gracefully", "type", "error", "error", err) + } + + session.connected = false +} + +func Connected() bool { + return session.connected +} + +func User(uid string) (*discordgo.User, error) { + if !Connected() { + return nil, ErrNotConnected + } + + return session.s.User(uid) +} diff --git a/internal/discord/handlers.go b/internal/discord/handlers.go new file mode 100644 index 0000000..c2d2c25 --- /dev/null +++ b/internal/discord/handlers.go @@ -0,0 +1,21 @@ +package discord + +import ( + "github.com/bwmarrin/discordgo" + "gitlab.com/whom/bingobot/internal/logging" +) + +func addHandlers() { + session.s.AddHandler(handleConnect) + session.s.AddHandler(handleDisconnect) +} + +func handleConnect(s *discordgo.Session, e *discordgo.Connect) { + session.connected = true + logging.Info("discord session connected") +} + +func handleDisconnect(s *discordgo.Session, e *discordgo.Disconnect) { + session.connected = false + logging.Info("discord session disconnected") +} diff --git a/internal/state/state.go b/internal/state/state.go index d2e93dd..8a0ea7c 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -13,7 +13,7 @@ import ( "sync" "time" - "github.com/bwmarrin/discordgo" + "gitlab.com/whom/bingobot/internal/discord" "gitlab.com/whom/bingobot/internal/logging" ) @@ -27,7 +27,6 @@ const ( EventValidationFailedError = "event failed validation: " ) -var DiscordSession *discordgo.Session var eventMutex sync.RWMutex var eventSubscriptionCache = [NumEventTypes][]chan Event{} var eventCache = []Event{} @@ -360,8 +359,8 @@ func (ue UserEvent) Data() map[string]string { } func (ue UserEvent) Validate() error { - if DiscordSession != nil { - _, err := DiscordSession.User(ue.uid) + if discord.Connected() { + _, err := discord.User(ue.uid) return err } else { // I would love to know how to actually fail here diff --git a/main.go b/main.go index cc1f1d6..d4a4d94 100644 --- a/main.go +++ b/main.go @@ -6,25 +6,19 @@ import ( "os" "os/signal" - "github.com/bwmarrin/discordgo" "gitlab.com/whom/bingobot/internal/config" + "gitlab.com/whom/bingobot/internal/discord" "gitlab.com/whom/bingobot/internal/logging" - "gitlab.com/whom/bingobot/internal/state" ) var ( - Token = flag.String("token", "", "Bot authentication token") - App = flag.String("app", "", "Application ID") - Guild = flag.String("guild", "", "Guild ID") // Do we want it to be tied to one server? + token = flag.String("token", "", "Bot authentication token") appConfig *config.AppConfig ) func main() { flag.Parse() - if *App == "" { - log.Fatal("application id is not set") - } var err error @@ -44,27 +38,18 @@ func main() { } func startBot() error { - state.DiscordSession, _ = discordgo.New("Bot " + *Token) + err := discord.Connect(*token) - err := state.DiscordSession.Open() if err != nil { - logging.Error("could not open discord session", "type", "error", "error", err) return err } - logging.Info("shutting down gracefully", "type", "shutdown") - sigch := make(chan os.Signal, 1) signal.Notify(sigch, os.Interrupt) <-sigch logging.Info("shutting down gracefully", "type", "shutdown") - - err = state.DiscordSession.Close() - if err != nil { - logging.Error("could not close discord session gracefully", "type", "error", "error", err) - return err - } + discord.Close() return nil } diff --git a/start.sh b/start.sh index afaaa8a..c2cc142 100755 --- a/start.sh +++ b/start.sh @@ -7,4 +7,4 @@ fi BOT_TOKEN=$(cat bot.token) -./bingobot --app ${APP_ID} --token ${BOT_TOKEN} \ No newline at end of file +./bingobot --token ${BOT_TOKEN} From 8b54f09a9506f5f7a0506f8bdd17ee7706ad3bbf Mon Sep 17 00:00:00 2001 From: Piper Pentagram Date: Fri, 8 Nov 2024 16:33:49 -0800 Subject: [PATCH 2/2] Check the session pointer for nil before calling session.connected --- internal/discord/discord.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/discord/discord.go b/internal/discord/discord.go index 387b97e..896ba1a 100644 --- a/internal/discord/discord.go +++ b/internal/discord/discord.go @@ -52,7 +52,7 @@ func Close() { } func Connected() bool { - return session.connected + return session != nil && session.connected } func User(uid string) (*discordgo.User, error) {