2
1

discordを運営していくにあたって、よく目にする飯テロに対して自動で返信するBOTを作ってみました。
discordBOTの導入手順などは色んな箇所で見かけるので割愛しますが、参考となる情報をまとめに記載しておきます。

最後にサンプルコード全文を記載しておきます。

各所の説明

ここにトークンのIDを設定します。

tokenID = 'ここにトークンIDを入れる'

自動返信する際に、画像付きでメッセージを返すための画像設定をここで行います。
画像ファイルは、imgフォルダを作成し、1.jpgとして準備しておきます。
IMAGE_MAXの値が2の場合は、1.jpgと2.jpgを作成します。
sample_eat_messageは返答するメッセージをランダムで返します。
IMAGE_MAXと同じ数にしておく必要はありません。

IMAGE_MAX = 2
sample_eat_message = ['','','']

キーワードに応じて返答するメッセージは、特定のキーワードがヒットした場合、必ずメッセージを返します。
例)ぬるぽ->ガッ!!
※画像添付(飯テロ画像)がなかった場合のみ対象

text_action = {
    ''      : '',
    ''      : '',
    ''      : '',
}

飯テロ画像でもなく、特定キーワードでもない場合、ランダムで自動返信するメッセージの設定もします。
RANDAM_WEIGHTはキーワード返答の時に反応する重みを設定します。約3回に1回の場合は3を設定
通常のメッセージを返信する事が決定した場合、sample_messageのメッセージをランダムで返します。

RANDAM_WEIGHT = 3
sample_message = ['','','']

各サーバーの情報は、config.iniで管理するため、1つ設定しておくだけで色んなサーバーで利用することができます。
ぜひお試しください。

サンプルコード全文

main.py
import discord
import discord.app_commands
import configparser
import random
import re

#########################
#   設定ファイル情報
#########################
CONF_PATH = './config.ini'
config = configparser.ConfigParser()
config.read(CONF_PATH, encoding='utf-8')
#########################
#   Discord設定情報
#########################
# ディスコードのトークンID
tokenID = 'ここにトークンIDを入れる'
# discord.Intents.all()を使用するとpresencesやmembersも有効な状態になります。
intents = discord.Intents.all()
# intents = discord.Intents.default()
# 用途に応じて以下のように無効化することもできます。設定できる項目は、以下のURLを参照してみてください。
# https://discordpy.readthedocs.io/ja/latest/api.html#discord.Intents
# discord_intents.bans = False # on_member_banやon_member_unbanのイベントを無効化
# intents.message_content = True
client = discord.Client(intents=intents)
tree = discord.app_commands.CommandTree(client)
#########################
#   個別設定情報
#########################
IMAGE_MAX = 2
# 画像を張り付けたら必ず返すメッセージ
sample_eat_message = ['','','']

# キーワードに応じて返答するメッセージ
text_action = {
    ''      : '',
    ''      : '',
    ''      : '',
}

# キーワード返答の時に反応する(3 = 0.3)
RANDAM_WEIGHT = 3
# 通常ランダムメッセージを返す
sample_message = ['','','']

#########################
#   スラッシュコマンド受信イベント
#########################
@tree.command(
    name="rice-terrorism",
    description="飯テロチャンネルを選択してください"
)
@discord.app_commands.default_permissions(
    administrator = True  #管理者のみ設定可能
)
async def hoge(ctx:discord.Interaction):
    try:
        guildid = str(ctx.guild_id)         # サーバーID
        channelid = str(ctx.channel_id)     # チャンネルID
        # サーバーセクションの存在チェック
        if not config.has_section(guildid):
            # 存在しない場合は作成する
            config.add_section(str(guildid))

        # チャンネルの設定
        config.set(guildid, 'channelid', channelid)
        # config_1.iniファイルに上書き
        with open(CONF_PATH, "w") as file:
            config.write(file)

        await ctx.response.send_message(f"飯テロチャンネルとして設定しました")
    except Exception as e:
        print(str(e))

#########################
#   開始イベント
#########################
@client.event
async def on_ready():
    print("on_ready MeshiTero")
    print(discord.__version__)
    await tree.sync()#スラッシュコマンドを同期

