-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.py
325 lines (279 loc) · 11.4 KB
/
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
import asyncio
import logging
import os
import traceback
from typing import Union
import aiohttp
import nextcord
from nextcord.ext import application_checks, commands, tasks
from internal_tools.configuration import CONFIG
from internal_tools.discord import fancy_embed
async def main():
logging.basicConfig(filename="bot.log", filemode="w+", level=logging.INFO)
intents = nextcord.Intents.default()
intents.members = CONFIG["GENERAL"]["MEMBERS_INTENT"]
intents.presences = CONFIG["GENERAL"]["PRESENCE_INTENT"]
intents.message_content = CONFIG["GENERAL"]["MESSAGE_CONTENT_INTENT"]
bot = commands.Bot(intents=intents)
if CONFIG["GENERAL"]["TOKEN"] == "":
CONFIG["GENERAL"]["TOKEN"] = input(
"Token is not set in config, please enter the token here.\n\nToken: "
)
CONFIG.save()
for cog in [
"cogs." + x.name.replace(".py", "")
for x in os.scandir("cogs")
if not x.name.startswith("_")
]:
try:
bot.load_extension(cog)
print(f"Loaded: {cog}")
except Exception as e:
print(f"{e}")
@bot.event
async def on_ready():
await bot.change_presence(
activity=nextcord.Activity(
type=nextcord.ActivityType.watching, name="the scammers"
)
)
print(f"Online and Ready\nLogged in as {bot.user}")
@bot.slash_command(
"donate",
description="Shows info about where you can donate. Making the Bot took a lot of time and effort and some money.",
)
async def donate(interaction: nextcord.Interaction):
embed = fancy_embed(
"How to donate",
description="Down below you can see all ways to donate to me.",
fields=CONFIG["GENERAL"]["DONATION_FIELDS"],
)
await interaction.send(embed=embed)
@bot.slash_command(
name="support",
description="Gives you a Invite to the Support Server where you can talk to my Developer.",
)
async def support(interaction: nextcord.Interaction):
await interaction.send(CONFIG["GENERAL"]["OFFICIAL_INVITE"], ephemeral=True)
@bot.slash_command(
name="reload-all",
description="Reloads all Cogs",
guild_ids=CONFIG["GENERAL"]["OWNER_COG_GUILD_IDS"],
)
@application_checks.is_owner()
async def reload_all_cogs(interaction: nextcord.Interaction):
usable_cogs = [
"cogs." + x.name.replace(".py", "")
for x in os.scandir("cogs")
if not x.name.startswith("_")
]
for cog in usable_cogs:
try:
bot.unload_extension(cog)
except:
pass
bot.load_extension(cog)
await interaction.send("Done", ephemeral=True)
async def _try_send(interaction: nextcord.Interaction, text: str):
try:
await interaction.send(
text,
ephemeral=True,
)
except nextcord.errors.Forbidden:
return False
except nextcord.errors.NotFound:
return False
else:
return True
@bot.event
async def on_application_command_error(
interaction: nextcord.Interaction,
exception: Union[
nextcord.errors.ApplicationInvokeError,
nextcord.errors.ApplicationCheckFailure,
],
):
if interaction.application_command:
if interaction.application_command.error_callback != None:
return
if isinstance(exception, nextcord.errors.ApplicationInvokeError):
original_exception = exception.original
else:
original_exception = exception
if isinstance(
original_exception, application_checks.errors.ApplicationCheckAnyFailure
):
original_exception = original_exception.errors[
0
] # Take the first problem and show it. Step by step.
if isinstance(original_exception, nextcord.errors.NotFound):
if await _try_send(
interaction,
"Something being used for this Command (like a channel, member, role, etc.) is missing. It was deleted, or the person left. Fix this issue and try again.",
):
return
elif isinstance(original_exception, nextcord.errors.Forbidden):
if await _try_send(
interaction,
"The Bot is missing permissions for something it has to do for this Command. Make sure it has all needed permissions and try again.",
):
return
else:
try:
if interaction.user:
await interaction.user.send(
f"The Bot lacks the Permissions needed to send Messages in the Channel you just tried to use a Command in."
)
except:
return
elif isinstance(original_exception, nextcord.errors.DiscordServerError):
if await _try_send(
interaction,
"Something went wrong on Discords side. Please try again later.",
):
return
elif isinstance(
original_exception, application_checks.errors.ApplicationMissingRole
):
if type(original_exception.missing_role) == int:
missing_role_text = f"<@&{original_exception.missing_role}>"
else:
missing_role_text = f"@{original_exception.missing_role}"
if await _try_send(
interaction,
f"You are missing the Role that is needed to use this Command. ( {missing_role_text} )",
):
return
elif isinstance(
original_exception, application_checks.errors.ApplicationMissingAnyRole
):
missing_role_texts = []
for missing_role in original_exception.missing_roles:
if type(missing_role) == int:
missing_role_texts.append(f"<@&{missing_role}>")
else:
missing_role_texts.append(f"@{missing_role}")
if await _try_send(
interaction,
f"You are missing a Role that is needed to use this Command. ( You need at least on of these: {', '.join(missing_role_texts)} )",
):
return
elif isinstance(
original_exception, application_checks.errors.ApplicationBotMissingRole
):
if type(original_exception.missing_role) == int:
missing_role_text = f"<@&{original_exception.missing_role}>"
else:
missing_role_text = f"@{original_exception.missing_role}"
if await _try_send(
interaction,
f"The Bot is missing the Role that is needed to use this Command. ( {missing_role_text} )",
):
return
elif isinstance(
original_exception, application_checks.errors.ApplicationBotMissingAnyRole
):
missing_role_texts = []
for missing_role in original_exception.missing_roles:
if type(missing_role) == int:
missing_role_texts.append(f"<@&{missing_role}>")
else:
missing_role_texts.append(f"@{missing_role}")
if await _try_send(
interaction,
f"The Bot is missing a Role that is needed to use this Command. ( The Bot needs at least on of these: {', '.join(missing_role_texts)} )",
):
return
elif isinstance(
original_exception, application_checks.errors.ApplicationMissingPermissions
):
if await _try_send(
interaction,
f"You lack the Permissions needed to use this Command.\nYou need all of these Permissions: {', '.join(original_exception.missing_permissions)}",
):
return
elif isinstance(
original_exception,
application_checks.errors.ApplicationBotMissingPermissions,
):
if await _try_send(
interaction,
f"The Bot lacks the Permissions needed to use this Command.\nThe Bot needs all of these Permissions: {', '.join(original_exception.missing_permissions)}",
):
return
else:
try:
if interaction.user:
await interaction.user.send(
f"The Bot lacks the Permissions needed to send Messages in the Channel you just tried to use a Command in.\nThe Bot needs all of these Permissions: {', '.join(original_exception.missing_permissions)}"
)
except:
return
elif isinstance(
original_exception, application_checks.errors.ApplicationNoPrivateMessage
):
if await _try_send(
interaction,
f"This Command cant be used in DMs. Use it on a Server instead.",
):
return
elif isinstance(
original_exception,
application_checks.errors.ApplicationPrivateMessageOnly,
):
if await _try_send(
interaction,
f"This Command can only be used in DMs.",
):
return
elif isinstance(
original_exception,
application_checks.errors.ApplicationNotOwner,
):
if await _try_send(
interaction,
f"You need to be the Owner of this Bot to use this Command.",
):
return
elif isinstance(
original_exception,
application_checks.errors.ApplicationNSFWChannelRequired,
):
if original_exception.channel:
channel_mention = f"<#{original_exception.channel.id}>"
else:
channel_mention = f"The Channel used for this Command"
if await _try_send(
interaction,
f"{channel_mention} needs to be a NSFW Channel. You can make it one in the Channel settings.",
):
return
elif isinstance(
original_exception,
application_checks.errors.ApplicationCheckForBotOnly,
):
if await _try_send(
interaction,
f"This Command is only usable for other Bots.",
):
return
elif isinstance(original_exception, nextcord.errors.ApplicationCheckFailure):
try:
doc_string = interaction.application_command.parent_cog.cog_application_command_check.__doc__.strip("\n ") # type: ignore
except:
doc_string = ""
if await _try_send(
interaction,
f"You are not allowed to use this Command.\n{doc_string}",
):
return
if CONFIG["GENERAL"]["ERROR_WEBHOOK_URL"]:
webhook = nextcord.Webhook.from_url(
CONFIG["GENERAL"]["ERROR_WEBHOOK_URL"], session=aiohttp.ClientSession()
)
text = "".join(traceback.format_exception(original_exception)) # type: ignore
await webhook.send(f"Unpredicted Error:\n```\n{text}\n```")
await bot.start(CONFIG["GENERAL"]["TOKEN"])
if __name__ == "__main__":
asyncio.run(main())