alexa-appを使ってalexaカスタムスキルを作る(補足)


はじめに

alexa-appについての記事はExpress+alexa-appでlambdaを使わないでAlexa Skillを作るよの方が詳しいので、触れられていないところを補足する形で書いてみようと思います。

環境

  • NodeJS 10.7
  • express 4.16.0
  • alexa-app 4.2.3
  • heroku

インテントとは

インテントは会話の分類だと思ってください。

例として、上のように

  • 打率のnum位を指定して読み上げる「average」
  • 打率の成績を全部読み上げる「averageAll」
  • 打点の成績を全部読み上げる「rbiAll」
  • 防御率の成績を全部読み上げる「eraAll」

を用意します。

alexa-appでの実装

alexa.js
app.intent('average', { utterances: UTTERANCES.request.average }, averageResponse);
app.intent('averageAll', { utterances: UTTERANCES.request.average }, averageAllResponse);
app.intent('rbiAll', { utterances: UTTERANCES.request.average }, rbiAllResponse);
app.intent('eraAll', { utterances: UTTERANCES.request.average }, eraAllResponse);

app.intent()

  • 第一引数:developerコンソールで定義したインテントを設定します。
  • 第二引数:スキーマを定義するようです。(まだ調査が十分ではありません)
  • 第三引数:実行する関数を指定します。

インテントの設定例

「サンプル発話」で想定される呼びかけを設定します。

例:ユーザが「(ウェイクワード),打率全部」と話しかけたら先程のaverageAllResponseが実行されます。

インテントで値を受け取る

developerコンソールでの設定

打率のnum位を指定して成績を読み上げる、という処理で
numという数値をユーザの会話から取得するのにスロットという設定が必要となります。

スロットタイプが「AMAZON.NUMBER」のnumというスロットを作ると、サンプル発話の中に{num}と記述できるようになります。
このように設定すると、ユーザが「打率の8位は?」と尋ねると、averageインテントに該当する発話があったことと、8という数値をプログラムが取得できます。

アプリケーション側の実装

averageインテントの時にaverageResponseが発火します。スロットの値はreq.slots[設定したキーの名前].valueで取得できます。numと定義しましたね。

app.js
const averageResponse = (req, res) => {
  var num = req.slots['num'].value
  if(num <= 10){
    res.say(num+"位<break time='100ms'/>"+json['averageTop10'][num - 1]['name']+':'+json['averageTop10'][num - 1]['average']).shouldEndSession(false)
  }else{
    res.say("ごめんなさい。<break time='100ms'/>"+num+"は指定できません。<break time='100ms'/>10以下の順位を指定してください").shouldEndSession(false);
  }
}

SSML

さて、res.say()の中で見慣れないHTMLタグのようなものが出てきました。これはSSMLという音声読み上げにアクセントをつける言語です。HTMLのようにタグで文字列を囲んだり、小休止したいところにタグを入れます。

alexaカスタムスキル初心者がいくつかはまった点

herokuにデプロイするとエラー 'missing certificate url'

issueに上がっていました。

app.js
var app = express();
//----
//この間でapp.use()などを使ってはいけない
//----
alexa.express({
  expressApp: app,
  endpoint: '/alexa',
  checkCert: true
});

alexa.express()にはexpressのインスタンスをそのまま渡さないといけないようです。

実機テストでスキルが出てこない

開発したAlexa Skillが日本語版に出てこない場合
Alexa 開発者アカウントのハマりどころ

テストコンソールで2桁の数値が取れない?

これは情報が出てこなかったのですが、アプリケーション側で10以下の数値は許容しているものの、テストコンソールを使うと10以上の数値を取得できないという問題がありました。

JSON入力を見るとslots.num.valueというプロパティがないことがわかります。実機ではきちんと認識されました。