郵便受け

気分で何か書くかもしれない札のごみ箱

文鎮となったAlexaでDiscordbotを音声操作する

この記事はTCU-CTRL場外乱闘 Advent Calendar 2019 - Adventar7日目の記事です

 

前回の記事はこちら。
mak1a.hatenadiary.com


 

話の流れで適当に追い土嚢ゲーム提案して軽く仕様を伝えたのに、公開されたの見たら全く違ってキレ散らかした覚えがありますね。さっさと作り直して。

 

初めに

皆さんスマートスピーカーをお持ちですか?昨今では随分と手頃な値段で買えるようになってきて、セールで500円で買えたりするような代物になってきました。

 

ただそんなの持ってて使ってるのとよく言われるのですが答えはNOです。TDNスピーカーです。スマート要素は何処に行ったんでしょうね。

それにうちの子は最近は音すら出してないです。

もう音の出る文鎮ではなく文鎮と言い直した方が良いですね。

 

ただ文鎮として埃を被せたままにしとくのはあまりにも勿体無いし何か有効活用できたらなぁ…。声で操作出来るし何かその利点を使えたらなぁ…。

 

 

 

 

 

 

 




 
あ゙っ゙!゙!゙!゙

 f:id:NifuDa:20191207172746j:plain

 

コントローラー操作してたらキーボード打てないやんけ‼︎‼︎‼︎声で操作したろ‼︎‼︎‼︎


ということでこの記事ではスマートスピーカー、Alexaを利用してDiscordを音声入力をやってみようという記事になります。Alexaのスキル開発とは違うんでそこら辺はご了承下せぇ...

 

 

使用ツール・環境

今回の使用ツールと環境は以下のものになります

Discordbotの作成

何も準備なしにAlexaに語りかけても「すみません、よくわかりません」と言われるのがオチです。まずはDiscordでBotを作成し、手動でコマンドを打ったときに反応してくれるようにしていきます。

 

今回作るBotは今日で発売からちょうど1周年の大乱闘スマッシュブラザーズ SPECIALのアシスタントとして使えそうなものを作っていきます 。今のトレンド的にポケモンの方がよかったのでは…?
 

どういうものを作っていくかというと、

ボイスチャンネル内にいるユーザーの中から二人選んで、別ファイルに纏めたステージファイルから5つステージを選択(重複あり)してくれるBotです。

スマブラの専用部屋って勝ち抜けか負け抜けだけで部屋に複数人いるときに人指定してn先とか出来たらなぁって感じで作ることになりました。

ステージを指定してるのは元よりランダム設定しないで終点化で固定する輩がいたりするためです。釘刺しとけばちゃんと変えてくれるでしょう。



それでは作業に取り掛かっていきましょう。

 

まずbot用のアカウントを作成していきます。
discord developer portalでアカウントを登録し、使いたいサーバーに招待します。
詳細の手順はこちらの記事で説明されています。
Discord Botアカウント初期設定ガイド for Developer - Qiita


ソースコードについてダラダラと話してる訳にも行かないので、コードだけ載せておきます

require 'discordrb'
require 'csv'

#idの記述
Token = "自分のToken"
Client_ID = 自分のCLIENT ID

#変数に代入、!でコマンド呼び出し
bot = Discordrb::Commands::CommandBot.new token: Token,client_id: Client_ID,prefix:'!'

stage = CSV.read('stage.csv')

bot.command :smash do |event|
    server = bot.servers.first[1]
    for num in 0..server.channels.length do
        if server.channels[num].name == "ゲーム" then
            users = server.channels[num].users
            #プレイヤーピック
            2.times do |num|
                event.respond "#{users[rand(users.length)].name}"
            end
            #ステージピック
            5.times do |num|
                event.respond "#{stage[rand(0..stage.length)][0]}"
            end
        end
    end
end

bot.run

 

欠陥があるけどとりあえず動いてるから良し!ってことで次に行きましょう。色々探して書いてをやってたけどダメだったんで気が向けば直すんじゃないですかね(多分しない)



