You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lambda实现Alexa Skill调用REST API后返回空及speechOutput错误求助

问题排查与解决:speechOutput.trim is not a function 错误

你遇到的这个错误,核心原因是异步请求的回调逻辑没有正确返回Alexa响应,导致你的handle函数实际上没有返回任何有效内容,Alexa拿到的响应是空的,自然就会报speechOutput.trim is not a function(因为根本找不到speechOutput这个属性)。

具体分析你的代码问题:

你用的Request.get是典型的回调式异步方法,当你的handle函数执行到Request.get时,会立刻继续往下走,不会等待回调函数执行完毕。但你把响应构建代码return handlerInput.responseBuilder...写在了回调函数里——这个return只是回调函数的返回值,不是handle函数的返回值!所以handle函数最终返回的是undefined,Alexa接收不到合法的响应,就会抛出这个错误。

解决方案:改用异步/同步的方式处理请求

要解决这个问题,你需要把异步请求改成可以等待的形式,比如用async/await配合Promise化的请求方法。这里有两种常用的修改方式:

方式1:用util.promisify包装Request.get

Node.js内置的util模块可以把回调式的方法转换成Promise形式,这样就能用await等待请求完成:

const util = require('util');
const Request = require('request');
const getRequest = util.promisify(Request.get); // 包装成Promise

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    console.log("HelloWorldIntentHandler 1: ");
    return handlerInput.requestEnvelope.request.type === 'IntentRequest' && 
           handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  async handle(handlerInput) { // 标记为async函数
    console.log("HelloWorldIntentHandler 2");
    let speechText = 'Hello World';
    
    try {
      const response = await getRequest(url); // 等待请求完成
      const data = JSON.parse(response.body);
      const result = data.records.totalNum;
      
      if (result > 0) {
        speechText = `There are ${result} matches`;
      } else {
        speechText = "ERROR";
      }
    } catch (error) {
      // 处理请求错误,比如网络问题、API返回异常
      speechText = "Sorry, I couldn't get the data right now.";
      console.error('Request error:', error);
    }
    
    // 这里的return是handle函数的返回值,能正确传给Alexa
    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

方式2:改用支持Promise的请求库(比如axios)

如果你不想自己包装,直接用axios这类原生支持Promise的库会更简洁:

首先安装axios:

npm install axios

然后修改代码:

const axios = require('axios');

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    console.log("HelloWorldIntentHandler 1: ");
    return handlerInput.requestEnvelope.request.type === 'IntentRequest' && 
           handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  async handle(handlerInput) {
    console.log("HelloWorldIntentHandler 2");
    let speechText = 'Hello World';
    
    try {
      const response = await axios.get(url);
      const data = response.data;
      const result = data.records.totalNum;
      
      if (result > 0) {
        speechText = `There are ${result} matches`;
      } else {
        speechText = "ERROR";
      }
    } catch (error) {
      speechText = "Sorry, I couldn't get the data right now.";
      console.error('Request error:', error);
    }
    
    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

额外提示:

  • 一定要加上错误捕获(try/catch),避免因为API请求失败导致Skill崩溃;
  • 用模板字符串(`There are ${result} matches`)比字符串拼接更简洁易读;
  • 确认你的url变量已经正确定义,否则请求也会失败哦。

内容的提问来源于stack exchange,提问作者user1366265

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:07:26