Alexa Skillの開発をServerless Frameworkだけで完結するための「Serverless Alexa Skills Plugin」の紹介
この記事は、Serverless Advent Calendar 13日目の記事です。
今回は拙作ですがオススメのServerless FrameworkのPluginを紹介したいと思います。
概要
Serverless Alexa Skills Pluginは、Serverless FrameworkでAlexa Skill用のLambda Functionを開発しながら、スキル周辺の設定も serverless.yml
および serverless(sls)
コマンドから管理できるようにすることで、Alexa Skillの開発をServerless Frameworkで統合管理するためのPluginです。
経緯など
Alexa Skillの開発にはLambda Functionの開発がセット
Alexaのカスタムスキルを作る場合、基本的にはLambda Functionの開発がセットになります。もちろん、Lambdaを使わずに特定のHTTP Endpointとやり取りすることで実行することもできますが、HTTPサーバを作って運用したりする手間とコストを考えるとLambdaを使う方が大抵の場合楽ですし、コストメリットも高いです。
Lambda Functionの開発はServerless Frameworkでやりたい
最近は専らLambda Functionの開発はServerless Frameworkでやっています。以前は独自のデプロイツールを作って使っていたりもしましたが、v1.0からFrameworkの内部構造がそれ以前より段違いで良くなり、足りない機能はpull requestを送ったりpluginを作ったりして補えるようになったため、フルタイムで会社まで作ってメンテしていて、良い感じにエコシステムが確立しつつある製品に対抗してもしょうがないので乗っかる方針でやっています。
Alexa Skillの設定管理がめんどくさい
対して、Alexa Skillの設定はAlexa Skill Kitのコンソール画面から行うか、ack-cliを使う方法が公式で提唱されています。このack-cliがまた設定をJSONで書かないといけなかったり、公式ツールなのでしょうがないのですが、APIに忠実に作られているので必要なコマンド数が多かったりするわけです。
Serverless Frameworkで全部良い感じにやりたい
そんな思いから生まれたのがServerless Alexa Skills Pluginというわけです。
使い方
インストール
インストールはnpmにリリースされてるのでこれだけです。
$ npm install -g serverless $ serverless plugin install -n serverless-alexa-skills
認証情報の取得
利用するためにはLambda FunctionをデプロイするためのAWSの認証情報もそうですが、Alexa Skills Kit APIを実行するための認証情報も必要になります。AlexaはAWSではなくAmazon本体の管轄であり、Login with Amazon
というAmazon本体アカウントを使ったOAuth2.0によるシングルサインオンで認証を受ける必要が有るため、認証情報の扱いが異なるのでそこを説明したいと思います。AWSの認証情報の取得方法についてはここでは触れません。
まず、Amazon Developer Consoleへログインします。
APPS&SERVICES
タブから Login with Amazon
へ移動し、 Create a New Security Profile
からセキュリティプロファイルを作成します。
各入力項目は適当で良いです。
作成したら、出来上がったセキュリティプロファイルの Web Settings
を設定します。
Allowed Origins
は空で良いです。 Allowed Return URLs
に http://localhost:3000
を入力します。このポート番号は設定(serverless.yml)で変更可能なので、変えたい場合は変えても良いです。
ここまでできたら、できあがったセキュリティプロファイルの Client ID
と Client Secret
を控えておきましょう。併せてもう一つ、 Vendor ID
というものも必要になるので、Developer Consoleへログインした状態でコチラへアクセスして控えておきましょう。
ちょっと面倒ですが、この作業は初回だけです。同じアカウントを使う限りは今後いくつスキルを作ろうと同じ情報が使えます(漏洩などして入れ替えが必要にならなければw)
面倒な画面ポチポチはここまでです!!ここから先はみんな大好きの黒い画面をメインに進みます!!
認証情報をセット
取得した認証情報を serverless.yml
へ書き込みます。直接書き込むのに抵抗がある場合は下記のように環境変数を利用すると良いでしょう。また、 Allowed Return URLs
でポート番号を買えた場合は localServerPort
という設定を追加してポート番号を書き込んでください。
provider: name: aws runtime: nodejs6.10 plugins: - serverless-alexa-skills custom: alexa: vendorId: ${env:YOUR_AMAZON_VENDOR_ID} clientId: ${env:YOUR_AMAZON_CLIENT_ID} clientSecret: ${env:YOUR_AMAZON_CLIENT_SECRET}
そして、以下のコマンドを実行します。
$ serverless alexa auth
このコマンドを実行するとブラウザが開かれAmazonへのログイン画面が出てきます。そこでログインに成功すると localhost:3000
へリダイレクトされ、認証に成功していれば Thank you for using Serverless Alexa Skills Plugin!!
とデザイン皆無の味も素っ気もないメッセージが表示されているはずです!w
ちなみにこれによって取得した認証トークンの有効期限は1時間となっています。今後、トークンの自動リフレッシュなど実装予定ですが、現状では認証エラーが出たら再度上記コマンドの実行をお願いします。
スキルの作成
それではスキルを作ってみましょう。以下のコマンドを実行します。
$ serverless alexa create --name $YOUR_SKILL_NAME --locale $YOUR_SKILL_LOCALE --type $YOUR_SKILL_TYPE
それぞれオプションは以下の通りです。
- name(n): スキルの名前
- locale(l): スキルのロケール。日本語なら
ja-JP
, 英語ならen-US
- type(t): スキルのタイプ。
custom
orsmartHome
orvideo
スキルマニフェストの更新
スキルを作ったら、スキルの基本的な設定を表すスキルマニフェストを設定する必要があります。今作成したスキルに初期設定されているマニフェストは以下のコマンドで確認できます。
$ severless alexa manifests Serverless: ---------------- [Skill ID] amzn1.ask.skill.xxxxxx-xxxxxx-xxxxx [Stage] development [Skill Manifest] skillManifest: publishingInformation: locales: ja-JP: name: sample apis: custom: {} manifestVersion: '1.0'
実行すると上記のような出力が出るので、 [Skill ID]
と [Skill Manifest]
をコピーして serverless.yml
へ以下のように貼り付けます。
custom: alexa: vendorId: ${env:AMAZON_VENDOR_ID} clientId: ${env:AMAZON_CLIENT_ID} clientSecret: ${env:AMAZON_CLIENT_SECRET} skills: - id: ${env:ALEXA_SKILL_ID} skillManifest: publishingInformation: locales: ja-JP: name: sample apis: custom: {} manifestVersion: '1.0'
この serverless.yml
の設定を更新後、下記のコマンドを実行するとマニフェストが更新されます。ちなみに恒例?の --dryRun/-d
オプションで実際に更新は行わずに更新内容だけ確認できます。
$ serverless alexa update
マニフェストの設定構文についてはAPIに準じているので、こちらで確認できます。
対話モデルの構築
Alexaスキルを動かすためには、対話モデルの構築が必要です。これもマニフェストとほぼ同じ流れでできますが、作成しただけのスキルは対話モデルを持っていないのでまず先に serverless.yml
に対話モデルの設定を書き込む所から始まります。
custom: alexa: vendorId: ${env:AMAZON_VENDOR_ID} clientId: ${env:AMAZON_CLIENT_ID} clientSecret: ${env:AMAZON_CLIENT_SECRET} skills: - id: ${env:ALEXA_SKILL_ID} skillManifest: publishingInformation: locales: ja-JP: name: sample apis: custom: {} manifestVersion: '1.0' models: ja-JP: interactionModel: languageModel: invocationName: PPAP intents: - name: PineAppleIntent slots: - name: Fisrt type: AMAZON.Food - name: Second type: AMAZON.Food
このような形で models.ロケール.interactionModel
という構造で下記に準じた対話モデルを設定します。
そして、下記のコマンドで対話モデルを更新し、構築します。ここでも --dryRun
が利用可能です。
$ serverless alexa build
構築した対話モデルは下記のコマンドで確認可能です。
$ serverless alexa models Serverless: ------------------- [Skill ID] amzn1.ask.skill.xxxx-xxxx-xxxxx [Locale] ja-JP [Interaction Model] interactionModel: languageModel: invocationName: PPAP intents: - name: PineAppleIntent slots: - name: Fisrt type: AMAZON.Food - name: Second type: AMAZON.Food
現段階では以上です
ここから実際にスキルを公開するまではもう少しステップがありますが、一番変更が多く試行錯誤が必要でバージョン管理しておきたいマニフェストと対話モデルが統合管理できるのは大きいのではないかと思います。今後Alexa Skills Kitを通したテストや公開まで統合できるよう開発は進めていきたいと思っています。
また、ここでは触れなかったServerless FrameworkでAlexa Skill用のLambda Functionを実装する方法についてはこちらをご確認ください。
良かったら今後Alexaスキルを作る際にご利用いただき、フィードバックやStarをいただけると励みになりますので、よろしくお願いします。