-
Notifications
You must be signed in to change notification settings - Fork 0
/
riddle_bot.py
720 lines (634 loc) · 33.9 KB
/
riddle_bot.py
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
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
import io
import json
import os
import random
import re
import time
from typing import Optional, List, Tuple
from discord import (
Client,
Message,
Member,
Guild,
CategoryChannel,
utils,
Embed,
Role,
PermissionOverwrite,
User,
DMChannel,
Color,
TextChannel,
File,
)
BELL = "🔔"
THUMBSUP = "👍"
THUMBSDOWN = "👎"
config: dict = json.load(open("config.json"))
GUILD: int = config["guild"]
NOTIFICATION_ROLE: int = config["notification_role"]
SETTINGS_CHANNEL: int = config["settings_channel"]
MASTER_OF_EVERYTHING_ROLE: int = config["master_of_everything_role"]
GENERAL_CHAT: int = config["general_chat"]
PREFIX = config["prefix"]
def create_embed(**kwargs):
embed = Embed(**kwargs)
embed.set_footer(text="Bot by @Defelo#2022")
return embed
def level_name(level_id):
return f"level-{level_id}"
def solution_name(level_id):
return f"solution-{level_id}"
def role_name(category, level_id):
return f"{category} - Level {level_id}"
def riddle_master_name(category):
return f"Master of {category}"
def category_name(category_id, category, escaped=False):
if escaped:
return fr"\[{category_id}\] {category} - Levels"
else:
return f"[{category_id}] {category} - Levels"
class Bot(Client):
def __init__(self):
super().__init__()
self.guild: Optional[Guild] = None
self.notification_role: Optional[Role] = None
self.settings_channel: Optional[TextChannel] = None
self.master_of_everything_role: Optional[Role] = None
self.general_chat: Optional[TextChannel] = None
self.settings_message: Optional[Message] = None
self.cooldowns = {}
async def on_ready(self):
print(f"Logged in as {self.user}")
self.guild: Guild = self.get_guild(GUILD)
self.notification_role: Role = self.guild.get_role(NOTIFICATION_ROLE)
self.settings_channel: TextChannel = self.guild.get_channel(SETTINGS_CHANNEL)
self.master_of_everything_role: Role = self.guild.get_role(MASTER_OF_EVERYTHING_ROLE)
self.general_chat: TextChannel = self.guild.get_channel(GENERAL_CHAT)
async for msg in self.settings_channel.history():
self.settings_message: Message = msg
break
def get_levels(self, category: str) -> List[int]:
out = []
for role in self.guild.roles:
if role.id == MASTER_OF_EVERYTHING_ROLE:
continue
match = re.match("^" + role_name(category, r"(\d+)") + "$", role.name)
if match:
out.append(int(match.group(1)))
return sorted(out)
def get_categories(self) -> List[Tuple[int, str]]:
out = []
for category in self.guild.categories:
match = re.match("^" + category_name(r"(\d+)", "(.*)", escaped=True) + "$", category.name)
if match:
category_id, name = match.groups()
out.append((int(category_id), name))
return out
def get_next_category_id(self) -> int:
return max((cat_id for cat_id, _ in self.get_categories()), default=0) + 1
def get_max_level_id(self, category: str) -> int:
return max(self.get_levels(category), default=0)
def get_level_count(self, category: str) -> int:
return len(self.get_levels(category))
async def is_authorized(self, user: User) -> bool:
member: Optional[Member] = self.guild.get_member(user.id)
return member and member.guild_permissions.administrator
def get_level(self, category, level_id):
_, _, category_channel, _, _ = self.get_category(name=category)
if category_channel is None:
return None, None, None
level_channel: Optional[TextChannel] = utils.get(category_channel.channels, name=level_name(level_id))
solution_channel: Optional[TextChannel] = utils.get(category_channel.channels, name=solution_name(level_id))
role: Optional[Role] = utils.get(self.guild.roles, name=role_name(category, level_id))
return level_channel, solution_channel, role
def get_category(self, *, name=None, category_id=None):
assert name is not None or category_id is not None
category_channel: Optional[CategoryChannel] = None
regex_id = str(category_id or r"\d+")
regex_name = name or ".*"
for cat in self.guild.categories:
match = re.match("^" + category_name(f"({regex_id})", f"({regex_name})", escaped=True) + "$", cat.name)
if match:
category_id, name = match.groups()
category_id = int(category_id)
category_channel = cat
riddle_master_role: Optional[Role] = utils.get(self.guild.roles, name=riddle_master_name(name))
leaderboard_channel: Optional[TextChannel] = category_channel and utils.get(
category_channel.channels, name="leaderboard"
)
return category_id, name, category_channel, riddle_master_role, leaderboard_channel
async def on_member_join(self, member: Member):
if member.guild.id != self.guild.id:
return
await member.send(open("texts/welcome_dm.txt").read().format(user=member.mention))
master_of_everything = True
for _, cat_name in self.get_categories():
_, _, role = self.get_level(cat_name, 1)
if role is not None:
master_of_everything = False
await member.add_roles(role)
else:
_, _, _, riddle_master_role, _ = self.get_category(name=cat_name)
await member.add_roles(riddle_master_role)
await self.update_leaderboard(cat_name)
if master_of_everything:
await member.add_roles(self.master_of_everything_role)
async def on_raw_reaction_add(self, payload):
if self.settings_message is None or self.settings_message.id != payload.message_id:
return
if str(payload.emoji) != BELL or payload.user_id == self.user.id:
return
member: Message = self.guild.get_member(payload.user_id)
await member.add_roles(self.notification_role)
async def on_raw_reaction_remove(self, payload):
if self.settings_message is None or self.settings_message.id != payload.message_id:
return
if str(payload.emoji) != BELL or payload.user_id == self.user.id:
return
member: Message = self.guild.get_member(payload.user_id)
await member.remove_roles(self.notification_role)
async def update_leaderboard(self, category):
_, _, _, riddle_master_role, leaderboard_channel = self.get_category(name=category)
async for message in leaderboard_channel.history():
if message.author == self.user:
break
else:
message = await leaderboard_channel.send(embed=create_embed())
level_count = self.get_level_count(category)
leaderboard = []
for member in self.guild.members:
if await self.is_authorized(member):
continue
for role in member.roles:
match = re.match("^" + role_name(category, r"(\d+)") + "$", role.name)
if role.id == riddle_master_role.id:
leaderboard.append((level_count, f"@{member}"))
elif match:
leaderboard.append((int(match.group(1)) - 1, f"@{member}"))
leaderboard.sort(reverse=True)
max_width = max((len(member) for _, member in leaderboard), default=0)
description = ["```", "MEMBER".ljust(max_width) + " SCORE"]
for score, member in leaderboard[:20]:
description.append(member.ljust(max_width) + f" {score}")
description.append("```")
embed = create_embed(title="Leaderboard", description="\n".join(description))
await message.edit(embed=embed)
async def update_master_of_everything_role(self, member: Member):
master_of_everything = True
for _, cat_name in self.get_categories():
_, _, _, riddle_master_role, _ = self.get_category(name=cat_name)
if riddle_master_role not in member.roles:
master_of_everything = False
break
if master_of_everything:
await member.add_roles(self.master_of_everything_role)
else:
await member.remove_roles(self.master_of_everything_role)
async def on_message(self, message: Message):
if message.author == self.user:
return
if message.content.startswith(PREFIX):
cmd, *args = message.content[1:].split()
if cmd == "add":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if len(args) < 2 or args[0] not in ("category", "level"):
await message.channel.send(f"usage: {PREFIX}add category|level <category>")
return
category = " ".join(args[1:])
if args[0] == "level":
_, cat_name, category_channel, riddle_master_role, _ = self.get_category(category_id=category)
if category_channel is None:
await message.channel.send("Category does not exist!")
return
level_id = self.get_max_level_id(cat_name) + 1
await message.channel.send(f"Creating Level {level_id}")
role: Role = await self.guild.create_role(name=role_name(cat_name, level_id))
for level in self.get_levels(cat_name):
if level == level_id:
continue
level_channel, _, _ = self.get_level(cat_name, level)
await level_channel.set_permissions(
role, read_messages=True, send_messages=False,
)
level_channel: TextChannel = await category_channel.create_text_channel(
level_name(level_id),
overwrites={
self.guild.default_role: PermissionOverwrite(read_messages=False),
role: PermissionOverwrite(read_messages=True, send_messages=False, add_reactions=False),
riddle_master_role: PermissionOverwrite(
read_messages=True, send_messages=False, add_reactions=False
),
self.guild.me: PermissionOverwrite(read_messages=True, send_messages=True),
},
)
solution_channel: TextChannel = await category_channel.create_text_channel(
solution_name(level_id),
overwrites={
self.guild.default_role: PermissionOverwrite(read_messages=False),
self.guild.me: PermissionOverwrite(read_messages=True),
},
)
await message.channel.send(
f"Level {level_id} has been created.\n"
f"Level channel: {level_channel.mention}\n"
f"Solution channel: {solution_channel.mention}\n"
f"Role: {role.mention}"
)
await message.channel.send("Now send me the riddle!")
riddle = await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
riddle_message: Message = await level_channel.send(
embed=(
create_embed(
title=f"[{category}] {cat_name} - Level {level_id}", description=riddle.content
)
)
)
await riddle_message.add_reaction(THUMBSUP)
await riddle_message.add_reaction(THUMBSDOWN)
await message.channel.send("Riddle has been created! :+1:")
await message.channel.send(f"Now go to {solution_channel.mention} and send the solution.")
await message.channel.send(
f"After that type `{PREFIX}notify {category} {level_id}` to notify the Riddle Masters :wink:"
)
else:
category_channel: CategoryChannel = await self.guild.create_category(
category_name(self.get_next_category_id(), category)
)
await category_channel.create_text_channel(
"leaderboard",
overwrites={
self.guild.default_role: PermissionOverwrite(read_messages=True, send_messages=False),
self.guild.me: PermissionOverwrite(read_messages=True, send_messages=True),
},
)
riddle_master_role: Role = await self.guild.create_role(
name=riddle_master_name(category), color=Color(random.randint(0, 0xFFFFFF)), hoist=True
)
for member in self.guild.members:
if member.id != self.user.id:
await member.add_roles(riddle_master_role)
await self.update_leaderboard(category)
await message.channel.send("Category has been created!")
elif cmd == "notify":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if len(args) != 2:
await message.channel.send(f"usage: {PREFIX}notify <category-id> <level-id>")
return
else:
if not args[-1].isnumeric():
await message.channel.send("Level ID has to be numeric!")
return
category = args[0]
level_id = int(args[1])
_, cat_name, _, riddle_master_role, _ = self.get_category(category_id=category)
level_channel, _, role = self.get_level(cat_name, level_id)
notify_count = 0
for member in self.guild.members:
if riddle_master_role in member.roles:
await member.remove_roles(riddle_master_role, self.master_of_everything_role)
await member.add_roles(role)
if self.notification_role in member.roles:
await member.send(
"Hey! Es gibt jetzt ein neues Rätsel auf dem Riddle Server :wink:\n"
f"Schau mal hier: {level_channel.mention}"
)
notify_count += 1
await self.update_leaderboard(cat_name)
await message.channel.send(
f"{notify_count} member{[' has', 's have'][notify_count != 1]} been notified about the new level."
)
elif cmd == "delete":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if not (
(len(args) == 2 and args[0] == "category")
or (len(args) == 3 and args[0] == "level")
or (len(args) == 4 and args[0] == "levels")
):
await message.channel.send(
f"usage: {PREFIX}delete category <category-id>\n"
f" or: {PREFIX}delete level[s] <category-id> <level-id> [<level-id>]"
)
return
category = args[1]
_, cat_name, category_channel, riddle_master_role, leaderboard = self.get_category(category_id=category)
if args[0] == "category":
for level in self.get_levels(cat_name):
level_channel, solution_channel, role = self.get_level(cat_name, level)
if level_channel:
await level_channel.delete()
if solution_channel:
await solution_channel.delete()
if role:
await role.delete()
if leaderboard:
await leaderboard.delete()
if category_channel:
await category_channel.delete()
if riddle_master_role:
await riddle_master_role.delete()
await message.channel.send("Category has been deleted")
else:
if args[0] == "level":
if not args[2].isnumeric():
await message.channel.send("Level ID has to be numeric!")
return
from_level_id = int(args[2])
to_level_id = from_level_id
else:
if (not args[2].isnumeric()) or (not args[3].isnumeric()):
await message.channel.send("Level ID has to be numeric!")
return
from_level_id = int(args[2])
to_level_id = int(args[3])
for level_id in range(from_level_id, to_level_id + 1):
level_channel, solution_channel, role = self.get_level(cat_name, level_id)
existed = False
if level_channel:
await level_channel.delete()
existed = True
if solution_channel:
await solution_channel.delete()
existed = True
if role:
await role.delete()
existed = True
if existed:
await message.channel.send(f"Level {level_id} has been deleted")
else:
await message.channel.send(f"Level {level_id} does not exist")
for level in self.get_levels(cat_name):
if level <= to_level_id:
continue
level_channel, solution_channel, role = self.get_level(cat_name, level)
await level_channel.edit(name=level_name(level - (to_level_id - from_level_id + 1)))
await solution_channel.edit(name=solution_name(level - (to_level_id - from_level_id + 1)))
await role.edit(name=role_name(cat_name, level - (to_level_id - from_level_id + 1)))
await self.update_leaderboard(cat_name)
for member in self.guild.members:
if member != self.user:
await self.update_master_of_everything_role(member)
await message.channel.send("Done")
elif cmd == "rename":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if len(args) < 2 or not args[0].isnumeric():
await message.channel.send(f"usage: {PREFIX}rename <category-id> <name>")
return
category = args[0]
new_name = " ".join(args[1:])
cat_id, cat_name, category_channel, riddle_master_role, leaderboard = self.get_category(
category_id=category
)
for level in self.get_levels(cat_name):
level_channel, _, role = self.get_level(cat_name, level)
await role.edit(name=role_name(new_name, level))
async for msg in level_channel.history(oldest_first=True):
if msg.author == self.user and msg.embeds:
embed: Embed = msg.embeds[0]
embed.title = f"[{category}] {new_name} - Level {level}"
await msg.edit(embed=embed)
break
await category_channel.edit(name=category_name(cat_id, new_name))
await riddle_master_role.edit(name=riddle_master_name(new_name))
await message.channel.send("Done!")
elif cmd == "info":
embed = create_embed(title="Info")
for cat_id, cat_name in self.get_categories():
count = self.get_level_count(cat_name)
embed.add_field(
name=f"[{cat_id}] {cat_name}", value=f"{count} Level" + "s" * (count != 1), inline=False
)
await message.channel.send(embed=embed)
elif cmd == "setup":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
self.settings_message = await self.settings_channel.send(
embed=create_embed(title="Settings", description=open("texts/settings.txt").read())
)
await self.settings_message.add_reaction(BELL)
elif cmd in ("solve", "lösen"):
if not isinstance(message.channel, DMChannel):
await message.delete()
await message.channel.send(
f"Hey, {message.author.mention}! Schick mir deine Lösung bitte privat :wink:"
)
return
if not args:
await message.channel.send(f"usage: {PREFIX}solve <category-id> [<solution>]")
return
member: Member = self.guild.get_member(message.author.id)
now = time.time()
cooldown, wrong_answers = self.cooldowns.get(member.id, (0, 0))
seconds = round(cooldown - now)
if seconds > 0:
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
await message.channel.send(
f"Da deine letzte Antwort falsch war, musst du noch etwas warten, "
f"bevor du es noch einmal versuchen kannst.\n"
f"Verbleibende Zeit: `{hours:02d}:{minutes:02d}:{seconds:02d}`"
)
return
answer = " ".join(args[1:])
_, cat_name, _, riddle_master_role, _ = self.get_category(category_id=args[0])
if riddle_master_role is None:
await message.channel.send("Tut mir leid, diese Kategorie kenne ich nicht :shrug:")
return
for role in member.roles:
if role.id == riddle_master_role.id:
await message.channel.send("Hey, du hast bereits alle Rätsel in dieser Kategorie gelöst :wink:")
return
if re.match("^" + role_name(cat_name, r"(\d+)") + "$", role.name):
level_id = int(re.match("^" + role_name(cat_name, r"(\d+)") + "$", role.name).group(1))
break
else:
level_channel, _, role = self.get_level(cat_name, 1)
if role is not None:
await member.add_roles(role)
await message.channel.send(
"Sorry, du hattest anscheinend noch keine Level-Rolle.\n"
f"Schau jetzt mal in {level_channel.mention} :wink:"
)
return
if not answer:
await message.channel.send("Ok, jetzt schick mir bitte die Lösung!")
answer = (
await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
).content
_, solution_channel, old_role = self.get_level(cat_name, level_id)
async for msg in solution_channel.history():
if re.match(f"^{msg.content.lower()}$", answer.lower()):
level_channel, _, new_role = self.get_level(cat_name, level_id + 1)
await member.remove_roles(old_role)
if new_role is not None:
await member.add_roles(new_role)
await message.channel.send(f"Richtig! Du hast jetzt Zugriff auf {level_channel.mention}!")
else:
await member.add_roles(riddle_master_role)
await self.update_master_of_everything_role(member)
await message.channel.send(
f"Richtig! Leider war das aber schon das letzte Rätsel dieser Kategorie."
)
if self.master_of_everything_role in member.roles:
await self.general_chat.send(
f"{member.mention} hat jetzt **alle Rätsel aller Kategorien gelöst!**\n"
f"**Herzlichen Glückwunsch!** :tada:"
)
else:
await self.general_chat.send(
f"{member.mention} hat jetzt alle Rätsel der Kategorie {cat_name} gelöst! :tada:"
)
cooldown = wrong_answers = 0
break
else:
await message.channel.send(f"Deine Antwort zu Level {level_id} ist leider falsch.")
cooldown = now + min(2 ** wrong_answers, 24 * 60 * 60)
wrong_answers += 1
self.cooldowns[member.id] = (cooldown, wrong_answers)
await self.update_leaderboard(cat_name)
elif cmd == "fix":
await self.fix_member(self.guild.get_member(message.author.id))
for _, cat_name in self.get_categories():
await self.update_leaderboard(cat_name)
await message.channel.send("Done")
elif cmd == "fixall":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
for member in self.guild.members:
if member != self.user:
await self.fix_member(member)
for _, cat_name in self.get_categories():
await self.update_leaderboard(cat_name)
await message.channel.send("Done")
elif cmd == "score":
member: Member = self.guild.get_member(message.author.id)
embed = create_embed(title=f"Score of @{member}")
total = 0
for _, cat_name in self.get_categories():
_, _, _, riddle_master_role, _ = self.get_category(name=cat_name)
level_count = self.get_level_count(cat_name)
for role in member.roles:
match = re.match("^" + role_name(cat_name, r"(\d+)") + "$", role.name)
points = None
if role.id == riddle_master_role.id:
points = level_count
elif match:
points = int(match.group(1)) - 1
if points is not None:
embed.add_field(name=cat_name, value=f"{points} Points", inline=False)
total += points
break
embed.add_field(name="TOTAL", value=f"{total} Points", inline=False)
await message.channel.send(embed=embed)
elif cmd == "send":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if len(args) != 2 or args[0] not in ("text", "embed"):
await message.channel.send(f"usage: {PREFIX}send text|embed <channel>")
return
channel_id = int(re.match(r"^(<#)?(\d+)(?(1)>)$", args[1]).group(2))
channel: TextChannel = self.get_channel(channel_id)
if channel is None:
await message.channel.send("Channel does not exist.")
return
if args[0] == "text":
await message.channel.send("Now send me the message!")
msg: Message = await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
files = []
for attachment in msg.attachments:
file = io.BytesIO()
await attachment.save(file)
files.append(File(file, filename=attachment.filename, spoiler=attachment.is_spoiler()))
await channel.send(content=msg.content, files=files)
else:
await message.channel.send("Send me the title of the embed!")
title = (
await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
).content
await message.channel.send("Ok, now send me the content of the embed!")
content = (
await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
).content
await channel.send(embed=create_embed(title=title, description=content))
elif cmd == "edit":
if not await self.is_authorized(message.author):
await message.channel.send("You are not authorized to use this command!")
return
if len(args) != 3 or args[0] not in ("text", "embed") or not args[2].isnumeric():
await message.channel.send(f"usage: {PREFIX}edit text|embed <channel> <message-id>")
return
channel_id = int(re.match(r"^(<#)?(\d+)(?(1)>)$", args[1]).group(2))
channel: TextChannel = self.get_channel(channel_id)
if channel is None:
await message.channel.send("Channel does not exist.")
return
msg_to_edit: Optional[Message] = await channel.fetch_message(int(args[2]))
if msg_to_edit is None:
await msg_to_edit.channel.send("Message does not exist.")
return
if args[0] == "text":
await message.channel.send("Now send me the new message!")
msg: Message = await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
files = []
for attachment in msg.attachments:
file = io.BytesIO()
await attachment.save(file)
files.append(File(file, filename=attachment.filename, spoiler=attachment.is_spoiler()))
await msg_to_edit.edit(content=msg.content, files=files)
else:
await message.channel.send("Send me the new title of the embed!")
title = (
await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
).content
await message.channel.send("Ok, now send me the new content of the embed!")
content = (
await self.wait_for(
"message", check=lambda m: m.channel == message.channel and m.author == message.author
)
).content
await msg_to_edit.edit(embed=create_embed(title=title, description=content))
elif cmd == "help":
response = "```\n"
if await self.is_authorized(message.author):
response += open("texts/admin_commands.txt").read().format(prefix=PREFIX) + "\n"
response += open("texts/user_commands.txt").read().format(prefix=PREFIX) + "\n```"
await message.channel.send(response)
else:
await message.channel.send(f"Unknown command! Type `{PREFIX}help` to get a list of commands!")
async def fix_member(self, member: Member):
for cat_id, cat_name in self.get_categories():
_, _, _, riddle_master_role, _ = self.get_category(category_id=cat_id)
for role in member.roles:
if role.id == riddle_master_role.id:
break
elif re.match("^" + role_name(cat_name, r"(\d+)") + "$", role.name):
break
else:
_, _, role = self.get_level(cat_name, 1)
await member.add_roles(role or riddle_master_role)
Bot().run(os.environ["TOKEN"])