這是一篇 Discord Bot 的進階教學文章,會教學如何將 Discord Bot 指令分門別類,以及如何在 Discord Bot 上線期間直接新增、移除、更新指令,讓 Discord Bot 未來能夠方便維護和擁有更好的可讀性。
如果還不了解 Discord Bot 的用途以及該如何創建一臺 Discord Bot 的讀者,建議可以參考這篇之前本作者撰寫的 Python Discord Bot 基礎教學。
更多 Python Discord Bot 教學系列和程式範例
https://github.com/smallshawn95/Python-Discord-Bot-Teach.git
為了要讓未來 Discord Bot 方便維護以及增加可讀性,將各個指令分門別類會是一個不錯的方法,而 Cog 就是能夠實現這功能的架構,Cog 可以將程式碼分門別類,讓主程式只要負責執行加載檔案和卸載檔案的動作。
基礎教學的內容中,最後有提到使用關鍵字的 on_message
和前綴指令 command
如果放在同一個檔案會無法運作的問題,而使用 Cog 架構就可以來解決這個問題。
更多資訊可參考 Discord.py Cog 官方文檔。
小幫助
使用「前綴指令help(例:$help)」可以了解目前有哪些指令可以執行。
通常使用於撰寫好新的程式檔案要上線,或者要將之前載出的程式檔案再次上線。
執行語法:前綴符號load 檔案名稱(例:$load main)
@bot.command()
async def load(ctx, extension):
await bot.load_extension(f"cogs.{extension}")
await ctx.send(f"Loaded {extension} done.")
載入成功會回傳訊息讓使用者知道
main檔案載入成功
通常使用於程式檔案出 Bug 時,卸載來阻止其他使用者執行到錯誤指令。
執行語法:前綴符號unload 檔案名稱(例:$unload main)
@bot.command()
async def unload(ctx, extension):
await bot.unload_extension(f"cogs.{extension}")
await ctx.send(f"UnLoaded {extension} done.")
卸載成功會回傳訊息讓使用者知道
main檔案卸載成功
通常使用於更改過程式檔案要直接更新,或者 Debug 時的測試。
執行語法:前綴符號reload 檔案名稱(例:$reload main)
@bot.command()
async def reload(ctx, extension):
await bot.reload_extension(f"cogs.{extension}")
await ctx.send(f"ReLoaded {extension} done.")
重新載入成功會回傳訊息讓使用者知道
main檔案重新載入成功
import os
import asyncio
import discord
from discord.ext import commands
intents = discord.Intents.all()
bot = commands.Bot(command_prefix = "$", intents = intents)
# 當機器人完成啟動時
@bot.event
async def on_ready():
print(f"目前登入身份 --> {bot.user}")
# 載入指令程式檔案
@bot.command()
async def load(ctx, extension):
await bot.load_extension(f"cogs.{extension}")
await ctx.send(f"Loaded {extension} done.")
# 卸載指令檔案
@bot.command()
async def unload(ctx, extension):
await bot.unload_extension(f"cogs.{extension}")
await ctx.send(f"UnLoaded {extension} done.")
# 重新載入程式檔案
@bot.command()
async def reload(ctx, extension):
await bot.reload_extension(f"cogs.{extension}")
await ctx.send(f"ReLoaded {extension} done.")
# 一開始bot開機需載入全部程式檔案
async def load_extensions():
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
await bot.load_extension(f"cogs.{filename[:-3]}")
async def main():
async with bot:
await load_extensions()
await bot.start("機器人的TOKEN")
# 確定執行此py檔才會執行
if __name__ == "__main__":
asyncio.run(main())
只需要注意幾個地方,就能將基礎教學中的程式碼搬過來使用,而且可以將關鍵字觸發和前綴指令共同放在同一個檔案中。
@bot.event
要改成 @commands.Cog.listener()
@bot.command()
要改成 @commands.command()
self.bot
才能使用self
,否則程式碼會出錯
import discord
from discord.ext import commands
class Main(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
...
async def setup(bot):
await bot.add_cog(Main(bot))
import discord
from discord.ext import commands
# 定義名為 Main 的 Cog
class Main(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
# 前綴指令
@commands.command()
async def Hello(self, ctx: commands.Context):
await ctx.send("Hello, world!")
# 關鍵字觸發
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author == self.bot.user:
return
if message.content == "Hello":
await message.channel.send("Hello, world!")
# Cog 載入 Bot 中
async def setup(bot: commands.Bot):
await bot.add_cog(Main(bot))
本次 Discord Bot 進階教學 — Cog 篇到此介紹完了,希望大家有成功將指令分門別類,並且可以線上載入、卸載、重新加載指令。
本次教學中較難懂的點可能是 class 那部分,需要已經具備 class 的知識才能了解實際的運作,而筆者也沒有特別詳細描述,那是因為程式的資料過於龐大,如果每行程式碼都要釐清實際運作過程將會寸步難行,所以我們只要看得懂這行大概要做什麼以及如何應用,這樣就足以完成我們的 Discord Bot。
感謝各位觀看完整篇的教學,下篇教學將會介紹目前 Discord 推薦 Bot 應該都要使用的斜線指令該如何撰寫,敬請期待下一篇教學。
📢 歡迎加入我的 Discord 伺服器
https://discord.gg/Jtd3eVrFJs
Copyright © 2023 SmallShawn95. All rights reserved.