Google HomeとChinachuで"今日のアニメ"アシスタントを作った
自分が追っているアニメの放送時間がパッと分かるような仕組みがあったらいいな~と思ったのでGoogle Homeのアシスタントを作りました。
できること
番組情報はChinachuの予約済み/録画中/録画済みから抽出しています。
「OK Google, (一昨|昨|今|明|明後)日のアニメ」 あるとき ->「 (一昨|昨|今|明|明後)日は${番組情報リスト.map(e => `${e.時刻}から${e.チャンネル名}で${e.番組名}`).join('、')}です。」 ないとき ->「(一昨|昨|今|明|明後)日の番組が見つかりませんでした。」
構成
①Chinachu γ
ありがたいことにREST APIが用意されています。予約済み/録画中/録画済みリストを取得するには/reserves
と/recording
と/recorded
が使えます。
REST API · Chinachu/Chinachu Wiki · GitHub
②Nginx
ローカルのChinachuをリバースプロキシで外に出しています。Basic認証を設定しています。
③AWS Lambda
Dialogflowから飛んできたリクエストを捌いて、Google Homeに喋らせるメッセージを作ります。Dialogflowから飛んでくるリクエストと返すべきレスポンスは以下のドキュメントページを参照しました。expectUserResponse: false
にすることでGoogle Homeに喋らせたらそのままアプリを終了させることが出来ます。(そうしないと「キャンセル」とか言わないと自作アプリから抜けられない)
メッセージを作る際にはLambdaからChinachuに先のREST APIを用いて問い合わせて得られた番組情報リストをDialogflowで飛んできた日付でフィルタリングして残った番組情報を使っています。深夜番組特有の25時があるので朝の5時を日付の変更線にしています。ソースコードはGitHubに上げています。
Lambdaの環境変数タブに認証等に必要な情報を入れています。(パスワードを平文で入れて大丈夫なんだろうか...)
④Amazon API Gateway
リソース
- POST
/chinachu-linkage
- 認証
なし
- APIキー
必須
- 統合タイプ
Lambdaファンクション
こちらの記事でも言及されているようにメソッドレスポンスのコンテンツタイプをapplication/json; charset=UTF-8
にしないとGoogle Assistantで日本語が文字化けしてしまいました。
ステージ
dev
を作成しました。
APIキー
my_api
を作成しました。
使用量プラン
スロットリングとクォータを無効にしてbasic
を作成し、関連付けられた API ステージにchinachu-linkage
とdev
を追加し、my_api
を使用量プランに追加しました。
⑤Dialogflow
1. Entities
daywordというエンティティを作りました。
2. Fulfillment
Webhookを有効にしてRLをdev
ステージのものにし、Headerにx-api-key: my_apiのキー
を追加しました。
3. Intents
「今日のアニメ」というIntentsを作成し、Training phrasesタブに「今日のアニメ」と入力しました。するとGoogleは賢くて「@daywordのアニメ」という文章に反応してくれるようになります。
またFulfillmentタブでこのインテントに対するWebhookを有効にしました。
4. Integrations
Google Assistantを選択します。
⑥Google Assistant
DialogflowとGoogle Assistantを連携した時点で自動的に実機でも作ったアプリが起動できるようになりました。またInvocationでDisplay Nameを「今日のアニメ」にしました。
ルーティン(ショートカット)の作成
現状までで「OK Google, 今日のアニメにつないで(一昨|昨|今|明|明後)日のアニメを聞いて」が可能になりましたが、かなりまどろっこしいのでルーティンという機能を使って簡単にしました。モバイルのGoogle Assistantアプリから設定できました。
画像は「今日」のものですが同様に他の日も設定しました。(これもエンティティみたいにひとまとめにできたらいいのに)
完成
やったぜ。
気になること
これを見る限りPublishしてないテストアプリは30日立ったら失効してしまうらしい。30日立ったらもっかいシミュレータにアクセスすればいいのだろうけど、それは面倒。どうしよう。