今天來介紹 Discord 的投票功能。
進度

今天要介紹的是 Discord BOT 執行內容的第三種:建立投票。
不過,因為這個功能還算挺新的,網路上的教學或範例也頗少,所以我就只能邊看文件邊憑直覺去嘗試看看了,如果各位看完文章覺得有地方不合理,或甚至寫錯,就再請各位留言說一下,謝謝!
投票 (Poll)
早期的 Discord 並沒有投票功能,往往需要依靠 Discord BOT 的輔助才能進行投票,或者就簡單地用回應表情符號來當作投票。好在最後千呼萬喚始出來終於在 2024 年上半年新增了投票功能。
如果還不會使用的話,可以參考這篇教學
而在今年 6 月,discord.py
也發布了 v2.4.0
,開始支援投票相關的功能。
建立第一個投票
這次的範例程式碼比較長~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import discord from discord.ext import commands
GUILD_ID = "your guild ID" MY_GUILD = discord.Object(id=GUILD_ID)
class MyBot(commands.Bot): def __init__(self, *, command_prefix: str, intents: discord.Intents): super().__init__(command_prefix=command_prefix, intents=intents)
async def setup_hook(self): self.tree.copy_global_to(guild=MY_GUILD) await self.tree.sync(guild=MY_GUILD)
intents = discord.Intents.default() bot = MyBot(command_prefix="", intents=intents)
@bot.tree.command() async def ping(interaction: discord.Interaction): poll = discord.Poll( question="中颱山陀兒快來了,你覺得下週哪一天會放颱風假 (台北市)?", duration=datetime.timedelta(hours=1), ) poll.add_answer(text="9/1 (二)") poll.add_answer(text="9/2 (三)") poll.add_answer(text="9/1、9/2 兩天都放假") poll.add_answer(text="不會放假")
await interaction.response.send_message("來投票!", poll=poll)
@bot.tree.context_menu(name="Stop Poll") async def stop_poll(interaction: discord.Interaction, message: discord.Message): poll = message.poll
if poll is None: await interaction.response.send_message("未找到投票...", ephemeral=True) else: await poll.end() await interaction.response.send_message("投票提前截止成功!", ephemeral=True)
client.run('token')
|
來看一下效果:

選擇要投的選項

按下「投票」按鈕

對著訊息按下滑鼠右鍵,找到 Stop Poll 並執行。

執行後,投票就提前截止了。

並且下方還會看到 Discord BOT 傳送的訊息,以及投票結果。

發生了什麼事?
這次的程式碼內容比較多,主要要討論的部分有兩個:
- 設定 slash command:建立投票
- 設定 message command:投票截止
1. 設定 slash command:建立投票
1 2 3 4 5 6 7 8 9 10 11 12
| @bot.tree.command() async def ping(interaction: discord.Interaction): poll = discord.Poll( question="中颱山陀兒快來了,你覺得下週哪一天會放颱風假 (台北市)?", duration=datetime.timedelta(hours=1), ) poll.add_answer(text="9/1 (二)") poll.add_answer(text="9/2 (三)") poll.add_answer(text="9/1、9/2 兩天都放假") poll.add_answer(text="不會放假")
await interaction.response.send_message("來投票!", poll=poll)
|
首先,要先建立 Poll
,並設定投票的基本訊息,包含:
question
:這次投票所問的問題 (必要參數)
duration
:這次投票期間的長度 (必要參數) (注意,格式一定要是 timedelta
,並且至少要 1 小時)
multiple
:是否開放多選
接下來就是用 add_answer
添加選項,可以設定 text
和 emoji
。
最後,在 send_message
時記得設定 poll=poll
就好了。
概念其實跟前面介紹過的 Embed、View 很像,都是先建立一個類似容器的東西,再把剩下的東西加進去。
2. 設定 message command:投票截止
這部分比較不是必要的,但我覺得要加上這個功能才算完整
1 2 3 4 5 6 7 8 9
| @bot.tree.context_menu(name="Stop Poll") async def stop_poll(interaction: discord.Interaction, message: discord.Message): poll = message.poll
if poll is None: await interaction.response.send_message("未找到投票...", ephemeral=True) else: await poll.end() await interaction.response.send_message("投票提前截止成功!", ephemeral=True)
|
在某些情況下,會希望投票能提早截止。一般來說只要對著投票按下滑鼠右鍵,選擇「立即結束投票」就好了。

不過,能提早截止投票的人,只有發起投票的人。這件事看起來挺合理,但如果今天發起人是 Discord BOT,那就有一點點麻煩了。畢竟,不是所有東西都可以設定 custom_id
的。
但好在有 message command 這個功能,透過 Message 的 poll
屬性就可以拿到當初的 Poll
物件。接下來只要再執行 await poll.end()
就可以了。
小結
今天介紹了如何用 Discord BOT 建立投票 (Poll) 和提前截止投票。