alexa-sdkとask-sdk。新しいASK SDKへの移行準備

先日Alexa Skills KitのSDK(Node.js)のバージョン2がリリースされました。Now Available: Version 2 of the ASK Software Development Kit […]

広告ここから
広告ここまで

目次

    先日Alexa Skills KitのSDK(Node.js)のバージョン2がリリースされました。
    Now Available: Version 2 of the ASK Software Development Kit for Node.js

    かなり破壊的な変更が入っていますので、現状のalexa-sdkを使われている方向けに状況を整理します。

    ポイント1:V1とV2はパッケージ名が別

    最新バージョンということなのでnpmでインストールすれば良いのかと思いましたが、そもそも落としてくるパッケージ名が別になっています。

    // Version 1
    $ npm i -S alexa-sdk
    
    // Version 2
    $ npm i -S ask-sdk

    ポイント2:パッケージが分割された

    これまではsdk1つに全ての機能が用意されていました。しかしv2からは、必要な機能だけ利用する形でパッケージの軽量化が可能になっています。

    // 全部入り
    $ npm i -S ask-sdk
    
    // 実質上と同じ
    $ npm i -S ask-sdk-core ask-sdk-model ask-sdk-dynamodb-persistence-adapter

    alexa-sdkの各機能を以下のように分割している様子です。

    • ask-sdk-core: コア部分(必須)
    • ask-sdk-model: 対話モデル部分など
    • ask-sdk-dynamodb-persistence-adapter: DynamoDBとの連携部分

    ポイント3:v1コードもそのまま利用できる(アダプター必須)

    すでにスキルを開発されている場合、v2に全部マイグレしようというのはかなりつらみがあります。

    しかし幸いにもv1 / v2コードが混ざっても大丈夫なようにアダプターが用意されていました。

    アダプターをインストール

    $ npm install -S ask-sdk-v1adapter ask-sdk

    requireをアダプターに変更

    // const Alexa = require('alexa-sdk');
    const Alexa = require('ask-sdk-v1adapter');

    混ぜても大丈夫なので、順次マイグレーションしていく

    'use strict';
    const Alexa = require('ask-sdk-v1adapter');
    
    exports.handler = function(event, context, callback) {
        const alexa = Alexa.handler(event, context);
        alexa.registerHandlers(handlers);
        alexa.registerV2Handlers(HelpIntentHandler); // New API functions for registering v2 request handlers
        alexa.execute();
    };
    
    const handlers = {
        'LaunchRequest': function () {
            this.emit('SayHello');
        },
        'HelloWorldIntent': function () {
            this.emit('SayHello');
        },
        'SayHello': function () {
            this.response.speak('Hello World!');
            this.emit(':responseReady');
        },
        'AMAZON.CancelIntent': function () {
            this.response.speak('Goodbye!');
            this.emit(':responseReady');
        },
        'AMAZON.StopIntent': function () {
            this.response.speak('See you later!');
            this.emit(':responseReady');
        }
    };
    
    // HelpIntentHandler re-written following v2 request handler interface
    const HelpIntentHandler = {
        canHandle : function({requestEnvelope}) {
            return requestEnvelope.request.type === 'IntentRequest'
            && requestEvelope.request.intent.name === 'AMAZON.HelpIntent';
        },
        handle : function({responseBuilder}){
            const speechOutput = 'This is the Hello World Sample Skill. ';
            const reprompt = 'Say hello, to hear me speak.';
            return responseBuilder.speak(speechOutput)
                                  .reprompt(reprompt)
                                  .getResponse();
        },
    };

    ポイント4:このブログで紹介しているテストはだいたい死ぬ

    平たくいうと、alexa-conversationが現状未対応です。2018/04/22時点で最終更新が数ヶ月前のままなので、もしかするとメンテナンスされないままかもしれません。

    $ npm test
    
    > [email protected] test /develop/alexa/test
    >  ./node_modules/mocha/bin/_mocha tests/*.js
    
    (node:36453) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property 'System' of undefined
    (node:36453) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
      Executing conversation: Test Conversation

    とりあえずServerless Frameworkのsls invoke localを使うことでローカルテストはできそうでした。

    $ sls invoke local -f hello -d "{
      'session': {
        'new': true,
        'sessionId': 'amzn1.echo-api.session.[unique-value-here]',
        'attributes': {},
        'user': {
          'userId': 'amzn1.ask.account.[unique-value-here]'
        },
        'application': {
          'applicationId': 'amzn1.ask.skill.f35b1223-1ed1-4283-a207-0e5d0fd2ff05'
        }
      },
      'version': '1.0',
      'request': {
        'locale': 'en-US',
        'timestamp': '2016-10-27T18:21:44Z',
        'type': 'LaunchRequest',
        'requestId': 'amzn1.echo-api.request.[unique-value-here]'
      },
      'context': {
        'AudioPlayer': {
          'playerActivity': 'IDLE'
        },
        'System': {
          'device': {
            'supportedInterfaces': {
              'AudioPlayer': {}
            }
          },
          'application': {
            'applicationId': 'amzn1.ask.skill.f35b1223-1ed1-4283-a207-0e5d0fd2ff05'
          },
          'user': {
            'userId': 'amzn1.ask.account.[unique-value-here]'
          }
        }
      }
    }"
    
    {
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "SSML",
                "ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
            },
            "reprompt": {
                "outputSpeech": {
                    "type": "SSML",
                    "ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
                }
            },
            "shouldEndSession": false
        },
        "userAgent": "ask-node/2.0.1 Node/v7.4.0"
    }
    

    LambdaをInvokeした返り値をテストすれば良い(はず)なので、ユニットテスト等についても改めてまとめます。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark