package main import ( "github.com/bwmarrin/discordgo" "log" "os" "os/signal" "strings" ) var s *discordgo.Session var prefix = os.Getenv("COMMAND_PREFIX") func init() { token := os.Getenv("DISCORD_TOKEN") var err error s, err = discordgo.New("Bot " + token) if err != nil { log.Fatalf("Invalid bot parameters: %v", err) } } func init() { s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { data := i.ApplicationCommandData() if h, ok := slashCommandHandlers[data.Name]; ok { h(s, i, parseOptions(data.Options)) } }) s.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) { if m.Author.ID == s.State.User.ID { return } messageContent := strings.Split(m.Content, " ") if !strings.HasPrefix(strings.ToLower(messageContent[0]), prefix) { return } messageContent[0] = messageContent[0][len(prefix):] if fun, ok := dotCommandHandlers[messageContent[0]]; ok { response := fun(messageContent[1:]) _, err := s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{ Content: response, Reference: m.Reference(), AllowedMentions: &discordgo.MessageAllowedMentions{ RepliedUser: false, }, }) if err != nil { log.Printf("Error sending message: %v", err) } } }) } type optionMap = map[string]*discordgo.ApplicationCommandInteractionDataOption func parseOptions(options []*discordgo.ApplicationCommandInteractionDataOption) (om optionMap) { om = make(optionMap) for _, opt := range options { om[opt.Name] = opt } return } func main() { s.AddHandler(func(s *discordgo.Session, i *discordgo.Ready) { log.Printf("Logged in as: %v#%v", s.State.User.Username, s.State.User.Discriminator) }) err := s.Open() if err != nil { log.Fatalf("Cannot open Discord session: %v", err) } log.Println("Adding commands") registeredCommands := make([]*discordgo.ApplicationCommand, len(commands)) for i, v := range commands { cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", v) if err != nil { log.Panicf("Cannot create '%v' command: %v", v.Name, err) } registeredCommands[i] = cmd } defer func(s *discordgo.Session) { err := s.Close() if err != nil { } }(s) stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) log.Println("Press Ctrl+C to exit") <-stop log.Println("Shutting down...") for _, v := range registeredCommands { err := s.ApplicationCommandDelete(s.State.User.ID, "", v.ID) if err != nil { log.Panicf("Cannot delete '%v' command: %v", v.Name, err) } } }