Discordのbotを開発する Python版

# 概要

discordのAPIラッパーdiscord.pyを使ってbotを作ってみた。[ここ](https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f)にすでに記事があるのだが、画面キャプチャが古かったので最新版(2018年8月時点)を作ろうと思ったのがきっかけ。

本記事では触れないが似たようなラッパーで[node.js版](https://discord.js.org/#/)もあるらしい。

## 環境

* Python 3.6.6
* [discord.py](https://github.com/Rapptz/discord.py)

# 手順
## Python環境の用意

何はともあれPython3系が必要。discor.py自体は3.4と3.5をサポートしていると書いてるのだが、そこに書いてある通り3.4だとQuick Exampleのコードを少し修正しないといけないので、3.5以降を使う。つもりだったのだが先に3.6.6で動作確認したので3.6.6を前提に説明します。

細かいPythonのバージョンを指定した環境構築には[pyenv](https://github.com/pyenv/pyenv)とかを使うと良いと思うが、ここでは説明しない。以下の通り、何らかの手段でpython3.6の実行環境が整ったものとする。

```
$ python -V
Python 3.6.6
```

> ちなみにPython3.7系では動かなかった。

## botの登録

[Discordのdevelopers](https://discordapp.com/developers/applications/)サイトにアクセス。

`Create an application`を押下

![スクリーンショット 2018-08-13 23.53.04.png](https://qiita-image-store.s3.amazonaws.com/0/100776/34128431-0bbb-1638-9efd-745cc30617a7.png)

botの表示名(ここではDiscord Sample Bot)を入力して、画面右下の`Save Changes`を押下

![screencapture-discordapp-developers-applications-478576764545925142-information-2018-08-13-23_59_40_2.png](https://qiita-image-store.s3.amazonaws.com/0/100776/487c94e4-64b3-aea2-b89d-86ef1f3eb016.png)

左側のメニューから`bot`を選択し、右側の`Add Bot`を押下

![screencapture-discordapp-developers-applications-478576764545925142-bots-2018-08-14-00_00_11.png](https://qiita-image-store.s3.amazonaws.com/0/100776/5bc9237c-2e93-0cfe-cd45-8e98f93df740.png)

BOTを追加するか聞かれるので迷わず`Yes, do it!`を押下

![スクリーンショット 2018-08-13 23.58.44.png](https://qiita-image-store.s3.amazonaws.com/0/100776/717ad7be-bbb0-f91c-ef67-2910d52a4b12.png)

`Click to Reveal Token`をクリックして、トークン情報を表示。このトークン情報はbotの実装時に認証情報として利用するので控えておく。もちろん後からも参照できる。

![screencapture-discordapp-developers-applications-478576764545925142-bots-2018-08-14-00_00_31.png](https://qiita-image-store.s3.amazonaws.com/0/100776/1575bb76-b9c0-dd22-3ae7-9905c2a430d6.png)

左側のメニューから`OAuth2`を選択し、`bot`にチェックを入れる。画面下部にbot認証用のURLが表示されるのでURLをコピーしてブラウザでアクセスする。

![screencapture-discordapp-developers-applications-478576764545925142-oauth-2018-08-14-00_33_01.png](https://qiita-image-store.s3.amazonaws.com/0/100776/38c9471b-430a-bf07-6f2f-61828b447225.png)

botを追加するサーバーを聞かれるので対象のサーバを選択する。自分が管理しているサーバでないと追加できないので注意。

![スクリーンショット_2018-08-14_0_01_57.png](https://qiita-image-store.s3.amazonaws.com/0/100776/4a06503b-d416-868c-341c-81a1f410e199.png)

認証完了。

![スクリーンショット 2018-08-14 0.02.15.png](https://qiita-image-store.s3.amazonaws.com/0/100776/9e65bd4d-08e6-2456-f811-1dc258170eb6.png)

自分のサーバにオフライン状態のbotが追加されている。

![スクリーンショット_2018-08-14_0_02_56.png](https://qiita-image-store.s3.amazonaws.com/0/100776/a332669e-7422-632b-b769-08cdc755f437.png)


## botの実装

pipでdiscord.pyをインストール。

```
pip install -U discord.py
```

[Quick Example](https://github.com/Rapptz/discord.py)のソースをそのまま貼り付けた`bot.py`を作成。最終行の`token`はbot登録時に参照したトークン情報（文字列）に置き換えること。

Developerサイトの`General Information`のページに`CLIENT ID`とか`CLIENT SECRET`とかあるけど、それらの情報は全く必要なくて、必要なのは`TOKEN`なので注意。

> 間違って`CLIENT SECRET`を指定して認証通らずにハマった。

```python:bot.py
import discord
import asyncio

client = discord.Client()

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

@client.event
async def on_message(message):
    if message.content.startswith('!test'):
        counter = 0
        tmp = await client.send_message(message.channel, 'Calculating messages...')
        async for log in client.logs_from(message.channel, limit=100):
            if log.author == message.author:
                counter += 1

        await client.edit_message(tmp, 'You have {} messages.'.format(counter))
    elif message.content.startswith('!sleep'):
        await asyncio.sleep(5)
        await client.send_message(message.channel, 'Done sleeping')

client.run('token')
```

## 動作確認

bot.pyを実行。`on_ready()`が実行される。

```
$ python bot.py 
Logged in as
Discord Sample Bot
123456789123456789
------
```

Discord上のbotがオンラインになっている。

![スクリーンショット_2018-08-14_0_44_35.png](https://qiita-image-store.s3.amazonaws.com/0/100776/bd4decc0-bce3-6f30-35b7-6d8d2c0e57b0.png)

`!test`とチャットに打ち込むと、自分の投稿したメッセージ数を返してくれる。

![スクリーンショット_2018-08-14_0_05_05.png](https://qiita-image-store.s3.amazonaws.com/0/100776/df9804fc-69ca-a880-c645-4708d56fa5da.png)

`!sleep`とチャットに打ち込むと、5秒後に`Done sleeping`と返してくれる。

![スクリーンショット_2018-08-14_0_05_11.png](https://qiita-image-store.s3.amazonaws.com/0/100776/9ca1bbfd-3632-fd46-804f-3095289bfb45.png)

あとは`bot.py`をカスタマイズしていけば好きなbotが作れる！！簡単！！

このやり方だとpythonを立ち上げておかないとbotが応答できない。常駐させるにはレンタルサーバとか立ち上げっぱなしのサーバーが必要。