ステージが記載されてるcsvはこんな感じになってます。

終点
戦場
ポケモンスタジアム2
カロスポケモンリーグ
村と街
すま村
ヨッシーストーリー
ヨッシーアイランド
ライオットクルーズ
プププランド
夢の泉
ワイリー基地
メメントス
ミッドガル
KOFスタジアム

公式大会のステージとかよくわかんないけどよく見るやつはこんなところでしょうか。

 

あとはこれをコンパイルして実行するとチャンネルにBotが出現します。

 f:id:NifuDa:20191207181422p:plain

それではコマンドを入力してみましょう

f:id:NifuDa:20191207201216p:plain
こいつ友達いねぇからって一人遊びしてるよ



ボイスチャンネルから2人選びステージもcsvファイルから5つ選ばれたことが確認できましたね。

これでBot”は”完成です。コマンドを音声入力で出来るようにしていきましょう!



Herokuを使ってみる

さぁ音声入力を出来るようにしよう!と言いたいところですが、Botを動かすにしても常時pcをつけっぱで動かしっぱなしもあまり現実的ではありません。

ただサーバーに置くとしてもそもそも持ってなかったりBot1つのために借りるのもなんだかなぁ...と思うかと思います。そこで今回扱うサービスは「Heroku」になります。
jp.heroku.com


簡単に説明しますと、サーバーとかで管理するのを何もかもすっ飛ばして(Herokuに任して)リポジトリを投げつけるだけで実行できるようになります。
そしてありがたいことに基本料金は無料。実行時間が月1000時間超えるには課金が必要となってきますが、1月は744時間です。つまり実質無料となります。
メールアドレス1つで登録することができるので、アドレスの数だけサービスを無料で公開出来るぞ!!常識のある範囲で使おう!!



それでは早速Herokuの準備と参りましょう。


特にこれと言って難しいことはありません。アカウントを作って、アプリの作成して、リポジトリをデプロイして、実行する。これで終わりです。


アカウント

アカウントを作成してください。ここでつまづくようでしたらそもそもdiscordのアカウントすら作れてるか怪しいので諦めてください。


アプリ

登録が完了したらアプリを作成していきます。
完了したら画面内に「Create New App」が出てくると思うのでをクリックしましょう。
すると下図のような画面になると思います。


f:id:NifuDa:20191207190046j:plain
名前を決めてサーバーが置いてある所を選ぶのですが、「アメリカ」と「ヨーロッパ」しか選べません。おま国と言われてますがサービスが使えてるだけでもよしとしましょう。


リポジトリ

デプロイする方法は多数ありますが、今回はgithubを使っていきます。


最近(?)ではプライベートリポジトリが作れるようになったりと便利になったものですが、いざ公開しようとなるとコードがそのままではBotの接続コードが他人が見れる状態になってしまいます。これはあまりよろしくありませんね。ここでHerokuの機能を使いコードを環境変数としてしまいましょう。

アプリケーションの「Setting」から「Reveal Config Vars」を選択、(コード)を環境変数として登録します。

登録した環境変数を呼び出すには以下のように書き換えます。よかった、これで解決ですね。

ただこれだけではアプリケーションを実行できません。

Herokuを利用する際に必要なファイルを作成していきます。


Gemfile、Gemfile.lockを作る

Herokuでライブラリを使用するためには使ったものをGemfileに記述する必要があります。

Gemfile(拡張子“なし”)を用意し以下のように記述します。

source "https://rubygems.org"

gem 'discordrb'
gem 'csv'

用意できたらターミナルで

bundle install

を実行するとGemfile.lockが自動生成されます。


Profileの作成

Herokuで実行するコマンドを記述するファイルです。Herokuでターミナル上でファイルを実行する際に入力するコマンドを記述していきます。

bot: ruby main.rb

これで必要なファイルは用意できました。改めてGithubにプッシュしてデプロイしましょう。


実行

