web-dev-qa-db-ja.com

Alexa Skillラムダ関数でSSMLを正しく指定するにはどうすればよいですか?

私はAlexaがSSMLでマークアップされた何かを言うAlexaスキルを作ろうとしています。この例を模倣しようとしました repo ですが、常に次のラムダ応答を受信して​​います。

{
  ...
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak> [object Object] </speak>"
    },
  ...
}

そしてAlexaは文字通り「オブジェクトオブジェクト」と言います。


これは私がラムダ関数に入力したものです(node.jsを使用):

var speechOutput = {
    type: "SSML",
    ssml: 'This <break time=\"0.3s\" /> is not working',
};

this.emit(':tellWithCard', speechOutput, SKILL_NAME, "ya best not repeat after me.")

このようにspeechOutputを設定することも機能しません:

var speechOutput = {
    type: "SSML",
    ssml: 'This <break time=\"0.3s\" /> is not working',
};

index.js

'厳密に使用';

var Alexa = require('Alexa-sdk');

var APP_ID = "MY_ID_HERE";
var SKILL_NAME = "MY_SKILL_NAME";

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

var handlers = {
    'LaunchRequest': function () {
        this.emit('Speaketh');
    },
    'MyIntent': function () {
        this.emit('Speaketh');
    },
    'Speaketh': function () {
        var speechOutput = {
            type: "SSML",
            ssml: 'This <break time=\"0.3s\" /> is not working',
        };

        this.emit(':tellWithCard', speechOutput, SKILL_NAME, "some text here")
    }
};

私がどこで間違っているのか誰かが知っていますか?

7
David Baker

response.jsのAlexa-sdkソースコード ごとに、GitHubでは、コード内のspeechOutputオブジェクトは文字列であると想定されています。 Response.jsは、コードで構築しようとしている応答オブジェクトの構築を担当します。

this.handler.response = buildSpeechletResponse({
    sessionAttributes: this.attributes,
    output: getSSMLResponse(speechOutput),
    shouldEndSession: true
});

さらに深く掘り下げると、 buildSpeechletResponse()createSpeechObject() を呼び出します。これは、Alexa SkillsKit応答でoutputSpeechオブジェクトを作成する直接の責任があります。

したがって、高度なSSML機能のない単純な応答の場合は、:tellの最初のパラメーターとして文字列を送信し、そこからAlexa-sdkに処理させます。


一時停止などの高度なssml機能については、 ssml-builder npmパッケージを見てください。これにより、SSMLパーサーを自分で実装またはハードコーディングしなくても、応答コンテンツをSSMLでラップできます。

使用例:

var speech = new Speech();

speech.say('This is a test response & works great!');
speech.pause('100ms');
speech.say('How can I help you?');    
var speechOutput = speech.ssml(true);        
this.emit(':ask', speechOutput , speechOutput); 

この例では、音声出力と再プロンプト音声の両方が同じ値に設定されている質問応答を出力します。 SSML Builderは、アンパサンド(SSMLでは無効な文字)を正しく解析し、2つのsayステートメントの間に100msの一時停止を挿入します。

応答例:

Alexa Skills Kitは、上記のコードに対して次の 応答オブジェクト を出力します。

{
  "outputSpeech": {
    "type": "SSML",
    "ssml": "<speak> This is a test response and works great! <break time='100ms'/> How can I help you? </speak>"
  },
  "shouldEndSession": false,
  "reprompt": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak> This is a test response and works great! <break time='100ms'/> How can I help you? </speak>"
    }
  }
}
5
Anthony Neace

これは古い質問ですが、最近同様の問題が発生し、追加の依存関係を必要としない回答で貢献したいと思いました。

前述のように、speechOutputは文字列であると想定しているため、Alexaが「オブジェクトオブジェクト」と言う理由は、代わりにjsonであるためです。

次のようにハンドラーを試してください

'Speaketh': function () {
    var speechOutput = 'This <break time="0.3s" /> should work';

    this.emit(':tellWithCard', speechOutput, SKILL_NAME, "some text here")
}

この応答を返します

{ 
  ...
  "response": {
    "outputSpeech": {
    "ssml": "<speak> This <break time=\"0.3s\" /> should work </speak>",
    "type": "SSML"
  },
  ...
}
5
Edwin

あなたはこのようにあなたのコードを書くことができます:

'BreakIntent':function(){
        var speechOutput = 'She is better known as <break time="3s" /> Champion';
        var reprompt = "How can I help?";
        this.response.speak(speechOutput);
        this.response.listen(reprompt);
        this.emit(":responseReady");
    },

私は同じ問題に直面していて、このようにコードを書くことで解決できました。

0
Shivanshu Garg