13
17

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 5 years have passed since last update.

DiscordのbotをPythonで作成してRaspberry Pi上で動かす

Last updated at Posted at 2018-04-25

動かすまでの作業記録。

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あたりに

.bash_profile
export DISCORD_TOKEN=確認したトークン

と言った感じで記述しておく。記述したらsource .bash_profileとするかターミナルを再起動しておく。

Botの作成

Raspberry Pi上に、例えばmain.pyなどの名前でファイルを作成してPythonのコードを記述し、Botの振る舞いを定義していく。

discord.Client()を使う方法とdiscord.ext.commands.Bot()を使う方法がある。後者だとコマンドが使えるっぽいので、今回は後者を使ってみる。

コマンドの作成

コマンドは[プレフィックス]関数名 引数と言った具合のメッセージに対して実行される。例を見たほうが早いだろう。

image.png

プレフィックスは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 コマンド名でコマンドのヘルプが表示される。

image.png

対話の設定

@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)

image.png

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 で公開している。

参考

13
17
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
13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?