generated from kkrypt0nn/Python-Discord-Bot-Template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
180 lines (151 loc) · 5.53 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
""""
Modified by Harrison McCarty - Autonomous Robotics Club of Purdue
Copyright © Krypton 2021 - https://github.com/kkrypt0nn
Description:
"""
import json
import os
import platform
import random
import sys
import logging as log
import disnake
from disnake import ApplicationCommandInteraction
from disnake.ext import tasks, commands
from disnake.ext.commands import Bot
from disnake.ext.commands import Context
from helpers.db_manager import init_db, MemberModel, ARCdleModel
import exceptions
#
# Configuration
#
if not os.path.isfile("config.json"):
sys.exit("'config.json' not found! Please add it and try again.")
else:
with open("config.json") as file:
config = json.load(file)
# Setup database
init_db()
# Setup logging
logger = log.getLogger()
logger.setLevel(log.NOTSET)
console_handler = log.StreamHandler()
console_handler.setLevel(log.ERROR)
console_handler_format = "%(asctime)s | %(levelname)s: %(message)s"
console_handler.setFormatter(log.Formatter(console_handler_format))
logger.addHandler(console_handler)
file_handler = log.FileHandler(config["log"])
file_handler.setLevel(log.INFO)
file_handler_format = '%(asctime)s | %(levelname)s | %(lineno)d: %(message)s'
file_handler.setFormatter(log.Formatter(file_handler_format))
logger.addHandler(file_handler)
#
# Define bot commands
#
intents = disnake.Intents.default()
intents.presences = False
intents.members = True
intents.reactions = True
bot = Bot(command_prefix=config["bot_prefix"], intents=intents)
# Removes the default help command
bot.remove_command("help")
def load_commands(command_type: str) -> None:
for file in os.listdir(f"./cogs/{command_type}"):
if file.endswith(".py"):
extension = file[:-3]
try:
bot.load_extension(f"cogs.{command_type}.{extension}")
log.info(f"Loaded extension '{extension}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
log.error(f"Failed to load extension {extension}\n{exception}")
if __name__ == "__main__":
load_commands("general")
load_commands("currency")
#
# Define bot events
#
@bot.event
async def on_ready():
log.info(f"Logged in as {bot.user.name}")
log.info(f"Discord.py API version: {disnake.__version__}")
log.info(f"Python version: {platform.python_version()}")
log.info(f"Running on: {platform.system()} {platform.release()} ({os.name})")
await status_task()
# Setup the game status task of the bot
async def status_task():
await bot.change_presence(activity=disnake.Game(
"github.com/hmccarty/arc_assistant"
))
@bot.event
async def on_message(msg: disnake.Message):
if msg.author == bot.user or msg.author.bot:
return
if msg.guild == None:
# Check if user is in arcdle game
arcdle = ARCdleModel.get_member_active_game(msg.author.id)
if arcdle is not None:
game = bot.get_cog("game")
if game is not None:
await game.handle_message(msg, arcdle)
return
# If not, assume user is verifying
verification = bot.get_cog("verification")
if verification is not None:
await verification.handle_message(msg)
return
await bot.process_commands(msg)
# The code in this event is executed every time a command has been *successfully* executed
@bot.event
async def on_command_completion(ctx: commands.Context):
fullCommandName = ctx.command.qualified_name
split = fullCommandName.split(" ")
executedCommand = str(split[0])
log.info(
(f"Executed {executedCommand} command in {ctx.guild.name} ",
f"(ID: {ctx.message.guild.id}) by {ctx.message.author} ",
f"(ID: {ctx.message.author.id})"))
# The code in this event is executed every time a valid commands catches an error
@bot.event
async def on_command_error(ctx: commands.Context,
error: commands.CommandError):
if isinstance(error, commands.CommandOnCooldown):
minutes, seconds = divmod(error.retry_after, 60)
hours, minutes = divmod(minutes, 60)
hours = hours % 24
desc = "You can use this command again in " \
f"{f'{round(hours)} hours' if round(hours) > 0 else ''} " \
f"{f'{round(minutes)} minutes' if round(minutes) > 0 else ''} " \
f"{f'{round(seconds)} seconds' if round(seconds) > 0 else ''}."
embed = disnake.Embed(
title="Hey, please slow down!",
description=desc,
color=0xE02B2B
)
await ctx.send(embed=embed)
elif isinstance(error, commands.MissingPermissions):
if len(error.missing_perms) == 0:
desc = "You are missing the permissions to execute this command!"
else:
desc = "You are missing the permission `" + ", ".join(
error.missing_perms) + "` to execute this command!"
embed = disnake.Embed(
title="Error!",
description=desc,
color=0xE02B2B
)
await ctx.send(embed=embed)
elif isinstance(error, commands.MissingRequiredArgument) or \
isinstance(error, commands.MemberNotFound) or \
isinstance(error, commands.CommandNotFound) or \
isinstance(error, commands.UserInputError) or \
isinstance(error, commands.NoPrivateMessage):
embed = disnake.Embed(
title="Error!",
description=str(error).capitalize(),
color=0xE02B2B
)
await ctx.send(embed=embed)
raise error
# Run the bot with the token
bot.run(config["bot_token"])