feature image

2017年10月31日 | ブログ記事

DiscordのBotを作ってみよう!

こんにちは。traP Advent Calender 2017、10月31日担当の幼卒です。

ところで皆さんDiscordは使いますか?僕は友達があまりいないので、保育園卒園以前から関わりのある友達との会話に使うくらいですね。

今日はDiscordのbotを作ってみたいと思います。環境はDebian9.0、Ruby2.3.3です。まあDebian系なら大丈夫だと思います。windowsで環境を構築しようと思ったら半日潰れたのでwindowsはクソ!w(僕が弱いだけ)

1.discordrbを手に入れよう!

まずDiscordのAPIを利用するため、discordrbをインストールします。運が良ければ

$ sudo gem install discordrb

でインストールが成功します。僕も含め運が悪い人は、

ERROR:  Error installing discordrb:
ERROR: Failed to build gem native extension.

というエラーが吐かれます。とりあえずこの辺のコマンドを打ったあとに、

$ sudo apt-get install ruby-dev
$ sudo apt-get install g++

もう一度上のコマンドを打つと

16 gems installed

うまく行きました。

2.Discord側の準備をしよう!

Discordのアカウントを持っていない人はいないと思うんですけど、いたら作って下さい。

ここにアクセスするとこんなページが表示されます。(既に1つ作ってあるのは無視して下さい。)

Screenshot-from-2017-10-27-22-02-18

New Appをクリックして適当に必要事項を入力し、Create Appをクリックするとbotの詳細ページに飛びます。

Screenshot-from-2017-10-27-22-13-37

Screenshot-from-2017-10-27-22-14-10

APP DETAILSに書いてあるClient ID、及びCreate a Bot Userをクリックすると出てくるTokenが重要になるのでメモっておきましょう。

そして、
https//discordapp.com/oauth2/authorize?client_id=ここにClient IDを入れる&scope=bot&permissions=0
にアクセスするとこんな感じになるので、

Screenshot-from-2017-10-27-22-19-46

サーバーを選択して認証します(botを追加する許可はもらって下さい)。するとサーバーにbotが追加されているはずです。

3.botを作ろう!

やっと準備が整いました。

とりあえずVimでもEmacsでもAtomでもVSCodeでもなんでもいいのでエディタを開いて次のように書いて下さい。

require 'discordrb'
bot = Discordrb::Bot.new token: 'さっきメモったTokenをここに書く', client_id: メモったClient IDをここに書く

bot.message do |event|
  event.respond 'Hello, Discord!'
end
 
bot.run

そしてbot.rbのあるディレクトリに移動し、

$ ruby bot.rb

とします。そしてbotの追加したサーバーで何か発言をすると、

Screenshot-from-2017-10-27-22-35-49

Hello,Discord!と返ってきます。

あとはbot.rbに書き足していけば魔改造ができますね!(ただし技術が必要)

とりあえず全部のチャットに対してHello, Discord!と返されても困るので、textbotを含むチャットにのみ反応し、挨拶を返してくれるようにしましょう。bot messageからendまで消して、新たに

bot.message(containing: "testbot") do |event|
  event.respond "こんにちは,#{event.user.name}さん"
end

とします。すると、

Screenshot-from-2017-10-27-22-45-55

となります。

4.サイコロ機能をつけよう!

しかしこれだけでは面白くないですよね。Micr○s○ftの女子高生の足元にも及ばないでしょう。

サイコロぐらい投げれるようにしましょう。そのためにまず、

bot = Discordrb::Bot.new token: 'トークン', client_id: クライアントID

の部分を

bot = Discordrb::Commands::CommandBot.new token: 'トークン', client_id: クライアントID , prefix: '/'

と書き換えます。以後Discordでbotの機能を使うときには/hogehogeの形でメッセージを送ることになりますが、prefix:'/'の部分を変えれば!hogehogeや:hogehogeにできます。

次に新たに

bot.command :dice do |event|
  rand(1..6)
end

を追加します。Discordのbotを追加したサーバーで/diceとすれば、

Screenshot-from-2017-10-27-22-54-27

1から6の数字をランダムに返してくれるようになりました。

ついでに任意個数の任意面サイコロを振ってくれるようにしましょう。

