ASK SDK v1アダプターを使ってAlexa SDK(v1)→ ASK SDK(v2)へ移行する

ASK SDK v1アダプターを使うと、旧来のSDK(v1)で書かれたAlexaスキルのコードを段階的にASK SDK(v2)へ移行することができます。
2018.08.02

はじめに

Alexa SDK v2 for Node.js(ASK SDK)では、 旧来のAlexa SDK v1(Alexa SDK)から移行を行うために、後方互換性のあるASK SDK v1アダプターが用意されています。

GitHub alexa/alexa-skills-kit-sdk-for-nodejs/ask-sdk-v1adapter

こちらのアダプターを利用することで、v1とv2のコードを共存させることができ、v1で書かれたスキルのコードを段階的にv2へ移行できます。

v1のコードサンプル

今回は、Alexaに「こんにちは」というだけの簡単なスキルを例にとってみます。
v1で書かれたバックエンドのLambdaコード(Node.js)は以下のとおりです。

'use strict';
const Alexa = require('alexa-sdk');

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

const handlers = {
  'LaunchRequest': function () {
    const speech = 'はじめまして!こんにちは、と言ってください。'
    this.emit(':ask', speech, speech);
  },
  'HelloIntent': function () {
    this.emit(':tell', 'こんにちは');
  },
  'AMAZON.HelpIntent': function () {
    const speech = 'これは、挨拶するだけのスキルです。こんにちは、と言ってください。'
    this.emit(':ask', speech, speech);
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', 'さようなら');
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', 'スキルを終わります');
  }
};

上記のコードを、v1アダプターを使って一部v2へ移行してみます。

ask sdkとv1アダプターのインストール

インストールはnpmコマンドで行います。Lambdaへアップロードする際にzipに含めるのを忘れずに。

$ npm install --save ask-sdk
$ npm install --save ask-sdk-v1adapter

alexa sdk → v1アダプターへの変更

v1のコードでインポートされているalexa-sdkask-sdk-v1adapterへ変更します。
v1アダプターはロジックを解釈して、v2のskillインスタンスを生成します。

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

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

v2のリクエストハンドラへ移行

一部移行するということで、HelloIntentをv2のリクエストハンドラHelloIntentHandlerに置き換えてみます。

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

exports.handler = function (event, context, callback) {
  const alexa = Alexa.handler(event, context);
  alexa.registerHandlers(handlers);
  alexa.registerV2Handlers(HelloIntentHandler);
  alexa.execute();
};

const handlers = {
  'LaunchRequest': function () {
    const speech = 'はじめまして!こんにちは、と言ってください。'
    this.emit(':ask', speech, speech);
  },
  /*
  'HelloIntent': function () {
    this.emit(':tell', 'こんにちは');
  },
  */
  'AMAZON.HelpIntent': function () {
    const speech = 'これは、挨拶するだけのスキルです。こんにちは、と言ってください。'
    this.emit(':ask', speech, speech);
  },
  'AMAZON.CancelIntent': function () {
    this.emit(':tell', 'さようなら');
  },
  'AMAZON.StopIntent': function () {
    this.emit(':tell', 'スキルを終わります');
  }
};

const HelloIntentHandler = {
  canHandle: function ({ requestEnvelope }) {
    return requestEnvelope.request.type === 'IntentRequest'
      && requestEnvelope.request.intent.name === 'HelloIntent';
  },
  handle: function ({ responseBuilder }) {
    return responseBuilder.speak('こんにちは')
      .getResponse();
  },
};

34〜43行目でHelloIntentHandlerを定義し、8行目のalexa.registerV2Handlersにてv2のハンドラを追加しています。
このとき、v1で定義していた移行元ハンドラのコード(17〜21行目)は削除しておく必要があります。

スキルを実行

修正されたコードにてスキルをテストしてみると、v1とv2で書いた処理がそれぞれ問題なく動作することを確認できました。

おわりに

ASK SDK v1アダプターを使うことで、v1で書かれたコードを一部v2へ移行することができました。
バックエンドのコード量が多いようなスキルの場合でも、一部のハンドラから徐々にv2への移行を行う、ということが可能となります。

但し、v1とv2を共存させるとコードの見通しは悪くなる可能性があり、中途半端な状態で放置するのはオススメできません。
いきなりv1アダプターを使って移行を進める前に、どのような計画でv2へ移行するのか(そもそも移行したほうが良いのか)を検討してみてもよいかもしれません。
小規模なスキルな場合は、v1アダプターを使わず丸ごとv2で作り直してしまう、というのも選択肢の一つだと思います。

参考

【ASK SDK for Node.js-EN】ASK SDK Migration Guide