0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

discord.py を使って簡単な投票機能を作る

Posted at

はじめに

Qiitaで記事を書いてみようと思ってのですが、特にネタもなかったので私がBOT開発初心者の時に作成した簡単な投票機能を持つBOTのお話を載せることにしました。
基本的な例外処理は実装してあり、約1年動かしてますが特に不具合もなく動いているので安心して使えると思います(?)
まあ簡単な仕組みだし

※ discord の BOT 用の TOKEN の取得などの部分は参考URLとかを見てください。
※ 当時は discord bot 向けの command フレームワークがあるのを知らなかったので、on_message で書いてあります…

作ったもの

Yes-No疑問文と複数選択肢の疑問文について投票ができ、絵文字にリアクションすることで解答します。

###Yes-No疑問文
以下のコマンドを打つことで

question.yes-no.[質問文]

こんな感じの投票をしてくれます。
yes-no.png

###複数選択肢の質問
以下のコマンドで、最大10個まで選択肢を設けられて

question.vote.[質問文].[選択肢1].[選択肢2].[選択肢3]

こんな感じの投票ができます。
vote.png

作成したもの

そんなに難しい部分はないと思うので、それぞれについて解説するよりかは全体のコードを読んでもらった方がわかりやすいかと。BOTのアクセストークンを入れれば動くと思うので、色々いじって試してみてください。

import discord

# 自分のBotのアクセストークン
TOKEN = 'myTOKEN'

# Reaction
list_yesno = ['🙆‍♂️', '🙅‍♂️']
list_vote = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟']


def emphasize(text):
    return "**" + text + "**"


def underline(text):
    return "__" + text + "__"


def isContainedNoInput(command):
    for i in command:
        if i == "":
            return True
    return False


client = discord.Client()


# メッセージ受信時に動作する処理
@client.event
async def on_message(message):
    # メッセージ送信者がBotだった場合は無視する
    if message.author.bot:
        return

    # コマンドのセパレータは"."
    command = message.content.split(".")

    # 投票関連のコマンド
    if command[0] == "question":

        # セパレータによる不自然な挙動を防止
        if isContainedNoInput(command):
            await message.channel.send("無効なコマンドです (セパレータが連続もしくは最後に入力されています)")
            return

        try:
            # Yes-No 疑問文
            if command[1] == "yes-no":
                embed = discord.Embed(title=command[2], description="", color=discord.Colour.blue())

                # 質問文を表示してYes,Noを絵文字でリアクション
                voting_msg = await message.channel.send(embed=embed)
                for i in range(len(list_yesno)):
                    await voting_msg.add_reaction(list_yesno[i])
                return

            # 選択肢のある疑問文 
            elif command[1] == "vote":
                embed = discord.Embed(title=command[2], description="", color=discord.Colour.green())

                # 選択肢の数を確認
                select = len(command) - 3
                if select > 10:
                    await message.channel.send("可能な選択肢は最大10個までです")
                    return

                # 選択肢を表示
                vote_candidate = command[3:]
                for i in range(len(vote_candidate)):
                    embed.description = embed.description + list_vote[i] + "   " + vote_candidate[i] + "\n"

                # リアクションによる回答欄を作成
                voting_msg = await message.channel.send(embed=embed)
                for i in range(select):
                    await voting_msg.add_reaction(list_vote[i])
                return

            # 使い方
            elif command[1] == "help":
                embed = discord.Embed(title="使用方法", description="", color=discord.Colour.red())
                embed.description = emphasize("question.[TYPE].[CONTENT] + .[CANDIDATE]\n") + \
                                    "注意 : 質問文や選択肢に\".\"を含めないでください\n" \
                                    "\n" \
                                    + emphasize("[TYPE] : \"yes-no\" or \"vote\"\n") + \
                                    underline("\"yes-no\" : \n") + \
                                    "Yes-No疑問文を作成します\n" \
                                    "[CANDIDATE]は必要ありません\n" \
                                    + underline("\"vote\" : \n") + \
                                    "選択肢が複数ある質問を作成します\n" \
                                    "[CANDIDATE]がない場合は質問文だけ表示されます\n" \
                                    "\n" \
                                    + emphasize("[CONTENT] : \n") + \
                                    "質問文に相当します\n" \
                                    "\n" \
                                    + emphasize("[CANDIDATE] : \n") + \
                                    "質問形式が\"vote\"である場合の選択肢です\n" \
                                    "選択肢として可能な最大個数は10個までです\n"
                await message.channel.send(embed=embed)

            # 以上のどの形式でもないものは形式不備を伝える
            else:
                await message.channel.send("質問形式が異なっています (2つめの引数が正しくありません)")
                return

        except IndexError:
            await message.channel.send("質問の入力形式に間違いがあります (引数が足りません)")
            return


# Botの起動とDiscordへの接続
client.run(TOKEN)

参考URL

  • discord bot の作成方法や環境構築、デプロイ方法は以下の記事に書いてあります。

  • Embed Text を用いて表示しています。以下の記事を参考にして自由にカスタマイズしてみてください。

0
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?