Node.js中的Facebook Messenger bot

时间:2017-10-20 07:03:21

标签: javascript node.js facebook-messenger-bot

我正在尝试调用外部API,但每次我发出https或任何类型的请求时,我的机器人都会被冻结。

我尝试使用不同的GET方法制作API,但每当我尝试进行API调用时它就会卡住。

[在此处输入图像说明] [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://messengerdemo.parseapp.com/img/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://messengerdemo.parseapp.com/img/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);
});

1 个答案:

答案 0 :(得分:2)

错误出现在代码的这一部分:

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

});

function(response {...}是一个异步调用,这意味着它会在API返回响应时运行,而不是在前一行之后立即运行。这意味着当你到达

callSendAPI(messageData);

变量messageData未必已启动,因此它不会像您希望的那样运行。为避免这种情况,您需要在知道messageData已初始化后通过将其移至此处来调用该函数:

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

另一个提示:如果这是您在网址中的真实API密钥,则应将其从此帖子中删除,并在代码中删除use it in an environment variable,特别是如果您正在使用Git或其他内容非本地存储。