0

I changed my Facebook account's password, and the Facebook Messenger Bot I made can no longer respond to my messages.

This error comes up in my Heroku logs:

2016-12-28T22:19:32.647313+00:00 heroku[router]: at=info method=POST path="/webhook" host=messengerrainbot.herokuapp.com request_id=0a347c11-4d67-4dcf-ae3b-2b8d4cc55b8d fwd="66.220.156.117" dyno=web.1 connect=0ms service=3ms status=200 bytes=196
2016-12-28T22:19:32.749540+00:00 app[web.1]: Error:  { message: 'Error validating access token: The session has been invalidated because the user has changed the password.',
2016-12-28T22:19:32.749560+00:00 app[web.1]:   type: 'OAuthException',
2016-12-28T22:19:32.749561+00:00 app[web.1]:   code: 190,
2016-12-28T22:19:32.749562+00:00 app[web.1]:   error_subcode: 460,
2016-12-28T22:19:32.749563+00:00 app[web.1]:   fbtrace_id: 'FlCFAaxy8j3' }

I cannot find anywhere how to get a new session access token.

My index.js file controlling everything:

var express = require('express');
var bodyParser = require('body-parser');
var request = require('request');
var app = express();

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.listen((process.env.PORT || 3000));

// Server frontpage
app.get('/', function (req, res) {
  res.send('This is TestBot Server');
});

// Facebook Webhook
app.get('/webhook', function (req, res) {
  if (req.query['hub.verify_token'] === 'EAAWWpxUBMGoBANlKHUR63Dz2WLZBMHACQRi65zwj46wFSb3aJCThUV4BLwevZCciUDeyVnYpGcfgrzu0reh3XqKdTkZBxVA1HhIfrAhbQjsy5ABYfUFTbfAdck4QmH0vJV6ZCAgAcGdrBl3pMaTQa2eCrPetlsZBHXAjZBIuISOgZDZD') {
    res.send(req.query['hub.challenge']);
  } else {
    res.send('Invalid verify token');
  }
});

// handler receiving messages
app.post('/webhook', function (req, res) {
  var events = req.body.entry[0].messaging;
  for (i = 0; i < events.length; i++) {
    var event = events[i];
    if (event.message && event.message.text) {
      sendMessage(event.sender.id, {text: "Hi. Send your location"}); // event.message.text
    } else if (event.message && event.message.attachments && event.message.attachments[0] && event.message.attachments[0].payload && event.message.attachments[0].payload.coordinates) {
      urlBase = "http://api.wunderground.com/api/57fd25cc02e9da86/conditions/forecast/alert/q/"
      lat = event.message.attachments[0].payload.coordinates.lat
      lon = event.message.attachments[0].payload.coordinates.long
      totUrl = urlBase + String(lat) + "," + String(lon) + ".json"

      request({
        url: totUrl,
        json: true
      }, function (error, response, body) {

        if (!error && response.statusCode === 200) {
          var rain = body.current_observation.precip_1hr_metric
          if (rain > 0) {
            sendMessage(event.sender.id, {text: "It's gonna rain. Grab an umbrella!"});
          } else {
            sendMessage(event.sender.id, {text: "No rain ahead!"});
          }
        }
      })
    } 
    events = []
  }
  req.body.entry[0].messaging = []
  res.sendStatus(200);
});

// generic function sending messages
function sendMessage(recipientId, message) {
  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
    method: 'POST',
    json: {
      recipient: {id: recipientId},
      message: message,
    }
  }, function(error, response, body) {
    if (error) {
      console.log('Error sending message: ', error);
    } else if (response.body.error) {
      console.log('Error: ', response.body.error);
    }
  });
};

and a link to my full Github repo if needed

Pat Myron
  • 4,437
  • 2
  • 20
  • 39

1 Answers1

0

You can generate a new access token in your application:

Andrés Andrade
  • 2,213
  • 2
  • 18
  • 23
  • I don't believe this is the right token. I think that token is for Facebook communicating with the Node server. I think I need to establish a new session with this one particular Facebook user (happens to be me) to get permission to send them messages back. It would seem ridiculous to me to have to change that token manually every time any user of your bot changed their password. – Pat Myron Dec 29 '16 at 00:23
  • 1
    @PatMyron You don't need a user access token since you are using your page to send the message and you are not accessing user data. To use the endpoint `https://graph.facebook.com/v2.6/me/messages?access_token=` you need a page access token: https://developers.facebook.com/docs/messenger-platform/send-api-reference. You can check all token types and how to generate them here: https://developers.facebook.com/docs/facebook-login/access-tokens – Andrés Andrade Dec 29 '16 at 01:00
  • I do think this PA‌​GE_ACCESS_TOKEN is the token that expired due to a password change. I'll look into both of those links. – Pat Myron Dec 29 '16 at 01:12
  • 1
    @PatMyron Exactly, maybe because you are the owner of the page or the application but it shouldn't expire. It seems like a issue with the API. Generating a new Page token from your app should fix it. – Andrés Andrade Dec 29 '16 at 13:31
  • I tried generating a new page token and now I get the error: `Error: { message: 'Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.', type: 'OAuthException', code: 190, error_subcode: 460, fbtrace_id: 'GNwl/a0rEcB' }` – Pat Myron Dec 29 '16 at 19:17
  • 1
    @PatMyron It seems like the user lost your app authorization. Here you can find your scenario and the code the get an access token at the end of the page: https://developers.facebook.com/blog/post/2011/05/13/how-to--handle-expired-access-tokens/ – Andrés Andrade Dec 29 '16 at 19:43
  • While I do think that article is probably addressing the same problem, I'm not sure how to translate the PHP solution for a webpage into a Node solution for a Facebook Messenger bot. – Pat Myron Jan 04 '17 at 19:10