[Alexa] Amazon LexのスキーマからAlexaスキルを作成する

alexa-eyecatch

1 はじめに

Amazon Lex(以下、Lex)のBotのスキーマをエクスポートして、Amazon Alexa(以下、Alexa)のスキルのInteraction Modelに使用することができるようになりました。

Export your Amazon Lex bot schema to the Alexa Skills Kit

Lexでは、お花の注文をするOrderFlowerというボットがサンプルとして提供されています。今回は、これをそのままスキルにしてみました。

001

2 Lexからのエクスポート

サンプルから作成したBotPublishにした後、一覧画面から、対象のBotを選択してAction > Export を選択します

002

対象のバージョンとPlatform「Alexa Skill Kit(ASK)」を選択してExportします。

003

ダウンロードされたzipファイルを解凍すると、次のようなJSONになっていました。

{
    "dialog": {
        "intents": [
            {
                "confirmationRequired": true, 
                "name": "OrderFlowers", 
                "prompts": {
                    "confirm": "Confirm.Intent-OrderFlowers"
                }, 
                "slots": [
                    {
                        "confirmationRequired": false, 
                        "elicitationRequired": true, 
                        "name": "FlowerType", 
                        "prompts": {
                            "elicit": "Elicit.Intent-OrderFlowers.IntentSlot-FlowerType"
                        }, 
                        "type": "FlowerTypes"
                    }, 
                    {
                        "confirmationRequired": false, 
                        "elicitationRequired": true, 
                        "name": "PickupDate", 
                        "prompts": {
                            "elicit": "Elicit.Intent-OrderFlowers.IntentSlot-PickupDate"
                        }, 
                        "type": "AMAZON.DATE"
                    }, 
                    {
                        "confirmationRequired": false, 
                        "elicitationRequired": true, 
                        "name": "PickupTime", 
                        "prompts": {
                            "elicit": "Elicit.Intent-OrderFlowers.IntentSlot-PickupTime"
                        }, 
                        "type": "AMAZON.TIME"
                    }
                ]
            }
        ], 
        "version": "1.0"
    }, 
    "intents": [
        {
            "name": "OrderFlowers", 
            "samples": [
                "I would like to pick up flowers", 
                "I would like to order some flowers"
            ], 
            "slots": [
                {
                    "name": "FlowerType", 
                    "samples": [
                        "I would like to order {FlowerType}"
                    ], 
                    "type": "FlowerTypes"
                }, 
                {
                    "name": "PickupDate", 
                    "samples": [], 
                    "type": "AMAZON.DATE"
                }, 
                {
                    "name": "PickupTime", 
                    "samples": [], 
                    "type": "AMAZON.TIME"
                }
            ]
        }
    ], 
    "prompts": [
        {
            "definitionVersion": "1.0", 
            "id": "Confirm.Intent-OrderFlowers", 
            "promptVersion": "1.0", 
            "variations": [
                {
                    "type": "PlainText", 
                    "value": "Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}.  Does this sound okay?"
                }, 
                {
                    "type": "PlainText", 
                    "value": "Okay, your {FlowerType} will be ready for pickup by {PickupTime} on {PickupDate}, and will cost [Price] dollars.  Does this sound okay?"
                }
            ]
        }, 
        {
            "definitionVersion": "1.0", 
            "id": "Elicit.Intent-OrderFlowers.IntentSlot-FlowerType", 
            "promptVersion": "1.0", 
            "variations": [
                {
                    "type": "PlainText", 
                    "value": "What type of flowers would you like to order?"
                }
            ]
        }, 
        {
            "definitionVersion": "1.0", 
            "id": "Elicit.Intent-OrderFlowers.IntentSlot-PickupDate", 
            "promptVersion": "1.0", 
            "variations": [
                {
                    "type": "PlainText", 
                    "value": "What day do you want the {FlowerType} to be picked up?"
                }, 
                {
                    "type": "PlainText", 
                    "value": "Pick up the {FlowerType} at {PickupTime} on what day?"
                }
            ]
        }, 
        {
            "definitionVersion": "1.0", 
            "id": "Elicit.Intent-OrderFlowers.IntentSlot-PickupTime", 
            "promptVersion": "1.0", 
            "variations": [
                {
                    "type": "PlainText", 
                    "value": "At what time do you want the {FlowerType} to be picked up?"
                }, 
                {
                    "type": "PlainText", 
                    "value": "Pick up the {FlowerType} at what time on {PickupDate}?"
                }
            ]
        }
    ], 
    "types": [
        {
            "name": "FlowerTypes", 
            "values": [
                {
                    "name": {
                        "synonyms": [], 
                        "value": "tulips"
                    }
                }, 
                {
                    "name": {
                        "synonyms": [], 
                        "value": "lilies"
                    }
                }, 
                {
                    "name": {
                        "synonyms": [], 
                        "value": "roses"
                    }
                }
            ]
        }
    ]
}

3 Skillへのインポート

まずは、Amazon開発者コンソールから、スキルを作成します。(ここでは、Invation Nameを「my sample」としています)

004

続いて、Interaction Modelでは、Launch Skill Builder(BETA) を選択します。

005

Interface Builderのメニューで、Code Editorを選択し、Drag and drop your json fileの所に、先程ExportしたJSONファイルをドロップします。

006 007

そのまま、保存しようとすると、エラーが発生していたので、とりあえず、[Place][] を削除しました。

008

009

Buildが無事成功したところで、少し内容を確認して見ると、OrderFlowersというインテントと、ダイアログモデルの必須スロットして、FlowerTypePickupDatePickupTimesが確認できます。 010

また、カスタムスロットも、そのまま変換されています。

012

そして、ダイアログモデルならではの、Slot Fillingが、そのまま収まっています。

013

4 Skill作成

殆どが、ダイアログモデルで処理されるため、書いたSkillのコードは、これだけです。

ダイアログモデルがCOMPLETEDを返すまで、全部、this.emit(':delegate'); で返しているだけです。

var Alexa = require('alexa-sdk');
const alexaAppId = process.env.ALEXA_APPLICATION_ID

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.appId = alexaAppId;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

const handlers = {
  'OrderFlowers': function () {
    if (this.event.request.dialogState === 'STARTED' || this.event.request.dialogState !== 'COMPLETED') {
        this.emit(':delegate');
    } else {
      this.emit(':tell', 'Congrats! Your order has succeeded.');
    }
  },
  'Unhandled':function () {
    this.emit('OrderFlowers');
  }
};

5 動作確認

動作しているようすは、次のとおりです。

もし、LexOrder Flowersサンプルを動作させた事がある方は、ちょっと懐かしいのではないでしょうか。

6 最後に

SkillBuilder(beta)で利用できるダイアログモードは、当初からLexと似てるな〜、と思ってましたが・・・そう、一緒でした。

ダイアログモデルを使用するのであれば、Lex開発の経験者は、違和感なく、SkillInteraction Modelが作成できるのではないでしょうか。

7 参考リスト

Export your Amazon Lex bot schema to the Alexa Skills Kit