-
Notifications
You must be signed in to change notification settings - Fork 11
/
bot.py
135 lines (109 loc) · 4.36 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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import traceback
import datetime
from typing import Optional
from discord import Intents
import aiohttp
import discord
from discord.ext import commands
log = logging.getLogger(__name__)
initial_extensions = (
'cogs.admin',
'cogs.github',
'cogs.guild_log',
'cogs.map_testing',
'cogs.ticketsystem',
'cogs.meme',
'cogs.misc',
'cogs.moderator',
'cogs.profile',
'cogs.records',
'cogs.status',
'cogs.votes',
'cogs.skindb',
'cogs.helpcmds',
'cogs.playerfinder',
'cogs.wiki',
'cogs.voice'
)
def get_traceback(error: Exception) -> str:
return ''.join(traceback.format_exception(type(error), error, error.__traceback__))
class DDNet(commands.Bot):
def __init__(self, **kwargs):
super().__init__(command_prefix='$', fetch_offline_members=True, help_command=commands.MinimalHelpCommand(), intents=Intents().all())
self.config = kwargs.pop('config')
self.pool = kwargs.pop('pool')
self.session = kwargs.pop('session')
async def setup_hook(self):
for extension in initial_extensions:
try:
await self.load_extension(extension)
except Exception:
log.exception('Failed to load extension %r', extension)
else:
log.info('Successfully loaded extension %r', extension)
self.start_time = discord.utils.utcnow()
self.add_check(self.global_check)
async def on_ready(self):
log.info('Logged in as %s (ID: %d)', self.user, self.user.id)
synced = await self.tree.sync()
log.info(f"Slash CMDs Synced: {str(len(synced))} Commands")
async def on_resumed(self):
log.info('Resumed')
async def close(self):
log.info('Closing')
await super().close()
await self.pool.close()
await self.session.close()
async def on_message(self, message: discord.Message):
await self.wait_until_ready()
await self.process_commands(message)
def global_check(self, ctx: commands.Context) -> bool:
return ctx.guild is None or ctx.channel.permissions_for(ctx.guild.me).send_messages
async def on_command(self, ctx: commands.Context):
if ctx.guild is None:
destination = 'Private Message'
guild_id = None
else:
destination = f'#{ctx.channel} ({ctx.guild})'
guild_id = ctx.guild.id
log.info('%s used command in %s: %s', ctx.author, destination, ctx.message.content)
query = """INSERT INTO stats_commands (guild_id, channel_id, author_id, timestamp, command)
VALUES ($1, $2, $3, $4, $5);
"""
values = (
guild_id,
ctx.channel.id,
ctx.author.id,
datetime.datetime.fromisoformat(ctx.message.created_at.replace(tzinfo=None).isoformat()),
ctx.command.qualified_name
)
await self.pool.execute(query, *values)
async def on_command_error(self, ctx: commands.Context, error: commands.CommandError):
command = ctx.command
msg = None
if isinstance(error, commands.MissingRequiredArgument):
msg = f'{self.command_prefix}{command.qualified_name} {command.signature}'
elif isinstance(error, commands.CommandInvokeError):
if isinstance(error.original, discord.Forbidden):
msg = 'I do not have proper permission'
elif isinstance(error.original, discord.HTTPException) and error.original.code == 40005:
msg = 'File is too large to upload'
else:
trace = get_traceback(error.original)
log.error('Command %r caused an exception\n%s', command.qualified_name, trace)
if isinstance(error.original, aiohttp.ClientConnectorError):
msg = 'Could not fetch/send data'
else:
msg = 'An internal error occurred'
if msg is not None:
try:
await ctx.send(msg)
except discord.Forbidden:
pass
async def on_error(self, event: str, *args, **kwargs):
log.exception('Event %r caused an exception', event)
def get_message(self, message_id: int) -> Optional[discord.Message]:
return discord.utils.get(self.cached_messages, id=message_id)