※この記事は個人が楽しむ範疇で書いているので、やるときには各ソフトのライセンスなどをご確認の上、自己責任でお願いします。
先日ボイロ/ボカロ(ゆかりさん)有志の新年会がありまして、ゆかりさんのAI化などの話がでまして、終わったあとの夜中にAlexaスキルとSlackBotを作る(しかも初めて作る)ということをやった結果、中途段階の成果物として時報をゆかりさんに喋ってもらうというシステムが出来上がりました。
内容について
- SlackBotを作ってチャンネルに招待する
- ローカルでNodeサーバーを立ててVOICEROIDの発声をコントロールする
- 発声をテストしてみる
- Incoming Webhooksを作ってSlackにメッセージを送る
- GASから時報メッセージをSlackに投稿する
- まとめ
SlackBotを作ってチャンネルに招待する
Botを作成する
Botを作製する手順が結構複雑だったので、忘備録として画像つきで手順を書いています。
自分のSlackのワークスペースの左上のユーザーメニューから[Administration] > [Manage apps]を選択します。
画面右上の[Build]のリンクをクリックします。
左側メニューのStart hereのすぐ下のBuilding Slack appsを選択します。
[Create Slack app]を選択します。
App Nameの箇所に任意の名前をつけてください
Development Slack Workspaceのプルダウンメニューには、Botを追加したいワークスペースを選択します。
[Create App]をクリックして次に進みます。
Add features and functionality内の[Bots]を選択します。
Display nameとDefault usernameを入力します。デフォルトでApp名が入りますが、任意に変更しても大丈夫です。入れ終わったら[Add Bot User]をクリックします。
Botの追加が終わったら、左メニューの[OAuth & Permissions]を選択、OAuth Tokens & Redirect URLsの下の[Install App to Workspace]をクリックします。
別のページに飛ばされます。Bot名を確認し、[Authorize]をクリックします。
次の画面でOAuth Tokenが取得できます。以下のNodeサーバーで必要になるのはBot User OAuth Access Token(xoxb-の文字で始まるほうをコピーします。これでSlackBotが作成されました。
Bot作成はワークスペースにBotが追加されているかを確認しておきます。Appsという項目内にBot名が追加されていれば大丈夫です。
Botをチャンネルに招待する
Bot用のチャンネルを作成し、BotをチャンネルにInviteします。適当なチャンネルを作成します。public/privateどちらでもかまいませんが、自分のワークスペースに他の人がいる場合は、privateチャンネルのほうがやりやすいかと思います。Nameにチャンネル名、Send invetes to: から作成したBotを選択し、[Create Channel]をクリックします。
チャンネル作成後、 joined [チャンネル名] along with [Bot名] とチャンネルに表示されていれば、自分とともにBotも追加されています。
ローカルでNodeサーバーを立ててVOICEROIDの発声をコントロールする
Nodeサーバーからゆかりさんへの発声コントロールをする場合は何かしらのCLIツールが必要になるかと思います。
GUIツールだとおかゆぅさんのゆかりねっとが有名かと思いますが、今回は自作のCLIツールを使ってVOICEROID+ 結月ゆかり EXをコントロールします。
(VOICEROID2では抑揚などのスライダーが動かすためには別のノウハウが必要になるようです。)
Nodeサーバーのコードを用意する
VOICEROIDがインストールされているPCにNode.jsをインストールしておきます。
Botがいるチャンネルのメッセージを取得するコードは以下のようになります。
<ReplaceHereYourBotUserOAuthAccessToken>の箇所を取得したBot User OAuth Access Tokenの文字列に置き換えます。(xoxb-の文字で始まるほうです。)
const { RTMClient } = require('@slack/client');
const TOKEN = '<ReplaceHereYourBotUserOAuthAccessToken>'
const { execSync } = require('child_process');
const rtm = new RTMClient(TOKEN);
rtm.start();
rtm.on('message', (message) => {
if(!message.text) {
return;
}
execSync(`.\\bin\\VoiceroidTClient.exe Yukari ${message.text}`);
console.log(`user:${message.user}, message: ${message.text}`);
});
コードサンプルはこちらに置いてます。依存パッケージがあるので、clone後はプロジェクトフォルダ内で npm install
のコマンドを実行しておきます。
blkcatman/node-exec-voiceroid-example
https://github.com/blkcatman/node-exec-voiceroid-example
また、上のexecSyncの箇所のコードからわかるように、プロジェクトフォルダ直下にあるbinフォルダー内にVoiceroidTClient.exeを置いておく必要があります。またVoiceroidTServer.exeもVOICEROIDをコントロールするのに必須なアプリケーションなので、同じようにbinフォルダーの中に入れます。
VOICEROIDを操作するCLIツールをビルドする
下記のリポジトリからソースコードをDLできます。VS2015のCommunityEditionでビルドできます。
(.NET 4.5が必要です。)
blkcatman/VoiceroidTalker
https://github.com/blkcatman/VoiceroidTalker
次はReleaseビルドを前提にお話します。ビルド後に生成される以下のファイルをindex.jsonと同階層にあるbinフォルダの中に移動します。
VoiceroidTClient/bin/Release/VoiceroidTClient.exe
VoiceroidTServer/bin/Release/VoiceroidTServer.exe
サーバーを動かす
あらかじめVOICEROIDを最小化していない状態で起動しておきます。
PowerShellもしくはVSコードのターミナルからnpmスクリプト経由でVoiceroidTServer.exeを実行します。プロセスが起動しっぱなしになるため、次の処理に移る前に別のPowerShell(VSコードターミナル)のウィンドウを立ち上げます。
npm run serve:yukari
同じようにnpmスクリプト経由でSlackBotのNodeサーバーを立ち上げます。
npm run serve:bot
発声をテストしてみる
SlackでBotがいるチャンネルで適当なメッセージを流します。
user:*********, message: テストメッセージです
user:*********, message: テストメッセージをしゃべっています
user:*********, message: テストメッセージを発声しています
Nodeサーバー上に上記のようにメッセージが出ていて、ゆかりさんがしゃべっていればOKです。
Incoming Webhooksを作る
記事があまりにも長くなるので、詳しい説明は割愛します。Webhookの投稿先チャンネルはBotがいるチャンネルを指定します。GASからSlackにポストするためのWebhook URLをコピーします。
Incoming Webhooksの作成方法はik-fibさんの記事を参考にしました。
SlackのIncoming Webhooksを使い倒す
https://qiita.com/ik-fib/items/b4a502d173a22b3947a0
GASから時報メッセージをSlackに投稿する
スプレッドシートを用意する
GoogleDriveから以下のような適当なスプレッドシートを作成します。
A列はラベルとして時刻を表記し、B列はゆかりさんに喋ってもらいたいテキストを入れています。0時~6時のように空欄箇所を作っておくと、その時間はゆかりさんが時報を喋らなくなります。
スクリプトを追加する
[ツール] > [スクリプト エディタ]からスクリプトを新規に作成します。
GASのサンプルコードはGistに置きました。(コードが長めなので、こちらではコードの表示を省略します)
blkcatman/TimeSignalToSlack.js
https://gist.github.com/blkcatman/98ef1bbbef89651033aef260d31a67f6
61行目の<ReplaceHereYourWebhookURL>の箇所をWebhook URLのURLに置き換えます。
var url = '<ReplaceHereYourWebhookURL>'
時報のトリガーを追加する
初回のトリガーを登録する時は、【関数を選択】から[createNextTimeSignalNow]を実行すれば、現在時刻から次の時刻に変わった時に時報のポストが発火します。発火後は次の時刻でのトリガーが自動的に追加されます。
パーミッションを許可する
コード実行時、権限関係の警告が出ると思いますので、このコードを許可します。
まとめ
前にトライした音声認識+VOICEROID+FaceRigでリアルタイムアバタートーキングではローカルPC内のみで完結していたので、そこから拡張するのが大変になっていました。
今回は時報というあまり大した機能ではありませんでしたが、SlackとGASなどのWebサービスと連携させることができ、構成が疎結合なシステムになったかと思います。
また、AWSやGCPなどのサービス群とも連携しやすくなったので、今後はAI化向けにカスタマイズしやすい環境になったので、いろいろな機能を追加できそうです。
音声認識周りはAlexaも使えそうなので、今後どのように機能を追加していくかいろいろ考えていきたいと思います。