github.com/diamondburned/arikawa/v2@v2.1.0/_example/advanced_bot/bot.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/diamondburned/arikawa/v2/bot" 12 "github.com/diamondburned/arikawa/v2/bot/extras/arguments" 13 "github.com/diamondburned/arikawa/v2/bot/extras/middlewares" 14 "github.com/diamondburned/arikawa/v2/discord" 15 "github.com/diamondburned/arikawa/v2/gateway" 16 ) 17 18 type Bot struct { 19 // Context must not be embedded. 20 Ctx *bot.Context 21 } 22 23 func (bot *Bot) Setup(sub *bot.Subcommand) { 24 // Only allow people in guilds to run guildInfo. 25 sub.AddMiddleware(bot.GuildInfo, middlewares.GuildOnly(bot.Ctx)) 26 } 27 28 // Help prints the default help message. 29 func (bot *Bot) Help(*gateway.MessageCreateEvent) (string, error) { 30 return bot.Ctx.Help(), nil 31 } 32 33 // Add demonstrates the usage of typed arguments. Run it with "~add 1 2". 34 func (bot *Bot) Add(_ *gateway.MessageCreateEvent, a, b int) (string, error) { 35 return fmt.Sprintf("%d + %d = %d", a, b, a+b), nil 36 } 37 38 // Ping is a simple ping example, perhaps the most simple you could make it. 39 func (bot *Bot) Ping(*gateway.MessageCreateEvent) (string, error) { 40 return "Pong!", nil 41 } 42 43 // Say demonstrates how arguments.Flag could be used without the flag library. 44 func (bot *Bot) Say(_ *gateway.MessageCreateEvent, f bot.RawArguments) (string, error) { 45 if f != "" { 46 return string(f), nil 47 } 48 return "", errors.New("missing content") 49 } 50 51 // GuildInfo demonstrates the GuildOnly middleware done in (*Bot).Setup(). 52 func (bot *Bot) GuildInfo(m *gateway.MessageCreateEvent) (string, error) { 53 g, err := bot.Ctx.GuildWithCount(m.GuildID) 54 if err != nil { 55 return "", fmt.Errorf("failed to get guild: %v", err) 56 } 57 58 return fmt.Sprintf( 59 "Your guild is %s, and its maximum members is %d", 60 g.Name, g.ApproximateMembers, 61 ), nil 62 } 63 64 // Repeat tells the bot to wait for the user's response, then repeat what they 65 // said. 66 func (bot *Bot) Repeat(m *gateway.MessageCreateEvent) (string, error) { 67 _, err := bot.Ctx.SendMessage(m.ChannelID, "What do you want me to say?", nil) 68 if err != nil { 69 return "", err 70 } 71 72 ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 73 defer cancel() 74 75 // This might miss events that are sent immediately after. To make sure all 76 // events are caught, ChanFor should be used. 77 v := bot.Ctx.WaitFor(ctx, func(v interface{}) bool { 78 // Incoming event is a message create event: 79 mg, ok := v.(*gateway.MessageCreateEvent) 80 if !ok { 81 return false 82 } 83 84 // Message is from the same author: 85 return mg.Author.ID == m.Author.ID 86 }) 87 88 if v == nil { 89 return "", errors.New("timed out waiting for response") 90 } 91 92 ev := v.(*gateway.MessageCreateEvent) 93 return ev.Content, nil 94 } 95 96 // Embed is a simple embed creator. Its purpose is to demonstrate the usage of 97 // the ParseContent interface, as well as using the stdlib flag package. 98 func (bot *Bot) Embed(_ *gateway.MessageCreateEvent, f arguments.Flag) (*discord.Embed, error) { 99 fs := arguments.NewFlagSet() 100 101 var ( 102 title = fs.String("title", "", "Title") 103 author = fs.String("author", "", "Author") 104 footer = fs.String("footer", "", "Footer") 105 color = fs.String("color", "#FFFFFF", "Color in hex format #hhhhhh") 106 ) 107 108 if err := f.With(fs.FlagSet); err != nil { 109 return nil, err 110 } 111 112 if len(fs.Args()) < 1 { 113 return nil, fmt.Errorf("usage: embed [flags] content...\n" + fs.Usage()) 114 } 115 116 // Check if the color string is valid. 117 if !strings.HasPrefix(*color, "#") || len(*color) != 7 { 118 return nil, errors.New("invalid color, format must be #hhhhhh") 119 } 120 121 // Parse the color into decimal numbers. 122 colorHex, err := strconv.ParseInt((*color)[1:], 16, 64) 123 if err != nil { 124 return nil, err 125 } 126 127 // Make a new embed 128 embed := discord.Embed{ 129 Title: *title, 130 Description: strings.Join(fs.Args(), " "), 131 Color: discord.Color(colorHex), 132 } 133 134 if *author != "" { 135 embed.Author = &discord.EmbedAuthor{ 136 Name: *author, 137 } 138 } 139 if *footer != "" { 140 embed.Footer = &discord.EmbedFooter{ 141 Text: *footer, 142 } 143 } 144 145 return &embed, err 146 }