DiscordでBotを作りたい
表題の通りで、最近仲の良い友人たちの間でDiscordを使っていて、こいつにBotを導入したかった。
応用は後で頑張るとして、まずは簡単なポスト(Ping - Pong)くらいできるようにしたい。
※余談だけど、Discord本当に良いのでSlackくらい流行ってほしい。
環境
常に動作させたかったので、自宅でおもちゃにしてるRaspberry Pi3で動作させることにした。
Linux raspberrypi 4.4.38-v7+ #938 SMP Thu Dec 15 15:22:21 GMT 2016 armv7l GNU/Linux
何を使う?
BotといえばSlackなんですけど(?)、よくHubotが使われてました。
自分も一度使ったことあるけど、色々面倒(Herokuとか使う)だったので、もう少し小規模にできるものから始めようかなと。
いろいろ調べた感じ、以下の二つが簡単にDiscordのBotを作れそう。
名前からおわかりの通り、discord.pyはPython、discordrbはRubyによるDiscordのAPIラッパーらしい。
二つのサンプルコードを貼ってみます。
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')
require 'discordrb'
bot = Discordrb::Bot.new token: '<token here>', client_id: 168123456789123456
bot.message(with_text: 'Ping!') do |event|
event.respond 'Pong!'
end
bot.run
discordrbを使う
結論から言いますと、何故かdiscord.pyで上手く動作しなかったので、discordrbを使うことにした。なんでできなかったんだろう・・・
というわけで、以降はdiscordrbの簡単な導入方法になります。
Bot実装
discordrb導入
Linuxの場合導入自体はメチャクチャ簡単。
gem install discordrb
・・・といいつつ、エラーでdiscordrbがインストールできない!(エラー内容はメモるの忘れた)
検索したらrubyバージョン2.1.5なら大丈夫?とのことなので、先にrvmを導入してからインストールすることに。
rvmインストール
curl -L get.rvm.io | bash -s stable
上記のコマンドがコケたら、以下を実行してからもう一度試す。
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
rvmのインストールが完了したら、ターミナルを閉じるか以下のコマンドを実行。
source ~/.rvm/scripts/rvm
お目当てのrubyバージョンをインストール。
rvm install 2.1.5
どうやらここでrubyのコンパイルが入るらしく、えらい時間かかった。30分くらい。
環境によっては以下のインストールが必要みたいです。nazuna01107さんありがとうございます!
apt-get install ruby-dev
ここまできてやっと当初の目的であるdiscordrbをインストールできる。
再度、discordrbインストール
gem install discordrb
gemのインストールが完了したら、使用するソースで以下をrequireするだけ。
require 'discordrb'
Windowsの人は公式のドキュメント見て!
DiscordにBotを登録
開発者ページでBotの登録をします。
New Appをクリック
上の画像で黒塗りになってるClient ID と Token をメモっておく。
Discord側の設定はこれだけでOK。REDIRECT URI(S)は設定しなくても大丈夫。
コーディング & 実装
コーディングといいつつ、今回はポストするまでが目標なので、discordrbのサンプルをそのまま使う。
最初はechoだけでもいいと思ったけど、それだとあまりにも味気ないから、投稿されたRubyのコードをそのまま eval するサンプルを使った。
require 'discordrb'
bot = Discordrb::Commands::CommandBot.new token: 'あなたのトークンを入れてね', client_id: 000000000000000000, prefix: '!'
bot.command(:eval, help_available: false) do |event, *code|
begin
eval code.join(' ')
rescue
'An error occurred '
end
end
これを適当なファイル名で保存して、
ruby bot.rb
すれば実行開始。
上手く行けば以下みたいな表記が出るはず。
Using WSCS version: 0.3.0
libsodium not available! You can continue to use discordrb as normal but voice support won't work.
Read https://github.com/meew0/discordrb/wiki/Installing-libsodium for more details.
[INFO : websocket @ 2017-02-28 02:26:10.165] Discord using gateway protocol version: 6, requested: 6
※なんか利用不可って言われてるけど気にしない。
常に動作させたい場合はコマンドの末尾に &
をつけてやってバックグラウンド実行するといいかも。
ruby bot.rb &
おしゃべりする
ちなみに、ここですげー躓いたんだけど、Discordの場合、Botにコマンドを実行させるときは prefixが必要らしく、Botに対していくら
eval 1+2
ってやっても効かなくて、ちゃんと ! をつけてやらないとダメみたい(prefixは変更できる)。
!eval 1+2
それと、上記の画像はDMだけど、任意のチャンネルでBotにコマンドを打つときも @Chika !eval 1+1
ってやる必要はないみたい。
これだと、同じコマンドを持ったBotが複数いる場合どうなるんだろう・・・このへんの仕様はまだ調べてない。
次の目標
とりあえずポストできることがわかったので、次回はもう少し実用的なBotにしたい。