#########################
#   メッセージ受信イベント
#########################
@client.event
async def on_message(message):
    try:
        # bot判定>BOTは除外
        if message.author.bot:
            return

        # 受信ステータスの取得
        guildid = str(message.guild.id)                     # サーバーIDを取得
        channelid = str(message.channel.id)                 # チャンネルIDを取得
        channel = client.get_channel(message.channel.id)    # チャンネル名を取得

        # 送信処理
        try:
            # サーバーが存在しない場合は処理を抜ける
            if not config.has_section(guildid):
                return

            # チャンネルIDが存在しない場合は処理を抜ける
            if not config.has_option(guildid, 'channelid'):
                return

            # 設定ファイルからチャンネルIDの取得
            save_channelid = config.get(guildid, 'channelid')
            # 受信チャンネルIDが設定したチャンネルIDの場合
            if channelid == save_channelid:
                content = ''
                ########################
                #   ここに飯テロ処理を実行する前に行う処理を記述する
                ########################

                if content != '':
                    # 送信処理(content:送信メッセージ reference:返信元)
                    await message.channel.send(content, reference = message)
                else:
                    if len(message.attachments) == 0:
                        # 添付ファイルが存在しない場合

                        # 特定のキーワードに応じて返答する処理
                        for action_msg in text_action:
                            if action_msg in message.content:
                                content = text_action[action_msg]

                        # ランダム処理(0:1 の重み ?:1)
                        if random.choices([0, 1], weights=[RANDAM_WEIGHT, 1])[0] == 1:
                            content += sample_message[random.randrange(len(sample_message))]

                        if content != '':
                            # 送信処理(content:送信メッセージ reference:返信元)
                            await message.channel.send(content, reference = message)
                    else:
                        # 添付ファイルが存在する場合

                        # 画像をランダムで取得(1.jpg,2.jpg...)
                        fname = str(random.randrange(IMAGE_MAX)) + '.jpg'
                        # ローカル画像からFileオブジェクトを作成(imgファイル内)
                        file = discord.File(fp="img/" + fname,filename=fname,spoiler=False) 
                        # ランダムでメッセージを取得
                        content = sample_eat_message[random.randrange(len(sample_eat_message))]
                        # 送信処理(content:送信メッセージ reference:返信元)
                        await message.channel.send(content, file=file, reference = message)

        except Exception as e:
            print(str(e))
    except Exception as e:
        print(str(e))

#########################
#   開始処理
#########################
if __name__ == '__main__':

    try:
        client.run(tokenID)
    except Exception as e:
        print(str(e))
        pass


まとめ

参考情報

■ 全体資料

・Python Discord ボットのチュートリアル – Discord ボットをコーディングして無料でホストする
    https://www.freecodecamp.org/japanese/news/create-a-discord-bot-with-python/

■ プログラミング資料

・指定したチャンネルにメッセージを送信する方法まとめ
    https://scrapbox.io/discordjs-japan/%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%81%AB%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%BE%E3%81%A8%E3%82%81

・discord.pyでスラッシュコマンドを実装する。
    https://qiita.com/beatbox4108/items/0d28619bb49e86f58ace

・discord.py V2のスラッシュコマンドを使えるようにする
    https://qiita.com/Luapy/items/3abff9575e132e2955ec

■ 設定資料

・常駐プログラム (Python) をWindowsにサービス登録
    https://nuxtblog.work/blog/fgj5szar4gjs/

