這是一篇 Discord Bot 的進階教學,之前教學中提到觸發機器人運作可以使用關鍵字和前綴指令,其實還有更多種方式觸發,本次教學能夠學到如何簡單撰寫斜線指令以及各個參數如何使用。 :::success :book: **更多 Python Discord Bot 教學系列和程式範例** https://github.com/smallshawn95/Python-Discord-Bot-Course.git ::: --- [TOC] --- ## 一、斜線指令簡介: Discord 官方在 2021 年 3 月份左右推出斜線指令(Slash Commands),它是 Discord 訊息交互的一種新方式,可以更簡單、直觀的使用指令功能,不僅打出 `/` 就可以了解 Bot 擁有的指令和各個指令的用途,還能清楚知道指令該傳入哪些參數,讓使用指令更加方便。 ![Picture_1](https://i.imgur.com/TW4xwBs.png) ## 二、斜線指令基本語法: :::warning :bell: **撰寫準備** 需要先在 `bot.py` 中的 `async def on_ready()` 中添加 `await bot.tree.sync()`,這行程式碼的功能要讓 Bot 的斜線指令可以同步到 Discord 上,底下程式碼可以順便得知同步多少個指令。 ```python= @bot.event async def on_ready(): slash = await bot.tree.sync() print(f"目前登入身份 --> {bot.user}") print(f"載入 {len(slash)} 個斜線指令") ``` ::: 撰寫斜線指令也有單檔案和 Cog 架構兩種方式,簡單列出兩種方式的斜線指令基本語法,而接下來的斜線指令額外語法的教學將會使用 Cog 架構,如果不會 Cog 架構可以參考筆者這篇 [Python Discord Bot 進階教學 — Cog 篇](https://hackmd.io/@smallshawn95/python_discord_bot_cog)。 * **單檔案** :::warning :bell: 修飾器從 `@bot.command()` 改成 `@bot.tree.command()` ::: ```python= # name指令顯示名稱,description指令顯示敘述 # name的名稱,中、英文皆可,但不能使用大寫英文 @bot.tree.command(name = "hello", description = "Hello, world!") async def hello(interaction: discord.Interaction): # 回覆使用者的訊息 await interaction.response.send_message("Hello, world!") ``` * **Cog 架構** :::warning :bell: 需要在程式開頭導入 app_command 指令 ```python= from discord import app_commands ``` ::: ```python= # name指令顯示名稱,description指令顯示敘述 # name的名稱,中、英文皆可,但不能使用大寫英文 @app_commands.command(name = "hello", description = "Hello, world!") async def hello(self, interaction: discord.Interaction): # 回覆使用者的訊息 await interaction.response.send_message("Hello, world!") ``` ![Picture_2](https://i.imgur.com/sgRYF7r.png) ![Picture_3](https://i.imgur.com/KR44CVG.png) ![Picture_4](https://i.imgur.com/R3ZGWHe.png) ## 三、斜線指令額外語法: 更多有關斜線指令的資料可以參考 [discord.py API](https://discordpy.readthedocs.io/en/latest/interactions/api.html?#command)。 ### 參數敘述 `@app_commands.describe()` 是一個讓參數增加文字敘述的函式,需要注意函式中的變數名稱需要和參數的名字一模一樣,否則會因為無法辨別而發生錯誤。 ```python= # @app_commands.describe(參數名稱 = 參數敘述) # 參數: 資料型態,可以限制使用者輸入的內容 @app_commands.command(name = "add", description = "計算相加值") @app_commands.describe(a = "輸入數字", b = "輸入數字") async def add(self, interaction: discord.Interaction, a: int, b: int): await interaction.response.send_message(f"Total: {a + b}") ``` ![Picture_5](https://i.imgur.com/G8m1LxA.png) ![Picture_6](https://i.imgur.com/NANKpYl.png) ### 可選參數 :::warning :bell: 需要在程式開頭加入 typing 模組中的 Optional 工具。 ```python from typing import Optional ``` ::: typing 中的 `Optional` 工具可以讓參數變成可選,可讓使用者依據自身需求填寫。 ```python= # 參數: Optional[資料型態],參數變成可選,可以限制使用者輸入的內容 @app_commands.command(name = "say", description = "大聲說出來") @app_commands.describe(name = "輸入人名", text = "輸入要說的話") async def say(self, interaction: discord.Interaction, name: str, text: Optional[str] = None): if text == None: text = "。。。" await interaction.response.send_message(f"{name} 說 「{text}」") ``` ![Picture_7](https://i.imgur.com/ZdaFbqM.png) ![Picture_8](https://i.imgur.com/rLjZCWy.png) ### 選項清單 :::warning :bell: 為了撰寫程式碼更方便、快速,可以先將 discord.app_commands 中的 Choice 工具導入。 ```python from discord.app_commands import Choice ``` ::: `@app_commands.choices()` 是一個製作讓使用者選擇的選項清單的函式,要注意每個參數最多只能添加 25 個選項。 更多選項清單的寫法,可以參考此篇的 [discord.py API](https://discordpy.readthedocs.io/en/stable/interactions/api.html?#discord.app_commands.choices)。 ```python= # @app_commands.choices(參數 = [Choice(name = 顯示名稱, value = 隨意)]) @app_commands.command(name = "order", description = "點餐機") @app_commands.describe(meal = "選擇餐點", size = "選擇份量") @app_commands.choices( meal = [ Choice(name = "漢堡", value = "hamburger"), Choice(name = "薯條", value = "fries"), Choice(name = "雞塊", value = "chicken_nuggets"), ], size = [ Choice(name = "大", value = 0), Choice(name = "中", value = 1), Choice(name = "小", value = 2), ] ) async def order(self, interaction: discord.Interaction, meal: Choice[str], size: Choice[int]): # 獲取使用指令的使用者名稱 customer = interaction.user.name # 使用者選擇的選項資料,可以使用name或value取值 meal = meal.value size = size.value await interaction.response.send_message(f"{customer} 點了 {size} 號 {meal} 餐") ``` ![Picture_9](https://i.imgur.com/LNsKvH2.png) ![Picture_10](https://i.imgur.com/U2j1IXe.png) --- 本次斜線指令的教學就到這邊,非常感謝各位願意看完整篇文章,能夠讓大家輕鬆學會如何撰寫斜線指令的程式,是筆者的榮幸,如果文章有哪邊還是不懂、不清楚,或者覺得哪邊需要增進、更改,歡迎跟筆者反映,讓這篇文章更清楚、完整,就可以讓更多人輕鬆學會如何撰寫斜線指令的程式。 當初筆者要從前綴指令轉成斜線指令遇到很多的問題,比如照著官方文檔打程式碼,執行 Bot 時卻依然沒有顯示出斜線指令,後來是有人說必須在 Bot 上線的程式碼中要加 `await bot.tree.sync()`,才能將斜線指令同步到 Discord 上,有時要解決問題,真的需要別人拋磚引玉才會知道該如何解決。 歡迎加入筆者的 Discord 伺服器,可以跟筆者和裡面的成員一起討論程式、解題技巧、專案,一起進步、增強程式能力!筆者也是從程式小白走過來的,說不定您遇到的問題其實就是筆者曾經遇過的,這樣就可以快速解決 Bug,繼續撰寫程式,最後希望大家都能撰寫出符合自己需求的斜線指令。 --- :::info 📢 **歡迎加入我的 Discord 伺服器** https://discord.gg/Jtd3eVrFJs ::: *Copyright © 2023 SmallShawn95. All rights reserved.*