0

I am using the same verify token but it's giving me error https://infinite-dusk-17985.herokuapp.com/webhook/ and neither it's responding when I m using it on messenger.

'use strict';

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

app.set('port', (process.env.PORT || 5000))

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

// parse application/json
app.use(bodyParser.json())

// index
app.get('/', function (req, res) {
    res.send('hello world i am a secret bot')
})

// for facebook verification
app.get('/webhook/', function (req, res) {
    if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
        res.send(req.query['hub.challenge'])
        res.send('Sucess, Challenge loop crossed')
    }
    res.send('Error, wrong token')
})

// to post data
app.post('/webhook/', function (req, res) {
    let messaging_events = req.body.entry[0].messaging
    for (let i = 0; i < messaging_events.length; i++) {
        let event = req.body.entry[0].messaging[i]
        let sender = event.sender.id
        if (event.message && event.message.text) {
            let text = event.message.text
            if (text === 'Generic') {
                sendGenericMessage(sender)
                continue
            }
            sendTextMessage(sender, "Text received, echo: " + text.substring(0, 200))
        }
        if (event.postback) {
            let text = JSON.stringify(event.postback)
            sendTextMessage(sender, "Postback received: "+text.substring(0, 200), token)
            continue
        }
    }
    res.sendStatus(200)
})


const token = "EAACKS5K1KvkBAASh07gKvgk9LvjCweLqKxKti1ZBzdzArNFPYNX9ZCx9tu35NNWquJZBuZCdZBLdsZBJAPFhvKgMZBDlazgofkbZAAeE6Hgv3gOh8jRd1W42AAZBIBd7EYNJsADepcpIgSlJEH9kHrup49oT5wZBHZBItnQwwDqr96z4wZDZD"

function sendTextMessage(sender, text) {
    let messageData = { text:text }

    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token:token},
        method: 'POST',
        json: {
            recipient: {id:sender},
            message: messageData,
        }
    }, function(error, response, body) {
        if (error) {
            console.log('Error sending messages: ', error)
        } else if (response.body.error) {
            console.log('Error: ', response.body.error)
        }
    })
}

function sendGenericMessage(sender) {
    let messageData = {
        "attachment": {
            "type": "template",
            "payload": {
                "template_type": "generic",
                "elements": [{
                    "title": "First card",
                    "subtitle": "Element #1 of an hscroll",
                    "image_url": "http://messengerdemo.parseapp.com/img/rift.png",
                    "buttons": [{
                        "type": "web_url",
                        "url": "https://www.messenger.com",
                        "title": "web url"
                    }, {
                        "type": "postback",
                        "title": "Postback",
                        "payload": "Payload for first element in a generic bubble",
                    }],
                }, {
                    "title": "Second card",
                    "subtitle": "Element #2 of an hscroll",
                    "image_url": "http://messengerdemo.parseapp.com/img/gearvr.png",
                    "buttons": [{
                        "type": "postback",
                        "title": "Postback",
                        "payload": "Payload for second element in a generic bubble",
                    }],
                }]
            }
        }
    }
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token:token},
        method: 'POST',
        json: {
            recipient: {id:sender},
            message: messageData,
        }
    }, function(error, response, body) {
        if (error) {
            console.log('Error sending messages: ', error)
        } else if (response.body.error) {
            console.log('Error: ', response.body.error)
        }
    })
}

// spin spin sugar
app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'))
})

Any help would be highly appreciated.

Vinoth Krishnan
  • 2,925
  • 6
  • 29
  • 34
Lovsingh
  • 1
  • 1

2 Answers2

0

Since you didn't share the error stack trace, I am not sure about the reason. But, there is an issue with your code.

For the following code snippet,

// for facebook verification
app.get('/webhook/', function (req, res) {
   if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
      res.send(req.query['hub.challenge'])
      res.send('Sucess, Challenge loop crossed')
   }
   res.send('Error, wrong token')
})

You would definitely be getting Error: Can't set headers after they are sent.

So, update the code with the following.

// for facebook verification
app.get('/webhook/', function (req, res) {
   if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
      res.send(req.query['hub.challenge'])
      console.log('Sucess, Challenge loop crossed')
   } else{ 
     res.send('Error, wrong token')
   }
})
Mukesh Sharma
  • 8,914
  • 8
  • 38
  • 55
0

Here is a working solution:

// my_server.js
'use strict';

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


const app = express();
app.set('port', process.env.PORT || 5000);
// parse application/json
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// spin spin sugar
app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'));
});

/* for facebook verification */
app.get('/webhook', function(req, res) {
  if (req.query['hub.verify_token'] === 'my_voice_is_my_password_verify_me') {
    console.log("Validating webhook");
    res.status(200).send(req.query['hub.challenge']);
  } else {
    console.error("Verification failed. Make sure the validation tokens match.");
    res.status(403).end();
  }
});

Few things to take note:

  • When you setup the webhook at developers.facebook.com, make sure the Verification Token you provide their is exactly the same string as found in the above code (i.e. 'my_voice_is_my_password_verify_me')
  • If you wish to change this token, make sure you update it at both places. This is Very Important
  • If you deploy this code to Heroku, process.env.PORT will be your port. A hardcoded port number might not work!
  • You will notice app.use(bodyParser.json()); is used here. This is because Facebook sends JSON data (payload) in the request body
  • Note that you can't write 2 res.send() statements it will give you error as mentioned by Mukesh. Once the headers are sent it can't be modified
  • Finally as a best practice, you can try to run it locally using npm run start or node my_server.js and ensure it has no errors like a missing node module & etc although you won't get a success response while running it locally
Hamzeen Hameem
  • 2,360
  • 1
  • 27
  • 28