iT邦幫忙

2024 iThome 鐵人賽

DAY 18
1
Python

用 Python 打造你的 Discord BOT系列 第 18

[Day 18] 投票 Poll

  • 分享至 

  • xImage
  •  

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

進度

今天要介紹的是 Discord BOT 執行內容的第三種:建立投票。

不過,因為這個功能還算挺新的,網路上的教學或範例也頗少,所以我就只能邊看文件邊憑直覺去嘗試看看了,如果各位看完文章覺得有地方不合理,或甚至寫錯,就再請各位留言說一下,謝謝!

投票 (Poll)

早期的 Discord 並沒有投票功能,往往需要依靠 Discord BOT 的輔助才能進行投票,或者就簡單地用回應表情符號來當作投票。好在最後千呼萬喚始出來終於在 2024 年上半年新增了投票功能。

如果還不會使用的話,可以參考這篇教學

而在今年 6 月,discord.py 也發布了 v2.4.0,開始支援投票相關的功能。

建立第一個投票

這次的範例程式碼比較長~

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 傳送的訊息,以及投票結果。

發生了什麼事?

這次的程式碼內容比較多,主要要討論的部分有兩個:

  1. 設定 slash command:建立投票
  2. 設定 message command:投票截止

1. 設定 slash command:建立投票

@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,並設定投票的基本訊息,包含:

  1. question:這次投票所問的問題 (必要參數)
  2. duration:這次投票期間的長度 (必要參數) (注意,格式一定要是 timedelta,並且至少要 1 小時)
  3. multiple:是否開放多選

接下來就是用 add_answer 添加選項,可以設定 textemoji

最後,在 send_message 時記得設定 poll=poll 就好了。

概念其實跟前面介紹過的 Embed、View 很像,都是先建立一個類似容器的東西,再把剩下的東西加進去。

2. 設定 message command:投票截止

這部分比較不是必要的,但我覺得要加上這個功能才算完整

@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) 和提前截止投票。

後來才發現原來颱風日期寫錯,應該是 10/1、10/2 才對...


上一篇
[Day 17] 互動視窗 Modal
下一篇
[Day 19] 日誌系統
系列文
用 Python 打造你的 Discord BOT31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言