Search code examples
javascriptnode.jsexpressfacebook-messengerfacebook-messenger-bot

Declaring variable outside a function


sender_psid is declared inside the app.post function. Is there a way to declare it gobally so that the function calls at the bottom can access it?

Note: Declaring it outside the function wouldn't help, as webhook.event does not exist outside it.

/ Creates the endpoint for our webhook
app.post('/webhook', (req, res) => {

  let body = req.body;

  // Checks this is an event from a page subscription
  if (body.object === 'page') {

    // Iterates over each entry - there may be multiple if batched
    body.entry.forEach(function(entry) {

    // Gets the body of the webhook event
    let webhook_event = entry.messaging[0];
    console.log(webhook_event);


    // Get the sender PSID
    let sender_psid = webhook_event.sender.id;
    console.log('Sender PSID: ' + sender_psid);

    // Check if the event is a message or postback and
    // pass the event to the appropriate handler function
    if (webhook_event.message) {
      msg.handleMessage(sender_psid, webhook_event.message);
    } else if (webhook_event.postback) {
      msg.handlePostback(sender_psid, webhook_event.postback);
    }


  });

    // Returns a '200 OK' response to all requests
    res.status(200).send('EVENT_RECEIVED');
  } else {
    // Returns a '404 Not Found' if event is not from a page subscription
    res.sendStatus(404);
  }

});
//Imports functions from other files
let  msg = require('./msg.js'),
     handleMessage = msg.handleMessage(sender_psid, received_message),
     handlePostback = msg.handlePostback(sender_psid, received_postback),
     callSendAPI = msg.callSendAPI(sender_psid, response);

Solution

  • You NEVER want global variables that are request-specific in node.js servers. This just allows different requests to trounce the values that other requests are trying to use. If your request handlers have any asynchronous operations in them, this would be a form of concurrency bug or race condition. Do not do it. Do not try to do it. It's a bad design.

    Instead, you have these options:

    1. Pass any data from your request handler as a function argument to the external function.
    2. Add the data as a property to the req or res object (which is always request-specific) and then pass that req or res object to your external function so it can access the data there.
    3. Add the data as a property to some other object that you create specifically in that request handler and then pass that object to your external function so it can access the data there.

    If you are trying to create some data in a request handler that you then want access to in some future request handler, then you would either use a cookie or a session to be able to save that data and then get access to it in a future request from that same client.