前回、Amazon Echo Alexaのカスタムスキルを作る入門をやってみました。今回は少しコードやインテントをいじってカスタマイズして、Alexaちゃんにゴミ出しの曜日を教えてもらうスキルを開発してみます。
【Amazon Echo入門】Alexaちゃんに今日履いているパンツの色を答えさせる
ぼくはNode.jsよりPythonの方がいくらか得意なので、LambdaのPython3.6で開発してみます。
Lambdaの開発
AWSのLabmdaダッシュボード画面から「Create Function」します。
Blueprintsからalexaで検索したが、Python3.6のものがなかった。仕方ないので今回もAuthor from scratchで実装します。
前回はどうもAlexaとやりとりするための規定のリクエストとレスポンスのフォーマットがわからなかったのだけど、そこまで複雑なものではなく、単にレスポンスでJSONを返せばいいだけみたい。
参考:https://medium.com/@jacquelinewilson/amazon-alexa-skill-recipe-1444e6ee45a6
def lambda_handler(event, context): intent = event['request']['intent'] value = intent['slots']['TrashType']['value'] if value == '燃える': day = '燃えるゴミの日は火曜日です。' elif value == '燃えない': day = '燃えないゴミの日は水曜日です。' elif value == '資源': day = '資源ごみの日は木曜日です。' response = { 'version': '1.0', 'response': { 'outputSpeech': { 'type': 'PlainText', 'text': day } } } return response
前回同様にTriggersにAlexa Skills Kitを指定します。
ちゃんと動作するか確認したいので、Lambda Functionのテストを設定してみます。リクエスト内容は、intentのslots配下のみ書き換えます。
- Event template: Alext Intent - GetNewFact
- Event name: GetNewFact
{ "session": { "new": false, "sessionId": "amzn1.echo-api.session.[unique-value-here]", "attributes": {}, "user": { "userId": "amzn1.ask.account.[unique-value-here]" }, "application": { "applicationId": "amzn1.ask.skill.[unique-value-here]" } }, "version": "1.0", "request": { "locale": "en-US", "timestamp": "2016-10-27T21:06:28Z", "type": "IntentRequest", "requestId": "amzn1.echo-api.request.[unique-value-here]", "intent": { "slots": { "TrashType": { "name": "TrashType", "value": "燃えない" } }, "name": "GetNewFactIntent" } }, "context": { "AudioPlayer": { "playerActivity": "IDLE" }, "System": { "device": { "supportedInterfaces": { "AudioPlayer": {} } }, "application": { "applicationId": "amzn1.ask.skill.[unique-value-here]" }, "user": { "userId": "amzn1.ask.account.[unique-value-here]" } } } }
実行すると、outputSpeech
のtext
に「燃えないゴミの日は水曜日です。」と返ってきていることが確認出来る。
Alexa Skill側の設定
開発者コンソールから前回同様に新しいSkillを登録していきます。
- スキル名: TrashDay
- 呼び出し名: ゴミ出しの日
{ "intents": [ { "slots": [ { "name": "TrashType", "type": "LIST_OF_TRASH_TYPE" } ], "intent": "GetNewFactIntent" } ] }
カスタムスロットタイプにゴミの種別を設定する。
- タイプ: LIST_OF_TRASH_TYPE
- 値:
- 燃える
- 燃えない
- 資源
サンプル発話に以下を設定。
GetNewFactIntent {TrashType} ゴミの日 GetNewFactIntent {TrashType} ゴミの日教えて GetNewFactIntent {TrashType} ごみの日 GetNewFactIntent {TrashType} ごみの日教えて
前回同様に、エンドポイントのデフォルトにLambdaのARN IDを指定する。
シミュレータでテストしてみる。
「燃えるゴミの日教えてください」と入力して呼び出すと、インテントのTrashTypeが「燃える」と認識され、レスポンスで「燃えるゴミの日は火曜日です。」と返って来ていることが確認出来る。
まとめ
無事できました!
インテント周りの概念がちょっと慣れるまでわかりづらいですが、一度やってみると感覚的に理解できるようになりますね。
今回もLambdaで実装しましたが、どうやら普通にエンドポイントを指定して、HTTPでリクエストしてもいけるみたいです。これを利用すれば外部のサーバーにリクエストしたりできるので、既存のサービスとの連携も色々できそうですね。
次回はゴミ出しの日を、プログラムに直接入れるのではなく、どこか別のデータソースから取ってくる実装をしてみたいなーと思ってます。