Discord用スプラトゥーン武器ランダム配布Botを作る

#はじめに
この記事は [Discord Advent Calendar 2017](https://qiita.com/advent-calendar/2017/discord) 23日目の記事になります。皆さん当然クリスマスの夜はスプラトゥーンで過ごしますよね．

先日，[DiscordBotをGoogleHomeで音声操作してみる](https://qiita.com/kotatu_km/items/5b4e296a065b533274f9)という記事を書いて，メインは[GoogleHome](https://store.google.com/product/google_home?hl=ja)でDiscordのBotを操作することだったのでBot自体は*サラッ*と流して書いていたのですが，

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">お待たせしました！<br>Discordで武器と言うとランダムで武器が選ばれるBotができました！<br><br>普段使っているツールから気軽に武器ルーレットを使いたい方はぜひどうぞー！<br><br>以下のURLから認証して頂いて、導入したい鯖を選んでください<a href="https://t.co/mvOtm1yvTy">https://t.co/mvOtm1yvTy</a><a href="https://twitter.com/hashtag/Splatoon2?src=hash&amp;ref_src=twsrc%5Etfw">#Splatoon2</a></p>&mdash; おじーじじ@Botアイコンゆる募 (@gura_kyo) <a href="https://twitter.com/gura_kyo/status/942777823038603264?ref_src=twsrc%5Etfw">2017年12月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

このようなツイートを見かけまして，似たようなの作ってる方が居たのかと，そして100RT越えと意外に需要がありそうなので，私が作成したBotの作り方を詳しく書こうかと思います．~~Botが需要あるのであってBotの作り方は需要ないとか言わないで~~
ちなみに上のツイートの方とは**全く別人**ですので同一の機能を作る訳ではありません…そして私の作成するBotは最低限の機能しかないのでBot使いたい人は上の方のリンクへ飛んで下さい．便利です．オススメです．

#作るもの
ボイスチャンネルに居る人へ，ランダムに武器を指定してくれるBotです．
[DiscordBotをGoogleHomeで音声操作してみる](https://qiita.com/kotatu_km/items/5b4e296a065b533274f9)
とはGoogleHomeを介さないので少しソースコードを変えてあります．

**動作例**
`test_ch`に3人メンバーがいます．
![FullSizeRender 3.jpg](https://qiita-image-store.s3.amazonaws.com/0/54085/bc46aad8-b785-a823-86fa-e6ab23922deb.jpeg)

`!random_buki`と入力．
<img width="467" alt="スクリーンショット 2017-12-25 14.07.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/dfa73bb8-ccff-9cd0-3e2b-83a1165b1af0.png">

![FullSizeRender 4.jpg](https://qiita-image-store.s3.amazonaws.com/0/54085/aad64ce4-7f40-63cb-c3b9-66148110e063.jpeg)

Botがメンバーへ武器を指定してくれます．
<img width="364" alt="スクリーンショット 2017-12-05 21.38.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/e8092504-9cc0-7ede-9fff-1587746ad6b5.png">


ソースコードはこちら

```rb:discord_bot.rb
require 'discordrb'
require "csv"

#client_idはbotに設定されているものを入力 prefixはコマンドの呼び出しの時の記号(!play 等の!部分 ?とかでも可)
bot = Discordrb::Commands::CommandBot.new token: '自分のトークン', client_id: 000000000000, prefix: '!'
#スプラトゥーンの武器名が入っているcsvファイルを読み込み
data = CSV.read('buki.csv')

#"!random_buki"とチャットに入力があった場合反応
bot.command :random_buki do |event|
  channel = event.user.voice_channel
  users = channel.users
  for num in 0..users.length do
    event.respond "#{users[num].name} の使うブキ -> #{data[rand(0..data.length)][0]}"
  end
end

bot.run
```
BotのRubyファイルと同階層に武器名の入ったcsvファイルが必要です．

<img width="160" alt="スクリーンショット 2017-12-05 19.59.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/56f9fa5f-c57e-7b58-f5da-81b0916f70ce.png">

仕組みとしては，Discordでコマンドを呼び出したユーザーの入っているボイスチャンネルを取得し，それぞれに向けてcsvファイルの中身をランダムに返しているだけです．
以下で作り方を詳しく解説して行きます．

#discordrb
Botを作成するにはDiscordBot用のRubyライブラリ[discordrb](https://github.com/meew0/discordrb)を使います．
導入はこちら参照
[イチからDiscord Bot 。for Ruby](https://qiita.com/deneola213/items/efaeb0f5c20d44608a71)

導入記事の方にも書いてありますが，ハローワールドなBotから

```rb:hello_bot.rb
require 'discordrb'

bot = Discordrb::Commands::CommandBot.new (
token: TOKEN,
client_id: CLIENT_ID,
prefix:'!',
)

bot.command :hello do |event|
 event.send_message("hallo,#{event.user.name}")
end

bot.run
```

まず最初の`bot=...`でBotの初期設定を行います．`token`と`client_id`はDiscordのアプリ内でBotを登録時に出てくるBotのトークンとIDです．
そして`prefix`はBotの呼び出し時につける記号です．今回は`!`となっているので`hello`コマンドの呼び出しは`!hello`となります．prefixを`?`にした場合は`?hello`になる訳ですね．

次に`command`部分へ行きましょう

```ruby
bot.command :[コマンド名] do |event|
```

という書き方でBotのコマンドを設定します．

```ruby
event.send_message("hallo,#{event.user.name}")
```
send_messageはチャンネルにテキストメッセージを送ります．
今回は`event.user.name`で発言者の名前を取得しています．
ここは，

```ruby
event.respond("hallo,#{event.user.name}")
```
と，`respond`を使う事でも書き換え可能です．

eventには発言者の様々な情報が入っているので，発言者のサーバー，チャンネル等が取得可能です．例えば以下のコード．

```ruby:event_bot.rb
bot.command :hello do |event|
    event.respond "hello, #{event.user.name}!"
    event.respond "server: #{event.server.name}"
    event.respond "channel: #{event.channel.name}"
end
```
発言者のサーバーとチャンネル(テキストチャンネル)を取得し，respondでメッセージを送ります．
<img width="333" alt="スクリーンショット 2017-12-25 13.06.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/55c9eb39-5e88-acdd-aad4-dc132e6fdcdb.png">
サーバー名とチャンネル名を返せています．
<img width="241" alt="スクリーンショット 2017-12-25 13.06.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/21bcb7df-870a-3654-3431-6412a7e22389.png">

次はボイスチャンネルとチャンネル内にいるユーザーの取得をしてみましょう．

```ruby:event_bot.rb
bot.command :hello do |event|
    event.respond "hello, #{event.user.name}!"
    event.respond "server: #{event.server.name}"
    event.respond "channel: #{event.channel.name}"
    #以下追加
    voice_channel = event.user.voice_channel
    event.respond "voice_channel: #{voice_channel.name}"
    users = voice_channel.users
    for num in 0..users.length do
      event.respond "user: #{users[num].name}"
    end
end
```
`!hello`コマンドを打つと・・・

<img width="229" alt="スクリーンショット 2017-12-25 13.42.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/4483c71f-8d86-966f-9f9a-d873dbeefc1b.png">
<img width="290" alt="スクリーンショット 2017-12-25 13.42.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/54085/1e5c8090-01ae-9e6a-2be0-581e2ddd268a.png">

ボイスチャンネルのユーザーが取得できました．
これでもうdiscordrb独自の作業は終了です．csvファイルを読み込む機能を作り，ランダムでuser名の後ろに武器の名前をつけましょう．

```rb:discord_bot.rb
require 'discordrb'
require "csv"

#client_idはbotに設定されているものを入力 prefixはコマンドの呼び出しの時の記号(!play 等の!部分 ?とかでも可)
bot = Discordrb::Commands::CommandBot.new token: '自分のトークン', client_id: 000000000000, prefix: '!'
#スプラトゥーンの武器名が入っているcsvファイルを読み込み
data = CSV.read('buki.csv')

#"!random_buki"とチャットに入力があった場合反応
bot.command :random_buki do |event|
  channel = event.user.voice_channel
  users = channel.users
  for num in 0..users.length do
    event.respond "#{users[num].name} の使うブキ -> #{data[rand(0..data.length)][0]}"
  end
end

bot.run
```

これで完成です！お疲れ様でした！
今回はチャンネル全員へ武器を指定していますが，単純に発言者へ武器を指定するだけなら

```rb
bot.command :random_buki do |event|
    event.respond "#{event.user.name}:#{data[rand(0..data.length)][0]}"
end
```
でOKですね．
後はRubyファイルを走らせ，Botを招待したサーバーでコマンド`!random_buki`を入力すれば使用できます．

チャンネル・ボイスチャンネルのユーザー取得さえ出来れば，あるユーザーへ向けて〇〇したいという機能はほぼ完成ですので，この記事を参考にして貰って色々なゲームで，色々なBotをどんどん作っていただければ幸いです！

#参考
[discordrbドキュメント](http://www.rubydoc.info/github/meew0/discordrb)(http://www.rubydoc.info/github/meew0/discordrb)
[イチからDiscord Bot 。for Ruby](https://qiita.com/deneola213/items/efaeb0f5c20d44608a71)