動かすまでの作業記録。
Raspberry Pi側の準備
バージョンとか
久しぶりの起動だったので、最新版のRaspbianを入れ直した。
pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.4 (stretch)
Release: 9.4
Codename: stretch
Pythonとか
discord.pyが必要なので入れておく(cf. Rapptz/discord.py: An API wrapper for Discord written in Python.)。
pip3 install discord.py
あとnumpyを使った関係で以下もインストールした。これはBotを作るだけなら必須ではない。
sudo apt-get install libffi-dev
SSH
設定 > Raspberry Piの設定 > インターフェイス と辿って、SSH:を有効にしておく。再起動が必要だったかもしれない。
Discord側の準備
Botを登録
Discord - My Appsからボットを作成。
- New Appでアプリ追加。
- 作成したアプリの設定に入って下部のBotからCreate a Bot User。
- 上の方に戻ってGenerate OAuth2 URLへ。
- SCOPESがbotだけの状態で表示されているURLへアクセス。
- Botを登録したいサーバーを追加。
エディタの準備
Atomを使う(使わずに直接Raspberry Pi上で作成しても良い)。以下のパッケージをインストールしておく。
- ftp-remote-edit
- platformio-ide-terminal
FTP設定
※あらかじめRaspberry Piを起動してネットワークに接続しておく。
- Package > Ftp-Remote > Edit Servers
- サーバー名、Raspberry PiのIPアドレス、ユーザー名、パスワードを設定し、Use sftp (ssh) connectionにチェック。
- ユーザー名とパスワードは初期状態ではpiとraspberry
- Initial Directoryはどこでもいいが、例えば
/home/pi
にしておく。
- Package > Ftp-Remote > Toggle を選択して、Raspberry Piのディレクトリが表示されたらOK。
SSH接続
- Alt + Shift + TでAtom内でターミナルが起動する。
- sshでRaspberry Piへ接続できたらOK。
トークンの環境変数への登録
コード内にトークンを書きたくないので、Raspberry Piの環境変数に登録しておく。
まず、トークンを確認する。トークンはDiscord - My Apps下部のBot内、Token:の横のclick to revealをクリックすると分かる。
.bash_profile
あたりに
export DISCORD_TOKEN=確認したトークン
と言った感じで記述しておく。記述したらsource .bash_profile
とするかターミナルを再起動しておく。
Botの作成
Raspberry Pi上に、例えばmain.pyなどの名前でファイルを作成してPythonのコードを記述し、Botの振る舞いを定義していく。
discord.Client()
を使う方法とdiscord.ext.commands.Bot()
を使う方法がある。後者だとコマンドが使えるっぽいので、今回は後者を使ってみる。
コマンドの作成
コマンドは[プレフィックス]関数名 引数
と言った具合のメッセージに対して実行される。例を見たほうが早いだろう。
プレフィックスはBotのインスタンス作成時に引数として指定する。別に何でもいいし、複数指定することもできる。
import discord.ext import commands
import numpy as np
BOT_PREFIX = ('?', '!')
client = commands.Bot(command_prefix=BOT_PREFIX)
(※numpyは以下のコマンド中で使用するためにインポートしているだけなので、特に必要という訳ではない)
コマンドに使う関数は、@client.command()
デコレータにつづいて次のように定義する。
@client.command(description="与えられた任意の数の実数の和を返します。",
brief="数値の合計")
async def add(*num: float):
await client.say(np.sum(num))
descriptionとbriefはhelp表示時に使用されるテキストで、指定せずに@client.command()
だけでもいい。helpは自動的に作成されて、[プレフィックス]help
でコマンドの一覧が、[プレフィックス]help コマンド名
でコマンドのヘルプが表示される。
対話の設定
@client.event
デコレータに続いてコードを記述するとコマンド以外の発言に対して返事をさせられる。この機能をコマンドと同時に使用するためには、関数定義中のどこかでawait client.process_commands(message)
の記述が必要なので注意する。また、Bot自身の発言に反応しないような細工もしておく必要がある。
例えば以下のようなコードを書いておくと、「こんにちは」という発言に対して自己紹介をするようになる。
@client.event
async def on_message(message):
await client.process_commands(message)
# BOTとメッセージの送信者が同じ場合は何もしない
if client.user == message.author:
return
if message.content.startswith("こんにちは"):
m = "こんにちは! " + message.author.name + "さん!\n"
m = m + "`!add 1 1`のように入力すると、関数が実行できます!\n"
m = m + "`?help`で実装されている関数の一覧を表示します!"
await client.send_message(message.channel, m)
Botの起動
ファイルの最後に以下の記述をしておく。import os
も必要なので注意。
client.run(os.environ.get("DISCORD_TOKEN"))
また、以下の記述をしておくとBot起動時にターミナルにメッセージが表示される。これは必須ではない。
@client.event
async def on_ready():
print('以下のユーザー名でログインしています')
print('ユーザー名: ' + client.user.name)
print('ユーザーid: ' + client.user.id)
print('------------------------------------')
ファイルを保存し、python3 main.py
などとしてRaspberry Pi上でファイルを実行する。上手くログインできれば、上で設定したメッセージがターミナルに表示され、Discord上でBotがログイン状態となる。
作成したBot
今回作成したBotのコードは https://gist.github.com/nozma/9684af7dcb0e5e5218af81da6da59544 で公開している。