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