|
@@ -0,0 +1,222 @@
|
|
|
|
+package main
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "flag"
|
|
|
|
+ "fmt"
|
|
|
|
+ "log"
|
|
|
|
+ "os"
|
|
|
|
+ "os/signal"
|
|
|
|
+ "strings"
|
|
|
|
+
|
|
|
|
+ "github.com/bwmarrin/discordgo"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// Bot parameters
|
|
|
|
+var (
|
|
|
|
+ GuildID = flag.String("guild", "", "Test guild ID")
|
|
|
|
+ BotToken = flag.String("token", "", "Bot access token")
|
|
|
|
+ AppID = flag.String("app", "", "Application ID")
|
|
|
|
+ Cleanup = flag.Bool("cleanup", true, "Cleanup of commands")
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+var s *discordgo.Session
|
|
|
|
+
|
|
|
|
+func init() { flag.Parse() }
|
|
|
|
+
|
|
|
|
+func init() {
|
|
|
|
+ var err error
|
|
|
|
+ s, err = discordgo.New("Bot " + *BotToken)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatalf("Invalid bot parameters: %v", err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func searchLink(message, format, sep string) string {
|
|
|
|
+ return fmt.Sprintf(format, strings.Join(
|
|
|
|
+ strings.Split(
|
|
|
|
+ message,
|
|
|
|
+ " ",
|
|
|
|
+ ),
|
|
|
|
+ sep,
|
|
|
|
+ ))
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+var (
|
|
|
|
+ commands = []discordgo.ApplicationCommand{
|
|
|
|
+ {
|
|
|
|
+ Name: "rickroll-em",
|
|
|
|
+ Type: discordgo.UserApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Name: "google-it",
|
|
|
|
+ Type: discordgo.MessageApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Name: "stackoverflow-it",
|
|
|
|
+ Type: discordgo.MessageApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Name: "godoc-it",
|
|
|
|
+ Type: discordgo.MessageApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Name: "discordjs-it",
|
|
|
|
+ Type: discordgo.MessageApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ Name: "discordpy-it",
|
|
|
|
+ Type: discordgo.MessageApplicationCommand,
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ commandsHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
|
|
|
|
+ "rickroll-em": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: "Operation rickroll has begun",
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ch, err := s.UserChannelCreate(
|
|
|
|
+ i.ApplicationCommandData().TargetID,
|
|
|
|
+ )
|
|
|
|
+ if err != nil {
|
|
|
|
+ _, err = s.FollowupMessageCreate(*AppID, i.Interaction, true, &discordgo.WebhookParams{
|
|
|
|
+ Content: fmt.Sprintf("Mission failed. Cannot send a message to this user: %q", err.Error()),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _, err = s.ChannelMessageSend(
|
|
|
|
+ ch.ID,
|
|
|
|
+ fmt.Sprintf("%s sent you this: https://youtu.be/dQw4w9WgXcQ", i.Member.Mention()),
|
|
|
|
+ )
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "google-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: searchLink(
|
|
|
|
+ i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
|
|
|
|
+ "https://google.com/search?q=%s", "+"),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "stackoverflow-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: searchLink(
|
|
|
|
+ i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
|
|
|
|
+ "https://stackoverflow.com/search?q=%s", "+"),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "godoc-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: searchLink(
|
|
|
|
+ i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
|
|
|
|
+ "https://pkg.go.dev/search?q=%s", "+"),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "discordjs-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: searchLink(
|
|
|
|
+ i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
|
|
|
|
+ "https://discord.js.org/#/docs/main/stable/search?query=%s", "+"),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ "discordpy-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
|
|
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
|
|
+ Data: &discordgo.InteractionResponseData{
|
|
|
|
+ Content: searchLink(
|
|
|
|
+ i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
|
|
|
|
+ "https://discordpy.readthedocs.io/en/stable/search.html?q=%s", "+"),
|
|
|
|
+ Flags: 1 << 6,
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ panic(err)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+func main() {
|
|
|
|
+ s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
|
|
|
|
+ log.Println("Bot is up!")
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
|
|
+ if h, ok := commandsHandlers[i.ApplicationCommandData().Name]; ok {
|
|
|
|
+ h(s, i)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ cmdIDs := make(map[string]string, len(commands))
|
|
|
|
+
|
|
|
|
+ for _, cmd := range commands {
|
|
|
|
+ rcmd, err := s.ApplicationCommandCreate(*AppID, *GuildID, &cmd)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatalf("Cannot create slash command %q: %v", cmd.Name, err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cmdIDs[rcmd.ID] = rcmd.Name
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ err := s.Open()
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatalf("Cannot open the session: %v", err)
|
|
|
|
+ }
|
|
|
|
+ defer s.Close()
|
|
|
|
+
|
|
|
|
+ stop := make(chan os.Signal, 1)
|
|
|
|
+ signal.Notify(stop, os.Interrupt)
|
|
|
|
+ <-stop
|
|
|
|
+ log.Println("Graceful shutdown")
|
|
|
|
+
|
|
|
|
+ if !*Cleanup {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for id, name := range cmdIDs {
|
|
|
|
+ err := s.ApplicationCommandDelete(*AppID, *GuildID, id)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatalf("Cannot delete slash command %q: %v", name, err)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|