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

基于AWS Lambda的Alexa意图调用Yummly API异步函数问题

搞定Alexa + Lambda + Yummly API的食谱推荐(给Python开发者的JS指南)

嘿,作为经常折腾Alexa技能和第三方API的开发者,我太懂从Python转JavaScript的别扭感了!我来帮你把这段RecommendationIntent的代码补全,并且解释清楚关键步骤~

先看你现有代码的作用

你已经写了槽位收集的核心逻辑,这段代码是让Alexa自动引导用户补全所有必填的槽位信息(比如食材、菜系、饮食限制),收集完成后会打印槽位内容,但还缺调用Yummly API和把结果返回给Alexa的核心环节。先把你给出的代码片段格式化一下:

"RecommendationIntent": function () { 
  // delegate to Alexa to collect all the required slots 
  let filledSlots = delegateSlotCollection.call(this); 
  if (!filledSlots) { 
    return; 
  } 
  console.log("filled slots: " + JSON.stringify(filledSlots));
  // 这里就是要加API调用和结果返回的地方
}

补全完整代码步骤

1. 初始化Yummly客户端

首先要确保你已经安装了ws-yummly库,本地运行npm install ws-yummly(之后打包Lambda要带上node_modules文件夹),然后在代码顶部引入并初始化:

const Yummly = require('ws-yummly');
// 替换成你在Yummly开发者平台申请的App ID和Key
const yummlyClient = new Yummly({
  app_id: '你的YUMMLY_APP_ID',
  app_key: '你的YUMMLY_API_KEY'
});

2. 完善Intent逻辑

这里我提供两种写法:一种是JS传统的Promise链式调用,另一种是更接近Pythonasync/await的写法,你可以选更顺手的:

写法一:Promise链式调用

"RecommendationIntent": function () { 
  // 收集槽位
  let filledSlots = delegateSlotCollection.call(this); 
  if (!filledSlots) { 
    return; 
  } 
  console.log("filled slots: " + JSON.stringify(filledSlots));

  // 从槽位提取搜索参数(根据你在Alexa控制台配置的槽位名称调整)
  const searchParams = {
    q: filledSlots.Ingredient.value, // 用户说的食材,比如"鸡肉"
    allowedCuisine: { 'cuisine': [filledSlots.Cuisine.value] }, // 比如"中式"
    allowedDiet: { 'diet': [filledSlots.DietaryRestriction.value] } // 比如"素食"
  };

  // 调用Yummly搜索API
  yummlyClient.search(searchParams)
    .then(apiResponse => {
      // 处理返回结果,比如取前3个食谱
      const topRecipes = apiResponse.matches.slice(0, 3);
      // 构造给Alexa的语音回复
      let speechContent = "我给你推荐这几个食谱:";
      topRecipes.forEach((recipe, idx) => {
        speechContent += `第${idx+1}个是${recipe.recipeName},`;
      });
      // 调整语句更自然,去掉末尾逗号
      speechContent = speechContent.slice(0, -1) + "。";

      // 返回结果给用户,同时监听后续请求
      this.response.speak(speechContent).listen("还需要其他食谱推荐吗?");
      this.emit(':responseReady');
    })
    .catch(error => {
      // 处理API调用错误
      console.error("Yummly API调用失败:", error);
      this.response.speak("抱歉,现在无法获取食谱推荐,请稍后再试。");
      this.emit(':responseReady');
    });
}

写法二:Async/Await(更像Python的异步风格)

如果你习惯Python的async/await,可以把Intent改成异步函数,代码可读性更高:

"RecommendationIntent": async function () { 
  // 收集槽位
  let filledSlots = delegateSlotCollection.call(this); 
  if (!filledSlots) { 
    return; 
  } 
  console.log("filled slots: " + JSON.stringify(filledSlots));

  // 提取搜索参数
  const searchParams = {
    q: filledSlots.Ingredient.value,
    allowedCuisine: { 'cuisine': [filledSlots.Cuisine.value] },
    allowedDiet: { 'diet': [filledSlots.DietaryRestriction.value] }
  };

  try {
    // 等待API返回结果
    const apiResponse = await yummlyClient.search(searchParams);
    const topRecipes = apiResponse.matches.slice(0, 3);
    
    let speechContent = "我给你推荐这几个食谱:";
    topRecipes.forEach((recipe, idx) => {
      speechContent += `第${idx+1}个是${recipe.recipeName},`;
    });
    speechContent = speechContent.slice(0, -1) + "。";

    this.response.speak(speechContent).listen("还需要其他食谱推荐吗?");
    this.emit(':responseReady');
  } catch (error) {
    console.error("Yummly API调用失败:", error);
    this.response.speak("抱歉,现在无法获取食谱推荐,请稍后再试。");
    this.emit(':responseReady');
  }
}

给Python开发者的关键注意事项

  • Lambda打包:Lambda需要包含所有依赖,所以本地安装ws-yummly后,要把项目文件夹(包括node_modules)打包成ZIP文件上传到Lambda控制台。
  • 权限配置:确保你的Lambda执行角色有互联网访问权限(因为要调用Yummly的外部API),如果Lambda在VPC里,还需要配置NAT网关。
  • 槽位配置:在Alexa开发者控制台里,给槽位配置合适的类型(比如用内置的AMAZON.Cuisine类型识别菜系),这样Alexa能更准确理解用户的语音输入。
  • JS异步逻辑:JS的异步操作和Python差异很大,async/await是最接近Python异步写法的方式,建议优先用这种风格,减少回调地狱的困扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:42:05