Alexa Skill Node.js:音频播放结束触发意图及循环播放流程问题
解决Alexa Skill音频播放后触发后续交互的问题
看起来你是想做一个类健身流程的Skill:播放90秒以上的长音频片段,结束后询问用户是否继续,用户同意就播放下一段,循环这个过程对吧?核心问题是现在音频结束后没法触发后续的WORKOUT意图交互,我来给你拆解下关键步骤和代码示例:
1. 核心:监听AudioPlayer的PlaybackFinished事件
Alexa的长音频播放(超过90秒必须用AudioPlayer接口)结束后,会主动发送PlaybackFinished事件给你的Skill,这才是触发后续询问的关键——不是直接调用WORKOUT意图,而是通过这个事件返回交互提示,引导用户触发意图。
代码示例(Node.js ASK SDK v2)
首先注册专门的PlaybackFinished事件处理器:
const PlaybackFinishedRequestHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'AudioPlayer.PlaybackFinished'; }, handle(handlerInput) { // 音频播放结束,向用户发起询问 const speakOutput = '当前音频播放完毕,你准备好播放下一段了吗?'; const repromptOutput = '请告诉我你的选择,比如“是的”或者播放下一段。'; return handlerInput.responseBuilder .speak(speakOutput) .reprompt(repromptOutput) // 必须加这个,保持会话不关闭 .getResponse(); } };
然后把这个处理器添加到Skill的请求处理链中:
exports.handler = Alexa.SkillBuilders.custom() .addRequestHandlers( LaunchRequestHandler, // 你的启动意图处理器 WorkoutIntentHandler, // 自定义的WORKOUT意图处理器 PlaybackFinishedRequestHandler, // 添加上这个事件处理器 AMAZON.YesIntentHandler, // 内置的同意意图(可选,用来触发继续) AMAZON.NoIntentHandler // 内置的拒绝意图(可选) ) .lambda();
2. 处理用户的继续请求(WORKOUT/Yes意图)
当用户说“播放下一段”触发WORKOUT意图,或者说“是的”触发内置YesIntent时,你需要用AudioPlayer接口播放新的音频片段:
const WorkoutIntentHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' && Alexa.getIntentName(handlerInput.requestEnvelope) === 'WORKOUT'; }, handle(handlerInput) { // 替换成你的下一段音频URL const nextAudioUrl = 'https://your-audio-host.com/next-session.mp3'; return handlerInput.responseBuilder .addAudioPlayerPlayDirective('REPLACE_ALL', nextAudioUrl, nextAudioUrl, 0, null) .getResponse(); } }; // 如果你想用内置YesIntent触发继续,可以复用上面的逻辑 const YesIntentHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' && Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.YesIntent'; }, handle(handlerInput) { return WorkoutIntentHandler.handle(handlerInput); } };
3. 关键注意事项
- 必须用AudioPlayer接口:长音频(超过90秒)不能用
speak()播放,否则会被Alexa强制截断,必须使用addAudioPlayerPlayDirective。 - 保持会话活跃:在
PlaybackFinished的响应中必须添加reprompt(),否则会话会自动关闭,用户后续的语音请求无法被Skill接收。 - 交互模型配置:确保你的Skill控制台里已经完成这些配置:
- 在「Interfaces」中开启AudioPlayer功能
- 添加内置意图
AMAZON.YesIntent、AMAZON.NoIntent(如果需要用这些触发交互) - 确认自定义的
WORKOUT意图已经正确配置样本 utterance
为什么之前的代码不工作?
大概率是你没有正确监听PlaybackFinished事件,或者在事件处理时没有返回带speak和reprompt的响应,导致会话直接关闭,用户的后续请求无法被Skill捕获。另外要注意:Skill不能主动“调用”意图,只能通过返回提示引导用户主动触发对应的意图。
内容的提问来源于stack exchange,提问作者DoesData
相关产品推荐
相关产品推荐

