Discord Bot作成手順

チャットアプリ「Discord」ではbotという、プログラムで操作するアカウントを作ることが出来ます。有名なものだと「Dyno」や「mee6」等があります。どこかで見たことがある人も多いのではないでしょうか。

対応している言語はいくつかあるのですが、今回はシンプルで人気があるPythonを使います。
なるべく分かりやすく書いていきますが、今までプログラミングに全く触れたことがない方には少し厳しい所もあるかもしれません。

1.登録

既にやっている、この手順は知っているという方は3まで飛ばしてください。
Ⅰ.まずはbotアカウントを作ります。
このDiscordにログインした状態で、このURLにアクセスしてください。
ここからbotアカウントの作成ができます。
https://discord.com/developers
↓こんな感じの画面が出ると思います。

画像7

右上のNew Applicationを選択します。

画像2

アプリケーションを作成したら、次にBotアカウントの作成をします。
左のメニューから「Bot」を選んでください。

画像3

「Add bot」を押すと、確認の画面が出ます。
一度追加したら戻せませんよ、という趣旨のメッセージが出るので、「Yes, do it!」で実行します。

画像4

追加後、以下のような画面が出ると思います。
ここで名前、プロフィール画像等の設定をします。
すべて終わったら、TOKENをコピーして下さい。
これは絶対に他人に教えたり、外部に漏らさないようにしてください。
これを使ってbotを操作します。(これが漏れたらbotを乗っ取られます)

画像7

Ⅱ.作ったBotをサーバーに入れます。
Botアカウントが作れたら、Botを入れたいサーバーに招待しましょう。
左のメニューで「OAuth2」を選ぶと、URL Generatorが開きます。
ここの「Scopes」でbotを選ぶと、下にURLが生成されると思います。

画像7

その下の「bot permissions」で必要な権限にチェックを入れると上のURLに反映されるので、チェックを入れ終わったらCopyしてブラウザでアクセスして下さい。
そうすると以下のようなページが出るので、好きなサーバーを選んでBotを追加します。この地点ではまだオフラインです。
ここまでで一旦ブラウザでの作業は終了です。

画像9


2.基本のコード

いよいよbotのコードを書いていきます。Pythonが使える環境を準備してください。(おすすめの環境はvenv + PyCharmです。初心者におすすめの動画)
Pythonのターミナルを起動したら、まずはpipを使い、Discord.pyのライブラリをインストールします。
以下のコマンドを入力してください。

pip install discord.py[voice]

次にエディタを起動し、以下の基本のコードを書き実行してみて下さい。
これをベースに書き加えていく形になります。
トークンは、Botの管理ページからコピーしてきて下さい。(手順1-Ⅰ)

import discord

client = discord.Client()

@client.event
async def on_ready():
   print('ready')


client.run('トークン')

これを実行すると、コンソールに「ready」と出てbotがオンラインになったと思います。

これに、トリガー(Discordのイベント)と処理(何をするか)を組み合わせて書いていくことになります。
2つをまとめたものを「イベントハンドラ」と言います。
トリガーには以下のようなものがあります。

'''
起動時
'''
@client.event
async def on_ready():

'''
メッセージ受診時
'''
@client.event
async def on_message(message):

'''
リアクションが付いた時 ※Botがオンラインの時に送信されたメッセージのみ
'''
@client.event
async def on_reaction_add():

'''
リアクションが付いた時 ※サーバー内の全てのメッセージを検知可能
'''
@client.event
async def on_raw_reaction_add():

'''
誰かがサーバーに入った時
'''
@client.event
async def on_member_join(member):

'''
ボイスチャンネルの入出時
'''
@client.event
async def on_voice_state_update(member, before, after):

例えばメッセージに対して反応したい、そしてその反応をチャンネルごとに変えたい、といった場合はon_messageの下にその処理をすべて書きます。
on_messageを何個も書いてはいけません。
2つon_messageがあったからとしても、新規メッセージがあった際に動くのはより上にある方1つだけだからです。

また、外部ライブラリを使うことで、「Youtubeの音声をbotで流す」等多彩なことが出来るようになります。

3.サンプルコード

