Tweet

2018年12月10日月曜日

【AmazonAlexaスキル開発】Responseオブジェクトについて考えてみる(ask,tellなど)

こういう人向け(for you)

  • 下記のコードの違いが分からない方
    • this.emit(':tell', outputSpeech)
    • this.emit(':responseReady');
  • ディスプレイ対応Alexaスキルで音声と画面出力が上手く行かない方。

はじめに、おことわり


当記事は[Alexa] Responseオブジェクトを利用した応答の作成を参考に作成してます。
元記事の解説が素敵なので多く引用しております。
一度読んでみる事もオススメします。

tellとaskの違いについて

処理的にはshouldEndSessionで返ってくるのがTRUE/FALSEかという違いがあります。
引用画像の赤字部分に相当します。

これはtellの処理です。

しかし分かりやすく噛み砕くと、

  • tell:ユーザーのレスポンスを待たない発話
  • ask:ユーザーのレスポンスを待つ場合に利用されていました。
      ユーザーが8秒間黙っていた場合、さらなるプロンプトを発話します。

みなさんは会話終了するか、ユーザーからの応答プロンプトを待つかで使い分けていたかと思います。

(特に審査を通るスキルに関してはここらへんが厳密に審査されています)


「tell」記述要項 と Responseオブジェクト記述



「ask」記述要項 と Responseオブジェクト記述



両方とも同じ内容で書けるなら、
なぜ使い分けが必要なのか。


ディスプレイ表示対応している時に、
this.emit(':responseReady');を使用せざるを得なくて、私は書き方を変えました。

ディスプレイ液晶対応アレクサスキルを考える時は、
レスポンスオブジェクトでの書き方を理解する必要があると思ってます。

【AmazonAlexaスキル開発】
Echo Spotなどのディスプレイ対応Alexa対応スキルの作り方 ask-sdk V1での作り方 http://iga34engineer.blogspot.com/2018/12/amazonalexaecho-spotalexa-ask-sdk-v1.html

試しに読んでみてね。

駄目な例

    'complaints': function () {

      let message = "";
      //Alexa対応デバイスのディスプレイの有無を判定している。
      if (supportsDisplay.call(this)) {
          const builder = new Alexa.templateBuilders.BodyTemplate1Builder();

          // ディスプレイディレクティブの作成
          let template = builder.setTitle('愚痴愚痴いうもん')
            .setBackgroundImage(makeImage('https://省略.jpg'))
            .setTextContent(makePlainText('あなたは何も悪くないから必要以上に悲しむのはやめるのよ。'))
            .build();

            message = "ディスプレイありと認識しております。"
            this.emit(':ask', message);
            this.response.renderTemplate(template);
      }else{
        //Alexaディスプレイなし機種の場合の分岐
        message = "ディスプレイなしと認識しております。"
      }
        this.response.speak(message);
        this.emit(':responseReady');
    }

上記のようにディスプレイ有り分岐で
this.emit(----)を2回通る場合などは正常に動作しません。

恐らくではありますが、this.emit(':ask', message);の時点でもうセッションが終了して、
それ以降の処理が行われていないんですよね。
いわゆるreturn的な処理と同一かと思っています。

なので、Alexaに発音させる為に、this.emit(':ask', message);だけを使うっていう選択肢は悪手なのです。

修正後


  const handlers = {
    'LaunchRequest': function () {//起動したとき
    const speechOutput= FIRST_MESSAGE;
    this.emit(":ask",speechOutput,HELP_REPROMPT);
    },
    //愚痴愚痴いうもん 唯一のインテント

    'complaints': function () {
      let message = "";
      //Alexa対応デバイスのディスプレイの有無を判定している。
      if (supportsDisplay.call(this)) {
          const builder = new Alexa.templateBuilders.BodyTemplate1Builder();
          // ディスプレイディレクティブの作成
          let template = builder.setTitle('愚痴愚痴いうもん')
            .setBackgroundImage(makeImage('https://省略語.jpg'))
            .setTextContent(makePlainText('あなたは何も悪くないから必要以上に悲しむのはやめるのよ。'))
            .build();

            message = "ディスプレイありと認識しております。"
            // this.emit(':tell', RESULT_DISPLAY_MESSAGE);
            this.response.renderTemplate(template);
      }else{
        message = "ディスプレイなしと認識しております。"
      }
        this.response.speak(message);
        this.emit(':responseReady');
    },

コードをちゃんと修正いたしました。
インテントの関数内で、this.emit('responseReady');が出てくる箇所をそもそも1箇所にして、
アレクサに発声させる文章は、let messageに代入するように書き換えてます。

これなら画面表示もさせつつ、音声で発生する事が可能になりました。

まとめ

  • tell、askを適切に理解して使う。
  • ディスプレイ対応も考えると、Responseオブジェクトを利用してもいいかも。
  • 書き方を自分の中で落とし込んで使えるようにする。

0 件のコメント:

コメントを投稿