如何让Alexa Intent handler每次调用返回不同响应 基于ASK node.js SDK
解决方案
不需要编写多个Intent Handler,所有逻辑都可以在同一个MyGameIntentHandler中完成,核心依赖两个能力:
- 会话属性(Session Attributes)存储当前游戏的进度(当前数到的数字)
.listen()确实会保持会话开启,用户后续输入匹配MyGameIntent时会重新触发同一个Handler
前置配置
先去Alexa Developer Console的交互模型里给MyGameIntent做如下配置:
- 添加一个槽位,类型选
AMAZON.NUMBER,槽位名设为userNumber - 添加示例utterance:
{userNumber}、我接{userNumber}、是{userNumber},覆盖用户说数字的常用说法,构建并部署模型。
修改后的代码示例
const MyGameIntentHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' && Alexa.getIntentName(handlerInput.requestEnvelope) === 'MyGameIntent'; }, handle(handlerInput) { // 获取session属性,存储当前数到的数字 const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); // 从槽位读取用户输入的数字 const userInputNum = Alexa.getSlotValue(handlerInput.requestEnvelope, 'userNumber'); let speechText = ''; let shouldListen = true; // 第一次触发游戏,session中无currentNumber,走初始化逻辑 if (!sessionAttributes.currentNumber) { sessionAttributes.currentNumber = 1; speechText = 'One'; } else { const expectedNum = sessionAttributes.currentNumber + 1; // 校验用户输入是否符合预期 if (parseInt(userInputNum) === expectedNum) { // 输入正确,更新当前数字为Alexa要报的下一个数 sessionAttributes.currentNumber = expectedNum + 1; speechText = sessionAttributes.currentNumber.toString(); } else { // 输入错误,结束游戏 speechText = 'Game over'; shouldListen = false; } } // 保存更新后的session属性 handlerInput.attributesManager.setSessionAttributes(sessionAttributes); // 构建返回结果 const responseBuilder = handlerInput.responseBuilder.speak(speechText); if (shouldListen) { responseBuilder.listen(); } return responseBuilder.getResponse(); } };
逻辑说明
- 第一次用户触发开始游戏时,session属性里没有
currentNumber,走初始化逻辑,Alexa返回1,同时把1存入session属性,调用.listen()等待用户输入。 - 用户说出数字后,请求会再次触发这个Handler,代码从槽位取出用户输入的数字,和预期值(当前数字+1)对比:
- 匹配的话更新当前数字为下一个Alexa要报的数,返回对应数字继续等待用户输入
- 不匹配的话返回Game Over,不调用
.listen(),会话直接结束
内容的提问来源于stack exchange,提问作者Callum Reid
相关产品推荐
相关产品推荐