ここではいくつかの実際に使うようなコードを書いていきます。
これを参考にすると、自分で機能を開発する際にも書きやすくなるかもしれません。

コード中のチャンネル等の指定は全てIDで行っています。
何かしら理由がない限り、名前ではなくIDを使ったほうがいいです。
名前を変えた時にコードにも変更を加えなくてはいけなくなります。
IDは不変です。

全体のコードはGithubで公開しておくので、疑問点があった場合はそちらも見てみて下さい。
サンプルは後からも更新・追加予定です。

3-1. (基本)メッセージに反応して返す

@client.event
async def on_message(message):
    if message.content == 'A':
        await message.channel.send('B')

このコードでは「message.channel」で、on_messageで取得した「メッセージが送信されたチャンネル」を指定しています。

この指定を「message.channel」ではなく、client.channel.get(CHANNEL_ID)にすると、任意のチャンネルをIDで指定できます。
また、「if message.content」ではメッセージの内容をチェックしていますが、これを「message.channel.id」や「message.author.id」にしてチャンネルや送信者でチェックすることも出来ます。

PythonやJava等に触れたことのある人なら分かると思いますが、もちろん「startswith」や「endwith」を使うことも可能です。
これでコマンドの実装も可能です。

3-2.リアクションロール

この機能はmee6などの有名botにもあるので、ご存知の方も多いのではないでしょうか。

'''
リアクションを付けた時
'''
@client.event
async def on_raw_reaction_add(payload):
    message_id = payload.message_id
    guild_id = payload.guild_id
    guild = discord.utils.find(lambda g: g.id == guild_id, client.guilds)

# リアクションロールの処理
    if payload.emoji.name == "stamp1":
        role = discord.utils.get(guild.roles, name='role1')
    elif payload.emoji.name == "stamp2":
        role = discord.utils.get(guild.roles, name='role2')
 
    else:
        role = discord.utils.get(guild.roles, name=payload.emoji.name)
 
    if message_id != MESSAGE_ID_HERE:
        return
    if role is not None:
        member = discord.utils.find(lambda m: m.id == payload.user_id, guild.members)
        if member is not None:
            await member.add_roles(role)
            print(member)
 
        else:
            print("Member not found.")
 
    else:
        print("Role not found.")

これはリアクションが外されたときのコードも必要ですが、addの部分をremoveに置き換えるだけなので、省略しました。

MESSAGE_ID_HEREには反応してほしいメッセージIDを入力して下さい。
これはon_messageやbot.commandsと組み合わせて、反応してほしいメッセージIDをグローバル変数で渡すことで、ユーザーに決めさせることも出来ます。
また、他のイベントと組み合わせて使うことで、コマンドが入力されたらbotが最初にメッセージにリアクションを付けて分かりやすくする、などの処理も可能です。

上でも書きましたが、このイベントはbotが参加する前のメッセージでも反応できます。
それが必要ない場合は、on_reaction_addを使ったほうが多少シンプルに書けます。(その代わりbotが落ちたり再起動したら使えなくなります。)

このコードでは、on_raw_reaction_addから「payload」として他の処理に情報を渡し、そこから「payload.emoji.name」等で、付けられたリアクションの情報やユーザーの情報を取得しています。​

3-3. 定期実行

通常Pythonで使う、scheduleライブラリを使った方法では動作しません。
代わりに、discord.pyのtasksを使う必要があります。
以下はチャンネル(ID:123456789012345678)に、30秒毎にメッセージを送る処理です。

from discord.ext import tasks

@tasks.loop(seconds=30)
# 通常の関数
async def sample():
    ch = await client.get_channel(123456789012345678)
    await ch.send('テキスト')

以上が基本的なBotの書き方です。Pythonを触ったことがあると非同期処理などが理解できて楽なのではないでしょうか。

この他にわからないことがあれば、まずは公式ドキュメントを見ることをお勧めします。
公式ドキュメント

4.まとめ

いかかでしたでしょうか。
Discordは便利なチャットツールですが、Botを使うことによってさらに便利に使うことができます。

みなさんも是非使ってみてください。

この記事が気に入ったらサポートをしてみませんか?