[Day 17] 互動視窗 Modal
今天來介紹如何用 Discord BOT 傳送 Modal 給使用者填資料。
進度
除了傳送訊息,Discord BOT 也可以傳送一個可以互動的彈出視窗,也就是今天的主題 ── Modal。
Modal 的中文翻譯感覺沒有很統一,包含:互動視窗、模態框等,所以後續文章我會繼續維持使用原文 Modal 來稱呼。
什麼是 Modal?
用比較通俗一點的講法,Modal 就是所謂的「彈出視窗」,在使用者關閉或完成之前,不能做其他的事情。Modal 在前端開發上是一個很常見的元件,通常會用於提醒、通知,或是表單,也因此,在許多 UI Library 都會有對應的設計。
會說「對應」是因為有些 Library 定義的是 Dialog,不是 Modal。至於 Modal 與 Dialog 又有什麼異同舊式另一個話題了…
而 Discord 的 Modal 比較狹隘一點,它是讓 App (例如:Discord BOT) 收集表單類型的資料用的彈出視窗介面。
原文:Modals are single-user pop-up interfaces that allow apps to collect form-like data. (Discord 的說明)
而且,Modal 的使用也有兩個比較大的限制。第一,它只能由應用指令 (例如:斜線指令) 或是可以互動的元件 (例如:按鈕) 來觸發。換句話說,只有互動類 (Interaction
) 的觸發條件才能彈出 Modal 給使用者。第二,Modal 中的元件只能是 Text Input (編號為 4),不能使用按鈕、下拉式選單等其他元件。
第一個 Modal
如同先前所述,Modal 的觸發有一些限制,所以這邊使用斜線指令 (slash command) 來做為範例。
忘記那是什麼的朋友可以回去複習一下 Day 11 的文章
1 | import discord |
執行後,用 /ping
觸發,就可以看到 Modal:
簡單填寫一下。
送出後,就會收到這條訊息:
發生了什麼事?
有關 bot 與 slash command 的部分就不再介紹了。重點在這兩個部分:
- 建立 Modal 的 subclass
- 傳送 Modal
1. 建立 Modal 的 subclass
1 | class Questionnaire(discord.ui.Modal, title="Questionnaire Response"): |
在建立 Modal 時,需要先建立一個 Modal 的 subclass,接著再設定裡面的各個欄位 (Text Input)。最後,再設定 on_submit
,也就是 Modal 內的資料提交時所觸發的函數。
2. 傳送 Modal
這部分就簡單多了,從之前的 send_message
改成 send_modal
,傳送的內容也改成 Modal 物件就好了。
1 | await interaction.response.send_modal(Questionnaire()) |
認識一下 Text Input
Text Input 有幾個常用的參數:
label
(str
):標籤,也就是這個 Text Input 的標題style
(discord.TextStyle
):風格,只有兩種,分成 short 和 paragraph (long) (可以參考文件)placeholder
(str
):提示文字default
(str
):預設值required
(bool
):是否為必填 (預設為True
)min_length
(int
):至少要輸入的字串長度 (0 到 4000)max_length
(int
):至多能輸入的字串長度 (1 到 4000)row
(int
):排序編號。一個 Modal 至多只能有 5 個 Text Input,所以 row 必須介於 0 到 4 之間,而且不能重複。(沒設定的話,就會依照程式碼的順序排列)
其他參數細節可以看 discord.py 的文件
補充
如果想要同時傳遞 Modal 和訊息的話 (不太建議),可以用 interaction.channel.send
,不要用 interaction.response.send
,因為一個 interaction 只能 response 一次。
1 |
|
小結
今天介紹了如何建立 Modal,需要特別記得的點有兩個:
- 只能由 Interaction 觸發
- Modal 內只能有 Text Input