如何在AWS Lambda(Node.js)中控制Lex聊天Bot请求处理顺序
解决AWS Lex + Facebook机器人先显示快速回复的问题
我完全懂你的困扰——Node.js的异步特性让两个Facebook API请求并行执行,导致快速回复的消息先到Facebook,用户看到的顺序就反了。要搞定这个问题,核心就是让发送快速回复的请求,等第一个请求的所有逻辑完成后再触发。
问题根源
你当前的代码里,request(options)(获取用户数据并返回confirmIntent响应)和request(options_2)(发送快速回复)是同时发起的,没有等待关系。Node.js会同时处理这两个异步请求,谁先完成全看网络延迟,自然就出现了顺序混乱的情况。
解决方案
把发送快速回复的请求,嵌套到第一个请求的回调函数内部,并且放在callback(confirmIntent...)之后执行。这样就能严格保证执行顺序:
- 先获取Facebook用户数据
- 先让Lex返回confirmIntent的问候消息给用户
- 最后再发送快速回复消息
修改后的完整代码如下:
function greeting(intentRequest, callback) { const hello = intentRequest.currentIntent.slots.Hello; const sessionAttributes = intentRequest.sessionAttributes || {}; const confirmationStatus = intentRequest.currentIntent.confirmationStatus; var params = null; var options = { uri: 'https://graph.facebook.com/v2.6/'+PSID+'?fields=first_name,last_name,gender&access_token='+process.env.FB_access_token, method: 'GET', headers: { 'Content-Type': 'application/json' } }; var options_2 = { uri: 'https://graph.facebook.com/v2.6/me/messages?access_token='+process.env.FB_access_token, body: JSON.stringify({ recipient: {"id":PSID}, message: { text: "Here is a quick reply!", quick_replies: [ { content_type: "text", title: "Search", payload: "yes", image_url: "http://example.com/img/red.png" }, { content_type: "location" } ] } }), method: 'POST', headers: { 'Content-Type': 'application/json' } }; /*request 1 - Get FB user data*/ request(options, function (error, response, body) { // 新增错误处理,避免请求失败时无响应 if (error) { console.error('获取用户数据失败:', error); return callback(close(sessionAttributes, 'Fulfilled', { contentType: 'PlainText', content: '抱歉,出了点小问题,请稍后再试。' })); } console.log(response.body); body = JSON.parse(body); params = { first_name: body['first_name'], }; // 先返回confirmIntent响应给Lex,由Lex发送问候消息给用户 callback(confirmIntent(sessionAttributes, 'GetStarted', { Age: null, }, { contentType: 'PlainText', content: 'Hi ' +params.first_name+ ', I will guide you through a series of questions to select your own customized product. Are you ready to start?' })); // 确认问候消息发出后,再发送快速回复 request(options_2, function (error, response) { if (error) { console.error('发送快速回复失败:', error); } else { console.log('快速回复发送成功:', response.body); } }); }); }
额外小贴士
- 我在代码里加了基础的错误捕获,避免请求失败时程序卡住;你可以根据需求扩展错误处理逻辑
- 虽然你用的是Node.js 8.1,也支持Promise语法,建议你把
request换成request-promise这类基于Promise的库,用async/await写异步代码,可读性和维护性会更好
内容的提问来源于stack exchange,提问作者Rohan Jain
相关产品推荐
相关产品推荐

