自己紹介
こんにちは,ZOZOテクノロジーズの内定者さっとです.
最近、Alexaアプリの開発で遊んでいます!
意外と簡単に開発できるので、身の回りがもっと便利になるようなスキルを開発したいと思うこの頃です。
※本記事はZOZOテクノロジーズ#5の4日目です.
昨日は@pakioさんが「v-for内のv-checkboxの値をwatchプロパティで検知したい」という記事を出しました.
他にもZOZOテクノロジーズでは5つのアドベントカレンダーを毎日更新しています!
やること
アレクサアプリ開発でOAuth2.0を使った外部サービス(GoogleやFacebook,Slackなど)と連携したいことがあるかと思います.アレクサアプリでは,外部サービスとの連携を「アカウントリンク」と呼びますが,必要な項目を埋めるだけで簡単に設定することができます.
しかし,簡単に設定できるがゆえに,連携が失敗したり,上手くいかないとき調べる方法がありません.
そこで今回は,2016年にアレクサblogで紹介された下記の記事を元に,2019年版に刷新したデバック方法を紹介したいと思います.
How to Set up Amazon API Gateway as a Proxy to Debug Account Linking
API Gatewayを用いたプロキシ
先のブログでは,下記のようにAlexaと外部サービスの間にAWSのAPI Gatewayを利用したHTTPプロキシを構築しています.
How to Set up Amazon API Gateway as a Proxy to Debug Account Linking より
このような構成にすることで,
Alexa Voice Serviceでアカウントリンクが実行されるときに発生するHTTPトラフィックはすべてCloudwatchに記録することができます.
環境構築
前提条件
今回は,連携する外部サービスとしてAmazonを利用します.
そのため,Amazonのアカウントが必要です.
また,AWSでHTTPプロキシを構築するため,AWSアカウントも別途必要です.
ここで注意したいのが,IAMを作成できる権限を持っていなければなりません.
Login with Amazon
AmazonとAlexaを連携するためにLogin with AmazonにてOAuth2の証明書を作成しましょう.
作成した
- クライアントID
- クライアントシークレット
をメモしておきましょう.
Login with Amazonは下記からアクセスできます.
https://developer.amazon.com/loginwithamazon/console/site/lwa/overview.html
作成方法は,下記のAlexa Developers JPチャンネルの動画が参考になります.
また,アカウントリンク方法も紹介しているので,普通に神動画です.
https://youtu.be/dnzZzc2sKBA?t=960
AWS CloudFormation
AWS CloudFormationとは
HTTPプロキシはAWSのCloudFormationを利用して作成します.
CloudFormationとは,AWSが提供するリソースのモデル化およびセットアップをサポートしてくれるサービスです.
API Gateway,Cloudwatchなどのリソースの構築に必要な設定を記述したテンプレートファイルをインポートすることで簡単に環境を構築することができます.
テンプレートのダウンロードと編集
今回は,本家サイトが提供するCloudFormationのテンプレートファイルを用いて構築するので事前にダウンロードしておきましょう.
https://alexademo.ninja/httpproxy/cloudformation-us-east-1.json
How to Set up Amazon API Gateway as a Proxy to Debug Account Linking より
また,ブログは2016年のもので,テンプレートもその当時のままです.
このままでは,ビルド時に下記のようなエラーが発生してしまいます.
The runtime parameter of nodejs4.3 is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs8.10, nodejs10.x) while creating or updating functions. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException;)
エラーは,Lambda構築時にnodejsのバージョンが対応していないため,怒られています.
ログを見ると,nodejs8.10やnodejs10.xにしてと言われているので,下記のようにファイルを編集します.
65行目が"Runtime": "nodejs4.3",
となっているので,
これを下記のように"Runtime": "nodejs8.10",
に変更し,保存しましょう.
"HostnameLambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "alexademo.ninja",
"S3Key": "httpproxy/lambda/hostname_lambda_function.zip"
},
"Handler": "index.handler",
"Runtime": "nodejs8.10",
"Timeout": "30",
"Role": {
"Fn::GetAtt": ["LambdaExecutionRole", "Arn"]
}
}
},
サービスの選択
まず,リージョンをバージニア北部に設定しましょう.
その後,サービスからCloudFormationを選択します.
スタックの作成
テンプレートの選択
次に,テンプレートファイルのアップロードを選択し,
ファイルの選択でテンプレートファイルをアップデートします.
最後に,次へを押します.
パラメータの設定
次に,スタックの名前を設定します.
これは,わかりやすい名前であれば何でも良いですが,今回はOAuthDebugとしました.
その後,外部サービスと連携するために必要なAccessTokenURLとAuthorizationURLを設定しましょう.
今回は,Login with Amazonを利用するのでデフォルトで入っているとおりにします.
Login with Amazonの詳細なドキュメントは下記から確認してください.
https://developer.amazon.com/ja/docs/login-with-amazon/authorization-code-grant.html
スタックオプションの設定および詳細オプション
ここは,特に設定する項目は無いので,次へを選択します.
スタックの作成
最後に,IAMが作成されることを承認し,スタックを作成しましょう.
スタックの構築状況の確認
イベントログが流れ,環境が構築されている様子が見えると思います.
スタックの構築状況を確認するために,タブでスタックの情報を選択しましょう.
ステータスがCREATE_COMPLETEになるまで待ちます.
大体30秒~1分ぐらいかかります.
リンクのコピー
出力されたProxyAccessTokenURLとProxyAuthenticationURLはプロキシの入り口となるリンクになります.
Alexa開発者コンソールのアカウントリンクにこれらのURLを設定することで,HTTPプロキシ経由で外部サービスと通信を行うことが可能になります.
アレクサアプリの設定
Alexa開発者コンソールからリンクアカウントの設定を行います.
ProxyAuthenticationURLを認証画面のURIに貼り付けます
ProxyAuthenticationURLをアクセストークンのURI
実際に通信を発生させてみる
- スマホのアレクサアプリからデバックしたいスキルを選択しアカウントリンクをクリックします.

- これはおなじみのOauth2.0の認証画面ですね.

- 認証が成功すると次の画面が表示されます.

デバックログの確認
-
AWSのコンソールからCloudWatchのサービスを選択
-
ログストリームが2つあり,それぞれコード発行およびトークン発行時に発生したログになります.
- ログを確認するとaccess_tokenもここで確認できます.
認証失敗時のログ
-
デバックが機能しているかを確認するためにクライアントシークレットをあえて間違えてみます.
-
認証しようとすると勿論「アカウントリンクを完了できませんでした」と表示されます.

- このときのログを確認すると
コード発行は無事できていることがわかります.
Successfully completed execution
しかし,アクセストークン取得時に失敗していることが確認できます.
{
"error_description": "Client authentication failed",
"error": "invalid_client"
}
また,イベントフィルターでerrorと入れて検索するとエラーが起きているログだけ抽出できるので,
デバック作業の足がかりになると思います.
おわりに
今回は,Alexaアプリでアカウントリンク失敗した際のデバック方法を紹介しました.
Alexaに限らず,似たようなサービスでも利用できますので,ぜひ利用してみてください.
明日は,@ikeponsu さんで「Go言語の標準パッケージだけで画像処理をする その1 (入出力)」です!
お楽しみに!