Try   HackMD

這是一篇 Discord Bot 的進階教學,會使用 Python Cog 架構撰寫。
在之前的 View 教學中,曾經提到 Item 元素跟 View 息息相關,此次教學要來詳細介紹和實作 Discord 中的 Button,如果還沒看過 View 教學的讀者可以點此前往,Python Discord Bot 進階教學 — View 篇

:book: 更多 Python Discord Bot 教學系列和程式範例
https://github.com/smallshawn95/Python-Discord-Bot-Teach.git



一、Button 簡介:

Discord Button 於 2021 年 10 月推出,具有多種使用方式,可以傳送訊息、觸發特定事件、將使用者傳送到指定網址等等。
Discord Button 推出之前,開法者如果想要讓 Bot 可以利用 GUI 介面來實現投票、換頁、切歌等等功能,通常只能使用簡單的 Emoji,並且需要訊息輔助說明每個 Emoji 的用途,而現在的 Button 則在一開始就可以設定顯示文字、顏色等等,讓使用者可以直觀了解用途,也讓開發者可以根據自己需求創作。
更多詳細資訊可以參考 Discord.py Button 官方文檔

二、Button 撰寫:

Class

使用時機為函式中直接宣告時,設置 url 參數會變超連結按鈕,撰寫 Button 交互事件需要新增一個回呼函式或者搭配持續監聽事件。

discord.ui.Button(label: str, style: discord.ButtonStyle, emoji: Union[PartialEmoji, Emoji, str], custom_id: str, disabled: bool, url: str, row: int)
  • label 標籤
    Button 顯示的文字。
  • style 風格
    Button 的風格,參考註一
  • emoji 表情符號
    Button 的表情符號。
  • custom_id 交互 ID
    交互期間收到的 Button ID,如果設置為 URL Button 則沒有自定義 ID。
  • disabled 禁用
    Button 是否禁用。
  • url 網址
    Button 導航使用者前往的網址。
  • row 相對行號
    Discord 訊息允許 Item 元素最多 5 行,預設情況會自動排序,如果要控制相對位置,則行號 row = 1 會在 row = 3 之前,行號必須介於 0 到 4 之間。

裝飾器

使用時機為添加在 View 類別中,撰寫 Button 交互事件只需要在裝飾器底下即可。

@discord.ui.button(label: str, style: discord.ButtonStyle, emoji: Union[PartialEmoji, Emoji, str], custom_id: str, disabled: bool, row: int)
  • label 標籤
    Button 顯示的文字。
  • style 風格
    Button 的風格,參考註一
  • emoji 表情符號
    Button 的表情符號。
  • custom_id 交互 ID
    交互期間收到的 Button ID,如果設置為 URL Button 則沒有自定義 ID。
  • disabled 禁用
    Button 是否禁用。
  • row 相對行號
    Discord 訊息允許 Item 元素最多 5 行,預設情況會自動排序,如果要控制相對位置,則行號 row = 1 會在 row = 3 之前,行號必須介於 0 到 4 之間。

三、Button 交互方式:

回呼函式(Callback)

額外撰寫一個交互函式,並讓 Button 呼叫此函式。

優點 缺點
多個按鈕可以共用同個函式 可讀性較差,查看按鈕功能需要自行對照函式
  • 回呼函式
async def button_callback(interaction: discord.Interaction): await interaction.response.edit_message(content = "Hello, world!")
  • 主函式
@app_commands.command(name = "button_interaction_callback", description = "Button 回呼函式交互") async def button_interaction_callback(self, interaction: discord.Interaction): # 宣告 View view = discord.ui.View() # 使用 class 方式宣告 Button button = discord.ui.Button( label = "Click", style = discord.ButtonStyle.blurple ) # Button 連接回呼函式 button.callback = button_callback # 將 Button 添加到 View 中 view.add_item(button) await interaction.response.send_message(view = view)


被裝飾函式(Decorator)

在 Button 裝飾器底下撰寫一個交互函式。

優點 缺點
按鈕與函式綁定,不用額外對照函式 多一個 button: discord.ui.Button 參數
  • 自定 View
class ButtonView(discord.ui.View): def __init__(self, timeout: float | None = 180): super().__init__(timeout = timeout) # 使用裝飾器方式創建 Button,交互函式直接寫在裝飾器底下 @discord.ui.button( label = "Click", style = discord.ButtonStyle.blurple ) async def button_decorator(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.edit_message(content = "Hello, world!")
  • 主函式
@app_commands.command(name = "button_interaction_decorator", description = "Button 被裝飾函式交互") async def button_interaction_decorator(self, interaction: discord.Interaction): # 宣告自定 View view = ButtonView() await interaction.response.send_message(view = view)


持續監聽事件(Event Listener)

on_interaction() 是一個交互持續監聽事件,幫 Button 自定義設置 custom_id 參數,比對交互時的 custom_id 即可執行相對應的操作。

優點 缺點
按鈕不會超時,可以製作永久按鈕 需要設置 custom_id 參數,按鈕操作塞在同一函式的可讀性較差
  • 持續監聽函式
@commands.Cog.listener() async def on_interaction(self, interaction: discord.Interaction): # interaction.data 是一個包含交互資訊的字典 # 有些交互不包含 custom_id,需要判斷式處理來防止出錯 if "custom_id" in interaction.data: if interaction.data["custom_id"] == "hello_world": await interaction.response.edit_message(content = "Hello, world!")
  • 主函式
@app_commands.command(name = "button_interaction_on", description = "Button 持續監聽交互") async def button_interaction_on(self, interaction: discord.Interaction): # 宣告 View view = discord.ui.View() # 使用 class 方式宣告 Button 並設置 custom_id button = discord.ui.Button( label = "Hello, world!", style = discord.ButtonStyle.blurple, custom_id = "hello_world" ) # 將 Button 添加到 View 中 view.add_item(button) await interaction.response.send_message(view = view)


四、文章註解:

註一

底下列出 Discord Button 的所有風格,詳細內容可參考 Discord.py ButtonStyle 官方文檔

名稱 樣式
primary / blurple 藍色
secondary / grey / gray 灰色
success / green 綠色
danger / red 紅色
link / url 超連結


📢 歡迎加入我的 Discord 伺服器
https://discord.gg/Jtd3eVrFJs

Copyright © 2023 SmallShawn95. All rights reserved.