如何在 Alexa Skill lambda 函数中正确指定 SSML?

Posted

技术标签:

【中文标题】如何在 Alexa Skill lambda 函数中正确指定 SSML?【英文标题】:How to correctly specify SSML in an Alexa Skill lambda function? 【发布时间】:2017-06-06 04:07:59 【问题描述】:

我正在尝试制作一个 Alexa 技能,让 Alexa 说出一些已用 SSML 标记的内容。我试图模仿这个repo 中的例子,但我总是收到一个 lambda 响应


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

Alexa 的字面意思是“object object”。


这是我输入到我的 lambda 函数的内容(使用 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.")

像这样设置语音输出也不起作用:

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")
    
;

有人知道我哪里出错了吗?

【问题讨论】:

您是否使用任何帮助程序来构建您的响应? 不完全确定你的意思,但我想我不是。 你是在使用模板还是一些示例 Alexa 技能? 哦,是的,我正在关注官方教程,现在似乎已经改变了......我已经更新了我的问题以包含我的源代码。 【参考方案1】:

根据 GitHub 上的 the alexa-sdk source code for response.js,您的代码中的 speechOutput 对象应为字符串。 Response.js 负责构建您尝试在代码中构建的响应对象:

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

深入挖掘,buildSpeechletResponse() 调用 createSpeechObject(),它直接负责在 Alexa Skills Kit 响应中创建 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 中是无效字符)并在两个 say 语句之间注入一个 100ms 的暂停。

示例响应:

Alexa Skills Kit 将为上面的代码发出以下response object:


  "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>"
    
  

【讨论】:

【参考方案2】:

这是一个老问题,但我最近遇到了类似的问题,并希望提供一个不需要额外依赖项的答案。

如前所述,speechOutput 假设是一个字符串,所以 alexa 说“object object”的原因是因为它是一个 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"
  ,
  ...

【讨论】:

谢谢,效果很好,没有额外的依赖【参考方案3】:

你可以这样写你的代码:

'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");
    ,

我遇到了同样的问题,可以通过这种方式编写代码来解决。

【讨论】:

以上是关于如何在 Alexa Skill lambda 函数中正确指定 SSML?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从 Alexa Smart Home Skill Directive 收到的 BearerToken 来识别使用 AWS Lambda 和 NodeJS 的用户电子邮件和个人资料?

使用 Alexa Skill 连接到 Postgresql

Alexa Skill - 如何获取要求 Alexa 的完整声明文本

如何在 Alexa Skill 中使用 Java 获取亚马逊用户电子邮件

在“认证”期间如何继续开发我的 Alexa Skill?

如何从 Alexa Lambda 函数调用 Web 服务