Бот Facebook Messenger в Node.js

1

Я пытаюсь обратиться к внешнему API, но каждый раз, когда я делаю запрос https или any kind, мой бот просто застывает.

Я попытался сделать API с помощью другого метода GET, но он просто застревает, когда я пытаюсь сделать вызов 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 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);
});
  • 0
    @PatrickHund при редактировании вопроса я по ошибке удалил код. Извиняюсь за неудобства. Но спасибо за вашу помощь.
  • 0
    Привет, @Sergiu Я разместил код.
Показать ещё 2 комментария
Теги:
facebook-messenger-bot

1 ответ

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 в URL-адресе, вы должны удалить его из этого сообщения, а также использовать его в переменной среды в коде, особенно если вы используете Git или что-то, чтобы хранить его не локально.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню