In this article, we’ll leverage the discord.ext.commands extension in discord.py
to refactor our somewhat complex on_message function.
The code up to our last session is as follows:
We added !omikuji and !quiz commands, which made the on_message function somewhat bloated.
import asyncio
import json
import random
import discord
class MyClient(discord.Client):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
quiz_file = 'python_problems.en.json'
with open(quiz_file) as f:
self.quiz_list = json.load(f)
async def on_ready(self):
"""Triggered when connecting to Discord."""
print(f'Connected as {self.user}.')
async def on_message(self, message: discord.Message):
"""Triggered when receiving a message."""
# Ignore messages sent by the bot itself
if message.author == self.user:
return
print(f'Received a message from {message.author}: {message.content}')
if message.content == '!omikuji':
choice = random.choice([
"Great Blessing", "Blessing", "Small Blessing",
"Misfortune", "Great Misfortune"
])
await message.channel.send(
f"Your fortune for today is: **{choice}**!"
)
if message.content == '!quiz':
def quiz_reply_check(m: discord.Message):
"""Function to validate quiz replies."""
return m.author == message.author and m.content.isdigit()
quiz = random.choice(self.quiz_list)
quiz_str = (
f'Q: {quiz["question"]}\n\n' +
'\n'.join([
f'[{i+1}] {c}' for (i, c) in enumerate(quiz["choices"])
])
)
await message.channel.send(quiz_str)
try:
reply_message = await self.wait_for(
'message', check=quiz_reply_check, timeout=30
)
if reply_message.content == str(quiz['answer_num']):
result = "😀 Correct!"
else:
result = \
f"😢 Sorry, the correct answer is {quiz['answer_num']}."
except asyncio.TimeoutError:
result = \
f"😢 Time's up! The correct answer is {quiz['answer_num']}."
await message.channel.send(result)
with open('.discord_token') as f:
token = f.read().strip()
intents = discord.Intents.default()
intents.message_content = True
client = MyClient(intents=intents)
client.run(token)
Using the discord.ext.commands extension
As we add more commands like before,
repetitive logic increases, and our on_message becomes bulky.