-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.py
More file actions
105 lines (87 loc) · 3.46 KB
/
bot.py
File metadata and controls
105 lines (87 loc) · 3.46 KB
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
import os
import sys
import logging
import discord
from discord.ext import commands
from db.database import Database
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
REQUIRED_ENV = ["DISCORD_TOKEN", "GITHUB_USERNAME", "MOD_LOG_CHANNEL_ID", "WELCOME_CHANNEL_ID", "GITHUB_NOTIFY_CHANNEL_ID"]
COGS = [
"cogs.github",
"cogs.qflix",
"cogs.info",
"cogs.welcome",
"cogs.reminders",
"cogs.polls",
"cogs.autoresponse",
"cogs.logging",
"cogs.announcements",
"cogs.purge",
"cogs.trim",
"cogs.celebrations",
"cogs.timestamp",
"cogs.role_panels",
]
def check_env():
missing = [v for v in REQUIRED_ENV if not os.environ.get(v)]
if missing:
print(f"Missing required environment variables: {', '.join(missing)}", file=sys.stderr)
sys.exit(1)
class QuadstroNot(commands.Bot):
def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.voice_states = True
intents.presences = True
super().__init__(command_prefix="!", intents=intents)
self.database = Database()
async def setup_hook(self):
await self.database.connect()
for cog in COGS:
try:
await self.load_extension(cog)
print(f"Loaded {cog}")
except Exception as e:
print(f"Failed to load {cog}: {e}", file=sys.stderr)
sync_guild_id = os.environ.get("SLASH_SYNC_GUILD_ID")
if sync_guild_id:
guild = discord.Object(id=int(sync_guild_id))
self.tree.copy_global_to(guild=guild)
try:
synced = await self.tree.sync(guild=guild)
print(f"Synced {len(synced)} slash command(s) to guild {sync_guild_id}")
except discord.HTTPException as e:
print(f"Slash sync failed: {e}", file=sys.stderr)
async def close(self):
await self.database.close()
await super().close()
async def on_ready(self):
print(f"QuadstroNot is online as {self.user} (ID: {self.user.id})")
print(f"Connected to {len(self.guilds)} guild(s)")
for guild in self.guilds:
print(f" - {guild.name} (ID: {guild.id})")
async def on_message(self, message: discord.Message):
if message.author.bot:
return
if message.content.startswith("!"):
print(f"Command received: '{message.content}' from {message.author} in #{message.channel}")
await self.process_commands(message)
async def on_command_error(self, ctx: commands.Context, error: commands.CommandError):
if isinstance(error, commands.CommandNotFound):
return # silently ignore unknown commands
if isinstance(error, commands.MissingPermissions):
await ctx.send("You don't have permission to use that command.")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"Missing argument: `{error.param.name}`. Use `!help {ctx.command}` for usage.")
elif isinstance(error, commands.BadArgument):
await ctx.send(f"Invalid argument. Use `!help {ctx.command}` for usage.")
else:
await ctx.send("Something went wrong running that command.")
print(f"Unhandled error in {ctx.command}: {error}", file=sys.stderr)
def main():
check_env()
bot = QuadstroNot()
bot.run(os.environ["DISCORD_TOKEN"])
if __name__ == "__main__":
main()