前回、前々回 とAlexaからSlackに通知できる仕組みを試してみましたが、Alexaから呼ばれるLambdaに接続先やメッセージを環境変数で設定する必要があり、ユーザ毎にできるようにしたくなってきました*1
今の仕組みでも、Alexaユーザーとシステムユーザーを関連付けることができます。そこから接続情報やメッセージを引っ張って来れればうまく行きそうです。
- ユーザ毎に情報を保持するアプリ
- Alexa SKill
の2本立てで行きたいと思います。
Serverlessの為にどんな構成にする?
永続化は?
最初はユーザに紐付く情報をCognito Syncで考えていたのですが、各端末間のデータ同期に特化したサービスらしく、Lambda上でユーザに紐付く情報を取得するのは難しそうでした。なので、保存先はDynamoDBで行います。
イメージはこんな感じです。
ユーザ毎に情報を保持するアプリ
API Gateway経由でリクエストを受け取り、レスポンスを返します。AlexaからKickされたLambdaがユーザに紐付く情報を取得するのもこのアプリ経由になります。設定画面は誰からもアクセスされると困るので、API Gateway 側でTokenの有効性をチェックします。
Alexa Skill
AlexaからKickされたLambdaはAccess Tokenを元にユーザに紐付く情報を取得します(アカウントリンクを有効にします)。そして、その情報を元にSlackに通知を投げます。
ちょっと気になる点
それぞれのGitHubリポジトリ上に構築手順をまとめましたので、気になる方はぜひ試してみてください。 実は、API GatewayのカスタムオーソライザーでCognitoのarnを直接設定できます。これでTokenの有効性チェックを自前で行う必要はないのですがID Tokenしか有効でないらしく、AlexaからKickされたLambdaにはAccessTokenしか渡ってこない為、自前でチェックしています。その辺ご存知の方がいらっしゃればご教示頂きたいです。
まとめ
現在、Alexaからユーザ固有の設定をリクエストパラメータ的に渡すのは難しいので、外部のシステムに保持させておき、Access Tokenを元に取得するという方法が実現できました。これでちょっとスマートスピーカーの使い道も広がるんじゃないかと思います。
*1:流石にユーザに声でメッセージやURLを伝えてもらうのは無理ゲーだと思いました