-
Notifications
You must be signed in to change notification settings - Fork 927
/
data.go
207 lines (167 loc) · 4.94 KB
/
data.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package dcmd
import (
"context"
"reflect"
"github.com/botlabs-gg/yagpdb/v2/lib/discordgo"
"github.com/botlabs-gg/yagpdb/v2/lib/dstate"
"github.com/pkg/errors"
)
// Data is a struct of data available to commands
type Data struct {
Cmd *RegisteredCommand
Args []*ParsedArg
Switches map[string]*ParsedArg
// These fields are always available
ChannelID int64
Author *discordgo.User
// Only set if this command was not ran through slash commands
TraditionalTriggerData *TraditionalTriggerData
// Only set if this command was ran through discord slash commands
SlashCommandTriggerData *SlashCommandTriggerData
// Only provided if the command was ran in a DM Context
GuildData *GuildContextData
// The session that triggered the command
Session *discordgo.Session
Source TriggerSource
TriggerType TriggerType
// The chain of containers we went through, first element is always root
ContainerChain []*Container
// The system that triggered this command
System *System
context context.Context
}
type GuildContextData struct {
CS *dstate.ChannelState
GS *dstate.GuildSet
MS *dstate.MemberState
}
type SlashCommandTriggerData struct {
Interaction *discordgo.Interaction
// The options slice for the command options themselves
// This is a helper so you don't have to dig it out yourself in the case of nested subcommands
Options []*discordgo.ApplicationCommandInteractionDataOption
}
type TraditionalTriggerData struct {
Message *discordgo.Message
MessageStrippedPrefix string
PrefixUsed string
}
// Context returns an always non-nil context
func (d *Data) Context() context.Context {
if d.context == nil {
return context.Background()
}
return d.context
}
func (d *Data) Switch(name string) *ParsedArg {
return d.Switches[name]
}
// WithContext creates a copy of d with the context set to ctx
func (d *Data) WithContext(ctx context.Context) *Data {
cop := new(Data)
*cop = *d
cop.context = ctx
return cop
}
func (d *Data) SendFollowupMessage(reply interface{}, allowedMentions discordgo.AllowedMentions) ([]*discordgo.Message, error) {
switch t := reply.(type) {
case Response:
return t.Send(d)
case string:
if t != "" {
return SplitSendMessage(d, t, allowedMentions)
}
return []*discordgo.Message{}, nil
case error:
if t != nil {
m := t.Error()
return SplitSendMessage(d, m, allowedMentions)
}
return []*discordgo.Message{}, nil
case *discordgo.MessageEmbed:
switch d.TriggerType {
case TriggerTypeSlashCommands:
m, err := d.Session.CreateFollowupMessage(d.SlashCommandTriggerData.Interaction.ApplicationID, d.SlashCommandTriggerData.Interaction.Token, &discordgo.WebhookParams{
Embeds: []*discordgo.MessageEmbed{t},
AllowedMentions: &allowedMentions,
})
return []*discordgo.Message{m}, err
default:
m, err := d.Session.ChannelMessageSendEmbed(d.ChannelID, t)
return []*discordgo.Message{m}, err
}
case []*discordgo.MessageEmbed:
msgs := make([]*discordgo.Message, 0, len(t))
switch d.TriggerType {
case TriggerTypeSlashCommands:
cur := 0
for {
next := t[cur:]
if len(next) > 10 {
next = next[:10]
}
params := &discordgo.WebhookParams{
Embeds: next,
AllowedMentions: &allowedMentions,
}
m, err := d.Session.CreateFollowupMessage(d.SlashCommandTriggerData.Interaction.ApplicationID, d.SlashCommandTriggerData.Interaction.Token, params)
if err != nil {
return msgs, err
}
msgs = append(msgs, m)
if len(t[cur:]) <= 10 {
break
}
cur += 10
}
default:
for _, embed := range t {
m, err := d.Session.ChannelMessageSendEmbed(d.ChannelID, embed)
if err != nil {
return msgs, err
}
msgs = append(msgs, m)
}
}
return msgs, nil
case *discordgo.MessageSend:
switch d.TriggerType {
case TriggerTypeSlashCommands:
params := &discordgo.WebhookParams{
Content: t.Content,
TTS: t.TTS,
AllowedMentions: &t.AllowedMentions,
File: t.File,
}
if len(t.Files) > 0 {
params.File = t.Files[0]
}
if len(t.Embeds) > 0 {
params.Embeds = t.Embeds
}
m, err := d.Session.CreateFollowupMessage(d.SlashCommandTriggerData.Interaction.ApplicationID, d.SlashCommandTriggerData.Interaction.Token, params)
return []*discordgo.Message{m}, err
default:
m, err := d.Session.ChannelMessageSendComplex(d.ChannelID, t)
return []*discordgo.Message{m}, err
}
}
return nil, errors.New("Unknown reply type: " + reflect.TypeOf(reply).String() + " (Does not implement Response)")
}
// Where this command comes from
type TriggerSource int
const (
TriggerSourceGuild TriggerSource = iota
TriggerSourceDM
)
type TriggerType int
const (
// triggered directly somehow, no prefix
TriggerTypeDirect TriggerType = iota
// triggered through a mention trigger
TriggerTypeMention
// triggered thourgh a prefix trigger
TriggerTypePrefix
// triggered through slash commands
TriggerTypeSlashCommands
)