AlexaのInteraction Modelを元にLambdaの雛形を作ってくれる「skillinator.io」を試してみた。

2018.05.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

風薫る季節, 風薫る五月がやってまいりました。お元気でしょうか、せーのです。
今日は手頃なスキルをサクッと開発したい時に便利な「Skillinator.io」というツールをご紹介します。このツールを使うと、所謂Lambdaの"Blueprint"的な感じでIntent回りのコードを出力してくれるのです。

はじめの一歩がめんどくさいあなたへ

スキルを開発しよう、と思ったらまず何をするでしょう。こう聞かれたらこう返そう、というような会話のやり取りを設計しますね。これを「VUI(Voice User Interface)設計」と言います。

開発者コンソールでは主にユーザー側のセリフを「サンプル発話」という形でIntentに変換するよう設計します。
一方Alexaからの返答はLambda側でレスポンスとして実装します。 開発者コンソールはGUIがきっちり整っているので、それに基いてサクサク埋めていけばできるのですが、LambdaはAlexaのためだけにあるのではないので、イチからすべて書いていく必要があります。
それがめんどくさいので、大抵の場合は"BluePrint"からAlexaの雛形を探し、そこのIntentの部分やResourceの部分をちょこちょこ書き換えて作ります。でも書きたいIntentと雛形のIntentは数も違うので、結構手間なんですよね。

そんな時にこの「Skillinator.io」が便利なんです。このツールは開発者コンソールで作ったInteraction Modelを貼り付けてやるだけで、いい感じのLambdaの雛形を作ってくれるのです。

やってみた

ではやってみます。 まずは開発者コンソールで簡単なスキルを組み立ててみます。

HelloWorldIntentがあるだけで、あとはStop,Cancel,Helpと言ったデフォルトで設定されているIntentだけの構成です。

ここからモデルを保存、ビルドし、左ペインの「JSONエディター」というところを開くと、ここで設定したモデルがJSONの形で表示されます。

これをコピーして、Skillinator.io にアクセスして左側にペーストします。

あとは右上にあるGenerateボタンを押すだけ。少し待つと右側にLambdaの雛形が現れます。

簡単ですね!
少し中身を見てみましょう。

const Alexa = require('alexa-sdk');
const APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).
speechOutput = '';
const handlers = {
  'LaunchRequest': function () {
    this.emit(':ask', welcomeOutput, welcomeReprompt);
  },
  'AMAZON.HelpIntent': function () {
    speechOutput = 'Placeholder response for AMAZON.HelpIntent.';
    reprompt = '';
    this.emit(':ask', speechOutput, reprompt);
  },
   'AMAZON.CancelIntent': function () {
    speechOutput = 'Placeholder response for AMAZON.CancelIntent';
    this.emit(':tell', speechOutput);
  },
   'AMAZON.StopIntent': function () {
    speechOutput = 'Placeholder response for AMAZON.StopIntent.';
    this.emit(':tell', speechOutput);
   },
   'SessionEndedRequest': function () {
    speechOutput = '';
    //this.emit(':saveState', true);//uncomment to save attributes to db on session end
    this.emit(':tell', speechOutput);
   },
  'HelloWorldIntent': function () {
    speechOutput = '';

    //any intent slot variables are listed here for convenience


    //Your custom intent handling goes here
    speechOutput = "This is a place holder response for the intent named HelloWorldIntent. This intent has no slots. Anything else?";
    this.emit(":ask", speechOutput, speechOutput);
    },  
  'Unhandled': function () {
        speechOutput = "The skill didn't quite understand what you wanted.  Do you want to try something else?";
        this.emit(':ask', speechOutput, speechOutput);
    }
};

AppIDなどの固定値を入れる変数と、ハンドラーが書かれています。CancelとStopはtellで、Helpはaskで書かれている辺りも大元のBluePrintに合わせてある感じですね。

exports.handler = (event, context) => {
    const alexa = Alexa.handler(event, context);
    alexa.appId = APP_ID;
    // To enable string internationalization (i18n) features, set a resources object.
    //alexa.resources = languageStrings;
    alexa.registerHandlers(handlers);
  //alexa.dynamoDBTableName = 'DYNAMODB_TABLE_NAME'; //uncomment this line to save attributes to DB
    alexa.execute();
};

ハンドラーの登録部です。セッションの恒久化はデフォルトではコメントアウトされていますね。

==================================
// 3. Helper Function  =================================================================================================

function resolveCanonical(slot){
  //this function looks at the entity resolution part of request and returns the slot value if a synonyms is provided
  let canonical;
    try{
    canonical = slot.resolutions.resolutionsPerAuthority[0].values[0].value.name;
  }catch(err){
      console.log(err.message);
      canonical = slot.value;
  };
  return canonical;
};

ここからはよく使う処理がヘルパー関数として既に定義されていました。例えばこれはシノニムを使った時に値を取り出す関数ですね。他にもダイアログモデルでのDelegate処理や、フレーズをランダムで選んでくれる関数など、かゆい所に手が届く感じになっています。これは便利ですね。

まとめ

いかがでしたでしょうか。最初のテンプレ作成としては中々使いやすいツールだと思います。
ちなみにこのツールは開発も盛んで、先日発表になったAlexa-SDK V2にもベータ版として開発が進んでいるようです
みなさんもスキル開発の手助けにぜひ使って見て下さい。