main.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log"
  6. "os"
  7. "os/signal"
  8. "strings"
  9. "github.com/bwmarrin/discordgo"
  10. )
  11. // Bot parameters
  12. var (
  13. GuildID = flag.String("guild", "", "Test guild ID")
  14. BotToken = flag.String("token", "", "Bot access token")
  15. AppID = flag.String("app", "", "Application ID")
  16. Cleanup = flag.Bool("cleanup", true, "Cleanup of commands")
  17. )
  18. var s *discordgo.Session
  19. func init() { flag.Parse() }
  20. func init() {
  21. var err error
  22. s, err = discordgo.New("Bot " + *BotToken)
  23. if err != nil {
  24. log.Fatalf("Invalid bot parameters: %v", err)
  25. }
  26. }
  27. func searchLink(message, format, sep string) string {
  28. return fmt.Sprintf(format, strings.Join(
  29. strings.Split(
  30. message,
  31. " ",
  32. ),
  33. sep,
  34. ))
  35. }
  36. var (
  37. commands = []discordgo.ApplicationCommand{
  38. {
  39. Name: "rickroll-em",
  40. Type: discordgo.UserApplicationCommand,
  41. },
  42. {
  43. Name: "google-it",
  44. Type: discordgo.MessageApplicationCommand,
  45. },
  46. {
  47. Name: "stackoverflow-it",
  48. Type: discordgo.MessageApplicationCommand,
  49. },
  50. {
  51. Name: "godoc-it",
  52. Type: discordgo.MessageApplicationCommand,
  53. },
  54. {
  55. Name: "discordjs-it",
  56. Type: discordgo.MessageApplicationCommand,
  57. },
  58. {
  59. Name: "discordpy-it",
  60. Type: discordgo.MessageApplicationCommand,
  61. },
  62. }
  63. commandsHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
  64. "rickroll-em": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  65. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  66. Type: discordgo.InteractionResponseChannelMessageWithSource,
  67. Data: &discordgo.InteractionResponseData{
  68. Content: "Operation rickroll has begun",
  69. Flags: 1 << 6,
  70. },
  71. })
  72. if err != nil {
  73. panic(err)
  74. }
  75. ch, err := s.UserChannelCreate(
  76. i.ApplicationCommandData().TargetID,
  77. )
  78. if err != nil {
  79. _, err = s.FollowupMessageCreate(*AppID, i.Interaction, true, &discordgo.WebhookParams{
  80. Content: fmt.Sprintf("Mission failed. Cannot send a message to this user: %q", err.Error()),
  81. Flags: 1 << 6,
  82. })
  83. if err != nil {
  84. panic(err)
  85. }
  86. }
  87. _, err = s.ChannelMessageSend(
  88. ch.ID,
  89. fmt.Sprintf("%s sent you this: https://youtu.be/dQw4w9WgXcQ", i.Member.Mention()),
  90. )
  91. if err != nil {
  92. panic(err)
  93. }
  94. },
  95. "google-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  96. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  97. Type: discordgo.InteractionResponseChannelMessageWithSource,
  98. Data: &discordgo.InteractionResponseData{
  99. Content: searchLink(
  100. i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
  101. "https://google.com/search?q=%s", "+"),
  102. Flags: 1 << 6,
  103. },
  104. })
  105. if err != nil {
  106. panic(err)
  107. }
  108. },
  109. "stackoverflow-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  110. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  111. Type: discordgo.InteractionResponseChannelMessageWithSource,
  112. Data: &discordgo.InteractionResponseData{
  113. Content: searchLink(
  114. i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
  115. "https://stackoverflow.com/search?q=%s", "+"),
  116. Flags: 1 << 6,
  117. },
  118. })
  119. if err != nil {
  120. panic(err)
  121. }
  122. },
  123. "godoc-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  124. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  125. Type: discordgo.InteractionResponseChannelMessageWithSource,
  126. Data: &discordgo.InteractionResponseData{
  127. Content: searchLink(
  128. i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
  129. "https://pkg.go.dev/search?q=%s", "+"),
  130. Flags: 1 << 6,
  131. },
  132. })
  133. if err != nil {
  134. panic(err)
  135. }
  136. },
  137. "discordjs-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  138. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  139. Type: discordgo.InteractionResponseChannelMessageWithSource,
  140. Data: &discordgo.InteractionResponseData{
  141. Content: searchLink(
  142. i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
  143. "https://discord.js.org/#/docs/main/stable/search?query=%s", "+"),
  144. Flags: 1 << 6,
  145. },
  146. })
  147. if err != nil {
  148. panic(err)
  149. }
  150. },
  151. "discordpy-it": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  152. err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
  153. Type: discordgo.InteractionResponseChannelMessageWithSource,
  154. Data: &discordgo.InteractionResponseData{
  155. Content: searchLink(
  156. i.ApplicationCommandData().Resolved.Messages[i.ApplicationCommandData().TargetID].Content,
  157. "https://discordpy.readthedocs.io/en/stable/search.html?q=%s", "+"),
  158. Flags: 1 << 6,
  159. },
  160. })
  161. if err != nil {
  162. panic(err)
  163. }
  164. },
  165. }
  166. )
  167. func main() {
  168. s.AddHandler(func(s *discordgo.Session, r *discordgo.Ready) {
  169. log.Println("Bot is up!")
  170. })
  171. s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
  172. if h, ok := commandsHandlers[i.ApplicationCommandData().Name]; ok {
  173. h(s, i)
  174. }
  175. })
  176. cmdIDs := make(map[string]string, len(commands))
  177. for _, cmd := range commands {
  178. rcmd, err := s.ApplicationCommandCreate(*AppID, *GuildID, &cmd)
  179. if err != nil {
  180. log.Fatalf("Cannot create slash command %q: %v", cmd.Name, err)
  181. }
  182. cmdIDs[rcmd.ID] = rcmd.Name
  183. }
  184. err := s.Open()
  185. if err != nil {
  186. log.Fatalf("Cannot open the session: %v", err)
  187. }
  188. defer s.Close()
  189. stop := make(chan os.Signal, 1)
  190. signal.Notify(stop, os.Interrupt)
  191. <-stop
  192. log.Println("Graceful shutdown")
  193. if !*Cleanup {
  194. return
  195. }
  196. for id, name := range cmdIDs {
  197. err := s.ApplicationCommandDelete(*AppID, *GuildID, id)
  198. if err != nil {
  199. log.Fatalf("Cannot delete slash command %q: %v", name, err)
  200. }
  201. }
  202. }