diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bb74beb --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +.PHONY: main.go +bubw: + go build -o bub.exe + +bubl: + export GOOS=linux; export GOARCH=amd64; go build -o bub \ No newline at end of file diff --git a/commands.go b/commands.go new file mode 100644 index 0000000..b989ce8 --- /dev/null +++ b/commands.go @@ -0,0 +1,63 @@ +package main + +import ( + "io" + "log" + "net/http" + + "github.com/bwmarrin/discordgo" +) + +var client = &http.Client{} + +type CommandFunction func(s *discordgo.Session, m *discordgo.MessageCreate) + +func InitCommands(s *discordgo.Session) { + s.AddHandler(commandHandler("greet", greetCommand)) + s.AddHandler(commandHandler("dadjoke", dadJokeCommand)) +} + +func commandHandler(commandName string, handler CommandFunction) func(s *discordgo.Session, m *discordgo.MessageCreate) { + return func(s *discordgo.Session, m *discordgo.MessageCreate) { + if m.Content != "!"+commandName { + return + } + + handler(s, m) + } +} + +func greetCommand(s *discordgo.Session, m *discordgo.MessageCreate) { + greeting := `Hello! I'm Bub! I am a bot created for the Hubbub. +I was created by RageCage. Ask him for more info if you're interested in looking at my source code!` + s.ChannelMessageSend(m.ChannelID, greeting) +} + +func dadJokeCommand(s *discordgo.Session, m *discordgo.MessageCreate) { + errorMessage := "I couldn't get a dad joke! Tell RageCage to check on me. :)" + req, err := http.NewRequest("GET", "https://icanhazdadjoke.com/", nil) + if err != nil { + log.Println(err) + s.ChannelMessageSend(m.ChannelID, errorMessage) + return + } + + req.Header.Add("Accept", "text/plain") + jokeResponse, err := client.Do(req) + if err != nil { + log.Println(err) + s.ChannelMessageSend(m.ChannelID, errorMessage) + return + } + defer jokeResponse.Body.Close() + + jokeBytes, err := io.ReadAll(jokeResponse.Body) + if err != nil { + log.Println(err) + s.ChannelMessageSend(m.ChannelID, errorMessage) + return + } + joke := string(jokeBytes) + log.Println(joke) + s.ChannelMessageSend(m.ChannelID, joke) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..6cf9f3e --- /dev/null +++ b/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "log" + "os" + "os/signal" + "syscall" + + "github.com/bwmarrin/discordgo" +) + +func main() { + token := getBotToken() + discord, err := discordgo.New("Bot " + token) + if err != nil { + log.Fatal(err) + } + + InitCommands(discord) + InitRoleReactions(discord) + + err = discord.Open() + if err != nil { + log.Fatal("No connection, rip") + } + defer discord.Close() + + log.Println("Bub is alive!") + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) + <-sc +} + +func getBotToken() string { + token := os.Getenv("BOT_TOKEN") + if token == "" { + token = os.Args[1] + if token == "" { + log.Fatal("No BOT_TOKEN variable set in environment!") + } + } + return token +} diff --git a/roles.go b/roles.go new file mode 100644 index 0000000..e53bd73 --- /dev/null +++ b/roles.go @@ -0,0 +1,127 @@ +package main + +import ( + "fmt" + "log" + + "github.com/bwmarrin/discordgo" +) + +type RoleReaction struct { + RoleName string + RoleId string + EmojiName string + EmojiId string +} + +type ServerRoleAssignConfig struct { + GuildId string + RoleReactionMap map[string]RoleReaction + Message *discordgo.Message +} + +type ServerConfigOptionFunction func(s *discordgo.Session) ServerRoleAssignConfig + +func InitRoleReactions(s *discordgo.Session) { + addHubbubHandlers(s) +} + +func addHubbubHandlers(s *discordgo.Session) { + hubbubId := "827958531659530301" + roleAssignChannelId := "855923187354959872" + roleMap := map[string]RoleReaction{ + "🤓": { + RoleName: "Streamer", + RoleId: "827959638267002880", + EmojiName: "nerd", + EmojiId: "🤓", + }, + "😎": { + RoleName: "Viewer", + RoleId: "857793953125629992", + EmojiName: "sunglasses", + EmojiId: "😎", + }, + } + serverConfig := getServerConfig( + s, + hubbubId, + roleAssignChannelId, + roleMap, + ) + s.AddHandler(roleAddHandler(serverConfig)) + s.AddHandler(roleRemoveHandler(serverConfig)) +} + +func getServerConfig( + s *discordgo.Session, + guildId string, + roleAssignChannelId string, + roleMap map[string]RoleReaction, +) ServerRoleAssignConfig { + serverConfig := ServerRoleAssignConfig{ + GuildId: guildId, + RoleReactionMap: roleMap, + } + + messages, err := s.ChannelMessages(roleAssignChannelId, 1, "", "", "") + if err != nil { + log.Fatal(err) + } + + if len(messages) == 0 { + content := "React to this message to get a role!\n" + for emote, role := range roleMap { + content += fmt.Sprintf("%s : %s\n", emote, role.RoleName) + } + message, err := s.ChannelMessageSend(roleAssignChannelId, content) + if err != nil { + log.Fatal(err) + } + for _, role := range roleMap { + err := s.MessageReactionAdd(roleAssignChannelId, message.ID, role.EmojiId) + if err != nil { + log.Fatal(err) + } + } + serverConfig.Message = message + } else { + serverConfig.Message = messages[0] + } + + return serverConfig +} + +func roleAddHandler( + serverConfig ServerRoleAssignConfig, +) func(s *discordgo.Session, r *discordgo.MessageReactionAdd) { + return func(s *discordgo.Session, r *discordgo.MessageReactionAdd) { + if r.MessageID != serverConfig.Message.ID { + return + } + + if role, ok := serverConfig.RoleReactionMap[r.Emoji.Name]; ok { + err := s.GuildMemberRoleAdd(serverConfig.GuildId, r.UserID, role.RoleId) + if err != nil { + log.Println(err) + } + } + } +} + +func roleRemoveHandler( + serverConfig ServerRoleAssignConfig, +) func(s *discordgo.Session, r *discordgo.MessageReactionRemove) { + return func(s *discordgo.Session, r *discordgo.MessageReactionRemove) { + if r.MessageID != serverConfig.Message.ID { + return + } + + if role, ok := serverConfig.RoleReactionMap[r.Emoji.Name]; ok { + err := s.GuildMemberRoleRemove(serverConfig.GuildId, r.UserID, role.RoleId) + if err != nil { + log.Println(err) + } + } + } +}