ここまで来たら後は実行するだけなのですが、特にコマンドを打つことなく各スイッチを押すだけです。

これでHerokuを閉じても動かし続けることが出来ました。

Bot作成が目的ならここで終わりですね。ただ今回の目的はスマートスピーカーで操作をすることなのでもうちっとだけ続くんじゃよ。


IFTTTでお話し出来るようにする

さてようやく音声入力を出来るようにしていきます。Alexaにはスキルという固有の開発環境がありますが、登録が面倒(?)だったり、Lambdaの知識が必要だったり(単に作ってるときに私がスキルの存在を忘れてたり)で敷居が高く感じられる所があります。

そこで今回はWebサービス同士を連携させることができる「IFTTT」を使用していきます。

複雑なことはできませんが、今回は「コマンドを入力する」という単純な連携を目的にしているためちょうどいいですね。ありがたく使わせていただきましょう。


作りましょう。以上。


Webhookの取得

音声入力によって入力するコマンドを投稿したいテキストチャンネルを右クリックし、チャンネルの編集。Webhooksからwebhookを作成します。同じ手順を踏めばいつでも見れますが、すぐ使うことになるので忘れないうちにURLをコピペでもしておきましょう。


f:id:NifuDa:20191207200021j:plain
Webhookの設定画面

IFTTTで設定する

IFTTTでは既存のシステムを使用することが出来るのですが、まぁ大抵自分の思い通りの物は無い物です。なので1から作成していきます。

ホーム画面に行くとアイコンの隣にあるExploreをクリックすると選択画面に移りますが、これが既存のシステムなので+の部分をクリックしましょう。


すると下図の画面が出てきます。


f:id:NifuDa:20191207191034j:plain

ここに書かれてる「If This Then That」を省略すると「IFTTT」になるそうです。よく考えますよね。

日本では義務教育で英語を習うのでこれを読んでる人は何となくのニュアンスは分かると思いますが、「これが起こったらあれをする」といった感じです。

今回の場合は「Alexaでトリガーを起動したら、WebhookにjsonをPOSTする」ことになります。




まずはthisの部分を設定していきます。

クリックすると指示を出すプラットフォームの選択画面に移ります。

検索画面からAlexaを選択すると認証画面に移るので設定しましょう。大体の方がAmazonのアカウントと紐づけてると思うのですぐに終わると思います。

次にプラットフォームに何をさせるかのトリガーを選択していきます。今回はalexaに話しかけて反応させたいので「Say a specific phrase」を選びます。

次の画面でAlexaを反応させるためのフレーズを設定します。今回は「discord スマッシュ」にしました。



f:id:NifuDa:20191207194809p:plain

thisの部分はこれで終わりです。



次にthatの部分を設定していきます。

thisの時と同じ容量でwebhookを検索し設定していきます。

先程保存しといたであろうURLを貼り付けたり、Method、Content Type、Bodyを設定していきます。

Bodyのcontent部分がチャットに入力される部分になるので、ここにbotの呼び出しコマンドを入れていきます。


f:id:NifuDa:20191207192353j:plain


以上でセッティングが完了です!早速動かしていきましょう!

動くのを見てみる

撮影したり設定とかがめんどかったから動画は無いぞ!!!


この先は君の目で確かめてくれ!


というのも流石にあれなんで一応動いた証だけでも載せておきます。


f:id:NifuDa:20191207201716p:plain
ボットって付いてるから成功って言わせてくれ

終わりに

ここまで読んでいただきありがとうございます。

大分端折ったつもりなんですが結構長くなってしまい見直すのが苦痛になってたんでもし次書くときは短くしたいですね。

拙い記事ですが興味を持って自分でも作ってみようと思って頂けたら幸いです。やってることは簡単だし言語が変わっても大してやること変わらないんで楽に出来ると思います。



ちなみにですがこのbot、作っておいて全く使っていません。いつかちゃんと使う日は来るんでしょうかね?



次回は乱入が起きなければしゃりんさんになります。よろしくお願いします。