從零開始的Discord機器人(6) - 其他功能
本篇會介紹如何使用Modals、Context Menus與Embed,為本系列作一個收尾。
在上一篇中,介紹了Components的作用與使用方法。接下來,我決定將剩下的Modal(表單)、Context Menus(右鍵選單)與Embed(嵌入式訊息)在本篇一次介紹完,這個從零開始的Discord機器人系列就算告一個段落了。
由於要擴充Modal與Context Menus的功能其實和上一篇Components的思路基本上是一致的,所以這邊就不再重複介紹一遍如何接收事件的部分,只專注於建立這些物件。如果想知道如何擴充,可以返回上一篇跟著做。
1. Modal
第一個要介紹的是Modal(表單)。Modal和Component不同,它們並不需要依附於回應中,而是使用interaction.showModal ()
來顯示建立好的表單。
正如上一篇所說,Discord.js為建立這些物件提供了方便的Builder,因此我們也有ModalBuilder ()
可以使用。以下是一個Modal的範例:
const modal = new ModalBuilder()
.setCustomId('myModal')
.setTitle('My Modal');
如此一來就能建立一個Modal,並幫它設定一個CustomId與Title了。
但目前這個Modal裡面還沒有欄位,要幫Modal加入欄位其實和上一篇送出Components是一模一樣的。我們需要使用TextInputBuilder ()
建立一個文字輸入的欄位,並一樣裝進Action Row內,最後再使用addComponents ()
加進去即可。
需要注意的是,一個Modal裡最多可以放入5個Action Rows,每個Action Row都只能放入一個Text Input,並且目前無法放入Buttons與Select Menus。以下是加入Text Inputs並塞入Modal內的範例:
const favoriteColorInput = new TextInputBuilder ()
.setCustomId ('favoriteColorInput')
.setLabel ("What's your favorite color?")
.setStyle (TextInputStyle.Short);
const hobbiesInput = new TextInputBuilder ()
.setCustomId ('hobbiesInput')
.setLabel ("What's some of your favorite hobbies?")
.setStyle (TextInputStyle.Paragraph);
const firstActionRow = new ActionRowBuilder ()
.addComponents (favoriteColorInput);
const secondActionRow = new ActionRowBuilder ()
.addComponents (hobbiesInput);
modal.addComponents (firstActionRow, secondActionRow);
你可以使用setStyle ()
設定Text Input的類型,TextInputStyle.Short
為單行欄位,而TextInputStyle.Paragraph
為多行欄位。如果希望欄位為必填,可以使用setRequired ()
將其設為必填。
最後,當Modal送出之後,可以使用interaction.isModalSubmit ()
確認接收到的interaction是否為表單送出,並使用CustomId作為判斷。
2. Context Menus
接下來要介紹的是Context Menus(右鍵選單)。右鍵選單應該是全部裡面最單純的的功能了,只需要為選項設定一個名稱與類型即可。以下是一個ContextMenuCommandBuilder ()
的範例:
const data = new ContextMenuCommandBuilder ()
.setName ('User Information')
.setType (ApplicationCommandType.User);
你可以使用setType ()
設定這個右鍵選單要顯示在何處,ApplicationCommandType.User
為對成員右鍵時顯示,而ApplicationCommandType.Message
為對訊息右鍵時顯示。
最後,當使用右鍵選單之後,可以使用interaction.isContextMenuCommand ()
確認接收到右鍵選單,或者想要比較細一點可以使用isMessageContextMenuCommand()
和isUserContextMenuCommand()
判斷是對成員右鍵或是對訊息右鍵。
你可以注意到只有右鍵選單沒有使用到CustomId,取而代之的是使用interaction.targetUser
與interaction.targetMember
取得目標成員,以及使用interaction.targetMessage
取得目標訊息。
3. Embed
最後一個要介紹的是Embed(嵌入式訊息)。Embed是一種可以透過自訂排版、顯示圖片、加上超連結等一系列功能,方便我們美化並清楚展示資訊的特殊排版。
![](https://blog.anisile.cc/content/images/2023/09/image-1.png)
以上面的Embed為範例,下面就直接展示程式碼,並一一解釋每個function對應的位置:
const exampleEmbed = new EmbedBuilder()
.setColor(0x0099FF)
.setTitle('Some title')
.setURL('https://discord.js.org/')
.setAuthor({ name: 'Some name', iconURL: 'https://i.imgur.com/AfFp7pu.png', url: 'https://discord.js.org' })
.setDescription('Some description here')
.setThumbnail('https://i.imgur.com/AfFp7pu.png')
.addFields(
{ name: 'Regular field title', value: 'Some value here' },
{ name: '\u200B', value: '\u200B' },
{ name: 'Inline field title', value: 'Some value here', inline: true },
{ name: 'Inline field title', value: 'Some value here', inline: true },
)
.addFields({ name: 'Inline field title', value: 'Some value here', inline: true })
.setImage('https://i.imgur.com/AfFp7pu.png')
.setTimestamp()
.setFooter({ text: 'Some footer text here', iconURL: 'https://i.imgur.com/AfFp7pu.png' });
setColor ()
:顯示於Embed左側邊緣的顏色。setTitle ()
:Embed的標題。setURL ()
:點擊標題時會導向的網址。setAuthor ()
:Embed顯示的作者,可以設定名稱、icon,也能設定點擊作者時導向的網址。setDescription ()
:顯示關於Embed的描述。setThumbnail ()
:Embed的縮略圖,會在右上角顯示。addFields ()
:需要新增欄位時使用,每一個欄位都必須包含name、value這兩個值,如果想要讓一些欄位並排在同一行,可以加上inline這個值。你可能有注意到其中一個name與value為\u200b
的欄位,\u200b
是一種特殊字元,意思是寬度為0的空格,可以用來作為建立空格欄位使用。setImage ()
:Embed包含的圖片。setTimestamp ()
:顯示建立Embed的時間。setFooter ()
:顯示Embed的Footer。
實際上使用Embed時,你不需要像上面那樣設定所有的部分,可以根據自己的需要增減設定即可。由於Discord API的限制,Embed的各個欄位都有不同的字數限制,而自訂的欄位也有數量限制,你可以看這裡得到更詳盡的限制。完成建立Embed之後,送出Embed的方式也和送出Component一樣,我們只需要這麼做:
interaction.reply({
embeds: [embed],
})
如此一來,機器人的回應底下就會顯示Embed囉!
4. 結語
到這裡,從零開始的Discord機器人系列就告一個段落了。不過,這裡所介紹的內容還遠遠不是Discord.js的全部。想要知道Discord.js還有什麼功能,或是在製作機器人時有遇到困難,都可以閱讀官方文件,我相信都能找到你需要的資訊的。
如果你是從第一篇一路看到最後一篇,在這裡說一聲謝謝你!(當然就算不是我也很感謝你)這是我第一次寫這種系列文,如果有遇到問題或想要提供建議,都歡迎聯繫我,謝謝。
感謝你看到這邊,我們下個系列見。