This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiscordFuncs.go
477 lines (425 loc) · 15.3 KB
/
discordFuncs.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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
// for any misc discord functions
package main
import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
"github.com/bwmarrin/discordgo"
"github.com/dustin/go-humanize"
"go.mongodb.org/mongo-driver/mongo"
)
// GetChannelData gets channel name and NSFW status
func GetChannelData(discord *discordgo.Session, channelID string, guildID string) (string, bool) {
fmt.Println("Getting channel data....")
name, nok := ServerMap[channelID]
nsfw, wok := NSFWMap[channelID]
if nok && wok {
fmt.Println("Values cached.")
return name, nsfw
}
starttime := GetMillis()
fmt.Println("Checking database....")
nsfw, name, err := GetChannelFromDB(channelID)
if err == nil {
fmt.Println("Channel found in database, adding to RAM....")
ServerMap[channelID] = name
NSFWMap[channelID] = nsfw
endtime := GetMillis()
t := endtime - starttime
fmt.Println("Time to get channel name: " + strconv.FormatInt(t, 10) + "ms")
return name, nsfw
}
if err != nil && err != mongo.ErrNoDocuments {
return channelID, false
}
channels, err := discord.GuildChannels(guildID)
if err != nil {
fmt.Println("Error getting channel data: ", err)
return channelID, false
}
for _, channel := range channels {
if channel.ID == channelID {
ServerMap[channelID] = channel.Name
NSFWMap[channelID] = channel.NSFW
endtime := GetMillis()
t := endtime - starttime
fmt.Println("Time to get channel name: " + strconv.FormatInt(t, 10) + "ms")
go AddChannelToDB(channel.ID, channel.NSFW, channel.Name)
return channel.Name, channel.NSFW
}
}
return channelID, false
}
// updates the bot status
func updateStatus(discord *discordgo.Session) {
servers := discord.State.Guilds
serverCount := int64(len(servers))
err := discord.UpdateStatus(0, "on "+humanize.Comma(serverCount)+" servers")
if err != nil {
fmt.Println("Error updating the status: ", err)
}
}
// gets a buzzword. See buzz.go
func getBuzzWord(discord *discordgo.Session, channel string) error {
statement := getABuzzWord()
_, err := discord.ChannelMessageSend(channel, statement)
return err
}
// send routine for embedded messages
func embedSendRoutine(discord *discordgo.Session, channel string, sub string, title string, url string, score int32) {
rand.Seed(time.Now().Unix())
randColor := rand.Intn(0xffffff) // skipcq
embed := &discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{},
Color: randColor,
Description: "From r/" + sub + "\n Score: " + humanize.Comma(int64(score)),
Image: &discordgo.MessageEmbedImage{
URL: url,
},
Timestamp: time.Now().Format(time.RFC3339),
Title: title,
}
_, err := discord.ChannelMessageSendEmbed(channel, embed)
if err != nil {
if strings.Contains(err.Error(), fmt.Sprint(discordgo.ErrCodeUnknownChannel)) {
fmt.Println("Channel either was deleted or the bot does not have access to it. Removing all entries from database.")
err = RemoveChannelFromDBAllTables(channel)
if err != nil {
fmt.Println(err)
}
} else {
fmt.Println("Error posting to channel:", err.Error())
}
}
}
// sending a text message routine
func successSendRoutine(discord *discordgo.Session, channel string, sub string, textone string, texttwo string, score int32) {
_, err := discord.ChannelMessageSend(channel, "From r/"+sub+"\n"+textone+"\n"+texttwo+"\nScore: "+humanize.Comma(int64(score)))
if err != nil {
if strings.Contains(err.Error(), fmt.Sprint(discordgo.ErrCodeUnknownChannel)) || strings.Contains(err.Error(), fmt.Sprint(discordgo.ErrCodeMissingAccess)) {
fmt.Println("Channel either was deleted or the bot does not have access to it. Removing all entries from database.")
err = RemoveChannelFromDBAllTables(channel)
if err != nil {
fmt.Println(err)
}
} else if strings.Contains(err.Error(), "Must be 2000 or fewer in length.") {
fmt.Println(err)
_, err = discord.ChannelMessageSend(channel, "Sorry, but the requested content is too long to be sent via Discord. Please try again.")
if err != nil {
fmt.Println(err)
}
} else {
fmt.Println("Error posting to channel:")
fmt.Println(err)
}
}
}
// banned subreddit routine
func bannedSendRoutine(discord *discordgo.Session, channel string, sub string) {
discord.ChannelMessageSend(channel, "Error!\nToo many attempts due to find an acceptable post due to a banned subreddit: "+sub)
}
// nsfw subreddit not allowed routine
func nsfwSendRoutine(discord *discordgo.Session, channel string) {
discord.ChannelMessageSend(channel, "Error!\nToo many tries to not find NSFW post, maybe that Subreddit is filled with them? Hint: Make sure that the channel is marked as \"NSFW\".")
}
func errSendRoutine(discord *discordgo.Session, channel string, err error) {
discord.ChannelMessageSend(channel, "Critical Error!\nThere was a critical error. "+err.Error()+" Please report this if possible to the Github page: https://github.com/chand1012/Discord-Quick-Meme/issues")
}
// loop routine that gets posts from the cache.
func getPostLoop(subs []string, postType string, channel string, channelNsfw bool, sort string) (string, int32, string, string, bool, bool) {
var returnPost QuickPost
var sub string
var score int32
var url string
var title string
var nsfw bool
bannedToggle := false
toggled := false
bannedSubs, err := GetAllBannedSubs(channel)
if err != nil {
fmt.Println("Error getting banned subreddits: ", err)
}
for i := 0; i < 10; i++ {
returnPost, sub = GetPost(subs, 100, sort, postType)
blacklisted := CheckBlacklist(channel, returnPost)
banned := stringInSlice(sub, bannedSubs)
if !banned {
LastPost[channel] = returnPost
}
score = returnPost.Score
url = returnPost.Content
title = returnPost.Title
nsfw = returnPost.Nsfw
if nsfw {
fmt.Println("Post is NSFW.")
}
// complicated but it makes sense ish
if (channelNsfw && !blacklisted && !banned) || (channelNsfw && !nsfw && !blacklisted && !banned) {
toggled = true
AddToBlacklist(channel, returnPost)
break
} else if !channelNsfw && !nsfw && !blacklisted && !banned {
toggled = true
break
} else {
if !blacklisted && !banned {
fmt.Println("Channel is not NSFW but post is NSFW, retrying....")
} else if banned {
fmt.Println("Channel banned sub " + sub + ", retrying...")
if i == 9 {
bannedToggle = true
}
}
}
}
return sub, score, url, title, toggled, bannedToggle
}
// gets a media post and sends it
func getMediaPost(discord *discordgo.Session, channel string, channelNsfw bool, subs []string, sort string) {
var score int32
var url string
var title string
var sub string
var bannedToggle bool
var toggled bool
imageEndings := []string{".jpg", ".png", ".jpeg"}
sub, score, url, title, toggled, bannedToggle = getPostLoop(subs, "media", channel, channelNsfw, sort)
if ContainsAnySubstring(url, imageEndings) && toggled {
embedSendRoutine(discord, channel, sub, title, url, score)
} else if toggled {
successSendRoutine(discord, channel, sub, url, title, score)
} else if bannedToggle {
bannedSendRoutine(discord, channel, sub)
} else {
nsfwSendRoutine(discord, channel)
}
}
// gets a text post and sends it
func getTextPost(discord *discordgo.Session, channel string, channelNsfw bool, subs []string, sort string) {
var score int32
var text string
var title string
var sub string
var bannedToggle bool
var toggled bool
sub, score, text, title, toggled, bannedToggle = getPostLoop(subs, "text", channel, channelNsfw, sort)
if toggled {
successSendRoutine(discord, channel, sub, title, text, score)
} else if bannedToggle {
bannedSendRoutine(discord, channel, sub)
} else {
nsfwSendRoutine(discord, channel)
}
}
// gets a link post and sends it
func getLinkPost(discord *discordgo.Session, channel string, channelNsfw bool, subs []string, sort string) {
var score int32
var url string
var title string
var sub string
var bannedToggle bool
var toggled bool
sub, score, url, title, toggled, bannedToggle = getPostLoop(subs, "link", channel, channelNsfw, sort)
if toggled {
successSendRoutine(discord, channel, sub, url, title, score)
} else if bannedToggle {
bannedSendRoutine(discord, channel, sub)
} else {
nsfwSendRoutine(discord, channel)
}
}
// gets the number of users across all servers with the bot
// Discordgo broke this, gonna keep it here in case it gets fixed
// func getNumberOfUsers(discord *discordgo.Session) int {
// count := 0
// for _, guild := range discord.State.Guilds {
// count += len(guild.Members)
// }
// return count
// }
// gets the user's member struct via their
// func getUserMemberFromGuild(discord *discordgo.Session, guildID string, user discordgo.User) discordgo.Member {
// guildObject, _ := discord.Guild(guildID)
// for _, member := range guildObject.Members {
// if member.User.ID == user.ID {
// return *member
// }
// }
// return discordgo.Member{}
// }
// checks if user is a memebot admin.
func isUserMemeBotAdmin(discord *discordgo.Session, guildID string, user *discordgo.User) bool {
adminCode := "memebot admin"
member, _ := discord.GuildMember(guildID, user.ID)
if member.User.ID == "" {
return false
}
guildRoles, _ := discord.GuildRoles(guildID)
for _, role := range guildRoles {
for _, roleID := range member.Roles {
if role.ID == roleID && strings.Contains(strings.ToLower(role.Name), adminCode) {
return true
}
}
}
return false
}
// gets the source of the last sent meme
func getSource(discord *discordgo.Session, channel string) error {
var err error
returnPost := LastPost[channel]
if returnPost.Permalink == "" {
_, err = discord.ChannelMessageSend(channel, "ERROR: Nothing has ever been sent on this channel!")
} else {
postlink := returnPost.Permalink
_, err = discord.ChannelMessageSend(channel, "Source: https://reddit.com"+postlink)
}
return err
}
// ban a subreddit routine
func banSubRoutine(discord *discordgo.Session, channel string, commandContent []string, guildID string, user *discordgo.User) {
if len(commandContent) != 4 {
discord.ChannelMessageSend(channel, "Incorrect command syntax! Correct syntax is `!quickmeme ban [mode] [subreddit]`\nMode can be `channel` or `server`.")
} else if isUserMemeBotAdmin(discord, guildID, user) { // fix this
if commandContent[2] == "server" {
channels, _ := discord.GuildChannels(guildID)
subreddits := textFilterSlice(commandContent[3:])
if subreddits == nil {
discord.ChannelMessageSend(channel, ErrorMsg)
return
}
for _, chat := range channels {
// this should be async to save time
for _, subreddit := range subreddits {
go SetBannedSubreddit(chat.ID, strings.ToLower(subreddit))
}
}
// this should be a message about the ban
discord.ChannelMessageSend(channel, user.Mention()+" banned subreddit(s) "+strings.Join(subreddits, ", ")+" on all channels.")
} else {
subreddits := textFilterSlice(commandContent[3:])
if subreddits == nil {
discord.ChannelMessageSend(channel, ErrorMsg)
return
}
for _, subreddit := range subreddits {
go SetBannedSubreddit(channel, subreddit)
}
discord.ChannelMessageSend(channel, user.Mention()+" banned subreddit(s) "+strings.Join(subreddits, ", ")+".")
}
} else {
discord.ChannelMessageSend(channel, ErrorMsg)
}
}
// unban a subreddit routine
func unbanSubRoutine(discord *discordgo.Session, channel string, commandContent []string, guildID string, user *discordgo.User) {
if len(commandContent) < 4 || len(commandContent) > 5 {
discord.ChannelMessageSend(channel, "Incorrect command syntax! Correct syntax is `!quickmeme unban [mode] [subreddit]`\nMode can be `channel` or `server`.")
} else if isUserMemeBotAdmin(discord, guildID, user) { // fix this
if commandContent[2] == "server" {
channels, _ := discord.GuildChannels(guildID)
subreddits := textFilterSlice(commandContent[3:])
if subreddits == nil {
discord.ChannelMessageSend(channel, ErrorMsg)
return
}
for _, chat := range channels {
// this should be async to save time
for _, subreddit := range subreddits {
go RemoveBannedSubreddit(chat.ID, subreddit)
}
}
// this should be a message about the ban
discord.ChannelMessageSend(channel, user.Mention()+" unbanned subreddit(s) "+strings.Join(subreddits, ", ")+" on all channels.")
} else {
// there should be a message about the ban here
subreddits := textFilterSlice(commandContent[3:])
if subreddits == nil {
discord.ChannelMessageSend(channel, ErrorMsg)
return
}
for _, subreddit := range subreddits {
go RemoveBannedSubreddit(channel, subreddit)
}
discord.ChannelMessageSend(channel, user.Mention()+" unbanned subreddit(s) "+strings.Join(subreddits, ", ")+".")
}
} else {
discord.ChannelMessageSend(channel, "Insufficient Permissions! You must have the \"Memebot Admin\" role to ban subreddits!")
}
}
// gets banned subreddits and send to channel
func getbannedSubRoutine(discord *discordgo.Session, channel string, commandContent []string, guildID string, user *discordgo.User) {
var banContext string
if len(commandContent) < 3 {
banContext = "channel"
} else {
banContext = commandContent[2]
}
if banContext == "server" {
channels, _ := discord.GuildChannels(guildID)
for _, chat := range channels {
bannedSubs, err := GetAllBannedSubs(chat.ID)
if err != nil {
discord.ChannelMessageSend(channel, ErrorMsg)
fmt.Println(err)
break
}
msgString := strings.Join(bannedSubs, ", ")
if msgString != "" && chat.Type == discordgo.ChannelTypeGuildText {
discord.ChannelMessageSend(channel, "Subs banned on "+chat.Name+":\n"+msgString)
}
}
} else {
bannedSubs, err := GetAllBannedSubs(channel)
if err != nil {
discord.ChannelMessageSend(channel, ErrorMsg)
fmt.Println(err)
} else {
msgString := strings.Join(bannedSubs, ", ")
discord.ChannelMessageSend(channel, "Subs banned on this channel:\n"+msgString)
}
}
}
func setQueueRoutine(discord *discordgo.Session, channel string, commandContent []string, channelNsfw bool) {
var err error
if len(commandContent) == 4 {
interval := commandContent[2]
expressions := []string{"[0-9]+m", "[0-9]+h", "[0-9]+d"}
match := matchRegexList(expressions, interval)
if !match {
discord.ChannelMessageSend(channel, "There was an error with your syntax, see here: https://bit.ly/DiscordQuickMemeAdminSyntax")
return
}
err = SetMemeQueue(channel, channelNsfw, interval, commandContent[3])
if err != nil {
fmt.Println("There was an error setting the Queue: " + err.Error())
errSendRoutine(discord, channel, err)
return
}
discord.ChannelMessageSend(channel, "Memes will now be sent at a regularly scheduled time.")
} else {
discord.ChannelMessageSend(channel, "There was an error with your syntax, see here: https://bit.ly/DiscordQuickMemeAdminSyntax")
return
}
}
func delQueueRoutine(discord *discordgo.Session, channel string) {
fmt.Println("Deleting channel", channel)
err := DeleteMemeQueue(channel)
fmt.Println("Checking for errors...")
if err == mongo.ErrNoDocuments {
discord.ChannelMessageSend(channel, "Error, this channel isn't subscribed.")
return
}
if err != nil {
fmt.Println("There was an error removing an item from the queue: ", err)
errSendRoutine(discord, channel, err)
return
}
discord.ChannelMessageSend(channel, "You have successfully unsubscribed this channel from memes.")
fmt.Println("Done.")
}
func helpRoutine(discord *discordgo.Session, channel string) {
discord.ChannelMessageSend(channel, "For command syntax, see here: https://github.com/chand1012/Discord-Quick-Meme#to-use")
}