diff --git a/examples/echo/README.md b/examples/echo/README.md new file mode 100644 index 000000000..9e604a0fa --- /dev/null +++ b/examples/echo/README.md @@ -0,0 +1,40 @@ +DiscordGo logo + +## DiscordGo Echo Example + +This example demonstrates how to utilize DiscordGo to create a simple, +slash commands based bot, that will echo your messages. + +**Join [Discord Gophers](https://discord.gg/0f1SbxBZjYoCtNPP) +Discord chat channel for support.** + +### Build + +This assumes you already have a working Go environment setup and that +DiscordGo is correctly installed on your system. + +From within the example folder, run the below command to compile the +example. + +```sh +go build +``` + +### Usage + +``` +Usage of echo: + -app string + Application ID + -guild string + Guild ID + -token string + Bot authentication token + +``` + +Run the command below to start the bot. + +```sh +./echo -guild YOUR_TESTING_GUILD -app YOUR_TESTING_APP -token YOUR_BOT_TOKEN +``` diff --git a/examples/echo/main.go b/examples/echo/main.go new file mode 100644 index 000000000..145719ff5 --- /dev/null +++ b/examples/echo/main.go @@ -0,0 +1,119 @@ +package main + +import ( + "flag" + "log" + "os" + "os/signal" + "strings" + + "github.com/bwmarrin/discordgo" +) + +type optmap = map[string]*discordgo.ApplicationCommandInteractionDataOption + +func parseOpts(options []*discordgo.ApplicationCommandInteractionDataOption) (om optmap) { + om = make(optmap) + for _, opt := range options { + om[opt.Name] = opt + } + return +} + +func interactionAuthor(i *discordgo.Interaction) *discordgo.User { + if i.Member != nil { + return i.Member.User + } + return i.User +} + +func handleEcho(s *discordgo.Session, i *discordgo.InteractionCreate, opts optmap) { + builder := new(strings.Builder) + if v, ok := opts["author"]; ok && v.BoolValue() { + author := interactionAuthor(i.Interaction) + builder.WriteString("**" + author.String() + "** says: ") + } + builder.WriteString(opts["message"].StringValue()) + + err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: builder.String(), + }, + }) + + if err != nil { + log.Panicf("could not respond to interaction: %s", err) + } +} + +var commands = []*discordgo.ApplicationCommand{ + { + Name: "echo", + Description: "Say something through a bot", + Options: []*discordgo.ApplicationCommandOption{ + { + Name: "message", + Description: "Contents of the message", + Type: discordgo.ApplicationCommandOptionString, + Required: true, + }, + { + Name: "author", + Description: "Whether to prepend message's author", + Type: discordgo.ApplicationCommandOptionBoolean, + }, + }, + }, +} + +var ( + Token = flag.String("token", "", "Bot authentication token") + App = flag.String("app", "", "Application ID") + Guild = flag.String("guild", "", "Guild ID") +) + +func main() { + flag.Parse() + if *App == "" { + log.Fatal("application id is not set") + } + + session, _ := discordgo.New("Bot " + *Token) + + session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + if i.Type != discordgo.InteractionApplicationCommand { + return + } + + data := i.ApplicationCommandData() + if data.Name != "echo" { + return + } + + handleEcho(s, i, parseOpts(data.Options)) + }) + + session.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) { + log.Printf("Logged in as %s", r.User.String()) + }) + + _, err := session.ApplicationCommandBulkOverwrite(*App, *Guild, commands) + if err != nil { + log.Fatalf("could not register commands: %s", err) + } + + err = session.Open() + if err != nil { + log.Fatalf("could not open session: %s", err) + } + + sigch := make(chan os.Signal, 1) + signal.Notify(sigch, os.Interrupt) + <-sigch + + err = session.Close() + if err != nil { + log.Println("could not close session gracefully: %s", err) + } +}