・Discord DeveloperのPermissions 日本語まとめ【開発者向け】
    https://narikakun.net/technology/discord-developer-permissions/

        権限名                  権限名(説明)
        CREATE_INSTANT_INVITE   招待を作成(この権限を持つメンバーは招待を作成できます。)
        KICK_MEMBERS	        メンバーをキック(この権限を持つメンバーはメンバーをキックする権限を持ちます。)
        BAN_MEMBERS	            メンバーをBAN(この権限を持つメンバーはメンバーをBANする権限を持ちます。)
        ADMINISTRATOR	        管理者(この権限を持つメンバーはすべての権限を持ち、チャンネル固有の権限もバイパスします。この権限を付与することは 危険です。)
        MANAGE_CHANNELS	        チャンネルの管理(この権限を持つメンバーは、新しいチャンネルを作成、編集またはチャンネルを削除できます。)
        MANAGE_GUILD	        サーバー管理(この権限を持つメンバーは、サーバー名の変更と地域の変更ができます。)
        ADD_REACTIONS	        リアクションの追加(この権限を持つメンバーは、メッセージへの新たなリアクションを加えることができます。この権限がなくても、メンバーは メッセージにすでに付いている選択肢から、リアクションをすることが可能です。)
        VIEW_AUDIT_LOG	        監視ログの表示(この権限が与えられたメンバーは、サーバーの監査ログへのアクセス権を保有します。)
        PRIORITY_SPEAKER	    優先スピーカー(この権限を持つユーザーは、話しが聞き取られやすくなります。有効にすると、 この権限のない他の人の音量は自動的に下がります。優先スピーカーは、プッシュツートーク(優先)キーバインドを使用して有効化されます。)
        STREAM	                動画(権限を持つメンバーは、このサーバーで配信できます。)
        VIEW_CHANNEL	        テキストチャンネルの閲覧&ボイスチャンネルの表示(この権限を持つメンバーは、テキストチャンネルの閲覧とボイスチャンネルの表示ができます。)
        SEND_MESSAGES	        メッセージを送信(この権限を持つメンバーは、メッセージを送信することができます。)
        SEND_TTS_MESSAGES	    TTSメッセージを送信(この権限を持つメンバーは、/ttsをメッセージの始めに付けることで、テキスト読み上げ機能のメッセージを送ることができます。このメッセージはチャンネル内の全員が聞くことが 可能です。)
        MANAGE_MESSAGES	        メッセージの管理(この権限を持つメンバーは、他のメンバーのメッセージを削除したり、任意のメッセージをピン留めしたりできます。)
        EMBED_LINKS	            埋め込みリンク(この権限を持つメンバーは、埋め込みリンクを送信することが可能です。)
        ATTACH_FILES	        ファイルを添付(この権限を持つメンバーは、ファイルを添付することが可能です。)
        READ_MESSAGE_HISTORY	メッセージ履歴を読む(この権限を持つメンバーは、メッセージの履歴を読むことができます。)
        MENTION_EVERYONE	    @everyone、@here、全てのロールにメンション(この権限のあるメンバーは、@everyone または @here を使って、このチャンネルの全メンバーにpingできます。また、全てのロールに @mention できます。これはロールの「全員がこのロールにメンションすることを許可する」が無効化されている場合でも有効です。)
        USE_EXTERNAL_EMOJIS	    外部の絵文字の使用(この権限を持つメンバーは、このサーバー上で他のサーバーの絵文字を使うことができます。)
        VIEW_GUILD_INSIGHTS	    不明(この権限を持つメンバーは、サーバーのインサイトにアクセスすることができます。)
        CONNECT	                接続(この権限を持つメンバーは、音声チャネルに接続することができます。)
        SPEAK	                発言(この権限を持つメンバーは、音声チャネルで発言することができます。)
        MUTE_MEMBERS	        メンバーをミュート(この権限を持つメンバーは、音声チャネルでメンバーをミュートとできます。)
        DEAFEN_MEMBERS	        メンバーのスピーカーをミュート(この権限を持つメンバーは、音声チャンネルのメンバーのスピーカーをオフにできます。)
        MOVE_MEMBERS	        メンバーの移動(この権限を持つメンバーは、他のメンバーをこのチャンネルから移動させることができます。移動が可能となるチャンネルは、この権限を持つメンバー、そして移動させられるメンバー両方がアクセス権を持つ チャンネルのみです。)
        USE_VAD	                音声検出を使用(この権限が無効の場合、メンバーはプッシュツートークをチャンネル内で使用しなければいけなくなります。)
        CHANGE_NICKNAME	        ニックネームの変更(この権限を持つユーザーは、自分のニックネームを変更することができます。)
        MANAGE_NICKNAMES	    ニックネームの管理(この権限を持つユーザーは、他のメンバーのニックネームを変更することができます。)
        MANAGE_ROLES	        ロールの管理(この権限を持つメンバーは、新しくロールを作成したり、自身よりも下位の権限を編集または削除することができます。)
        MANAGE_WEBHOOKS	        ウェブフックの管理(この権限を持つメンバーは、ウェブフックを作成、編集および削除することができます。)
        MANAGE_EMOJIS	        絵文字の管理(この権限を持つユーザーは、絵文字を管理することができます。)

'''

2
1
0

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
2
1