bot.command :dice do |event,kazu,max|
  kazu = kazu.to_i
  max = max.to_i
  if kazu < 1
    kazu = 1
  end
  if max < 1
    max = 6
  end
  me = [];
  for i in 0..kazu-1
    me.push(rand(1..max))
  end
  me.unshift(me.inject(:+),"(")
  me.push(")")
  me.join(" ")
end

として、/diceのあとに振る個数,最大の目(2d6のような感じですね)のようにすれば

Screenshot-from-2017-10-27-23-21-52

114個の514面サイコロが振られ、その合計も表示してくれました。

5.音楽botを作ろう!

4.の方法を応用すれば、Rubyの知識があれば結構色々な機能がつけられるのではないでしょうか?素数判定とか、頑張れば某マイク□ソフトの女子高生のゲーム機能ぐらいならつけられるかもしれません。

最後にその女子高生に勝つための第一歩として音楽を流せるようにしましょう。

BotをVoice Channelに入れる

音楽botを作るためにはlibsodium、libopus0、FFmpegが必要です。それぞれ

$ sudo apt-get install libsodium-dev
$ sudo apt-get install libopus0-dev
$ sudo apt-get install ffmpeg

としとけば大丈夫でしょう。

botに音楽を流させるには、まずVoice Channelに入れなければ話になりません。今回は/connectとすると自分のいるVoice Channelに入るようにしましょう。以下を追加します。

bot.command :connect do |event|
  channel = event.user.voice_channel
  next "Voice Channelに入ってからコマンドを打ってね" unless channel
  bot.voice_connect(channel)
  "{channel.name}に入りました。"
end

もし自分がText Channelにいた場合にはメッセージを返すようにしておきましょう。Generalに入って/connectとすれば

Screenshot-from-2017-10-30-18-46-28

ちゃんとできました。

音楽を流す

まず適当に入手したmp3ファイルをどこかに置きます。今回はは/home/yosotsu/work/hogehoge.mp3としました。

以下を追加して、

bot.command :hoge do |event|
  event.voice.play_file("/home/yosotsu/work/hoge.mp3")
end

bot.command :stop do |event|
  event.voice.stop_playing
end

bot.command :pause do |event|
  event.voice.pause
end

bot.command :continue do |event|
  event.voice.continue
end

/hogeとすれば曲が流れます。最初はETERNAL BLAZEでも再生しようと思ったのですが、著作権的によくわからなかったのでやめました。/stop /pause /continueとすれば、それぞれ音楽が停止、一時停止、再開されます。

bot.rbのあるディレクトリにmusicフォルダを作り、/play 曲名でその曲を流せるようにするとこんな感じになります。/playlistで全曲表示できるようにしました。

bot.command :playlist do |event|
  musicList = []
  Dir.chdir("music/") do 
    Dir.glob("*") do |m|
      musicList.push(m)
    end
  end
  musicList.join("/n")
end

bot.command :play do |event,m|
  if File.exist?("music/#{m}.mp3")
    event.voice.play_file("music/#{m}.mp3")
  else
    "ファイルがありません"
  end
end

感想

正直最初のdiscordrbを入れるまでが一番大変でした。

GitHubを参考にしてやりました。英語を読むのが大変でしたが、exampleとかを見つつ意外と喰らいつけたので自信がつきました。Youtubeとか流せたら最高だと思います。

実はAdCを書き始めたのが3日前だったのでクソ記事が出来上がりました。次回はこのようなことがないように2ヶ月ぐらい前から準備したいですね。

明日はtyoxuさん、Kazuさんです。では!

Yosotsu icon
この記事を書いた人
Yosotsu

駆け出しぷろぐらま

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2017年11月14日
IBIS2017参加報告
Keijan icon Keijan
2017年11月17日
そばやのワク☆ワク流体シミュレーション~MPS編~
sobaya007 icon sobaya007
2017年12月26日
RustでMCMC(Metropolis-Hasting)
David icon David
2017年12月13日
チズケ破壊論
whiteonion icon whiteonion
2017年12月1日
WaltZ
Double_oxygeN icon Double_oxygeN
2017年11月4日
文章をよしなに分散表現しよう
David icon David
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記