Reputation: 491
When using the same Facebook getting started guide (https://developers.facebook.com/docs/messenger-platform/quickstart)
I am getting an error on the node.js console when typing a message and sending it to the bot.
{ error:
{ message: '(#100) No matching user found',
type: 'OAuthException',
code: 100,
fbtrace_id: 'BLguK1o+VsH' } } }
I have the latest version of node.js and am using Ngrok to expose my local host.
My app.post routine is below: (It is an exact copy of the getting started guide)
router.post('/webhook', function (req, res) {
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(pageEntry) {
var pageID = pageEntry.id;
var timeOfEvent = pageEntry.time;
// Iterate over each messaging event
pageEntry.messaging.forEach(function(messagingEvent) {
if (messagingEvent.optin) {
receivedAuthentication(messagingEvent);
} else if (messagingEvent.message) {
receivedMessage(messagingEvent);
} else if (messagingEvent.delivery) {
receivedDeliveryConfirmation(messagingEvent);
} else if (messagingEvent.postback) {
receivedPostback(messagingEvent);
} else {
console.log("Webhook received unknown messagingEvent: ", messagingEvent);
}
});
});
// 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.
// res.sendStatus(200);
}
});
Here is the receivedMessage function that is being called
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;
// You may get a text or attachment but not both
var messageText = message.text;
var messageAttachments = message.attachments;
if (messageText) {
// If we receive a text message, check to see if it matches any special
// keywords and send back the corresponding example. Otherwise, just echo
// the text we received.
switch (messageText) {
case 'image':
sendImageMessage(senderID);
break;
case 'button':
sendButtonMessage(senderID);
break;
case 'generic':
sendGenericMessage(senderID);
break;
case 'receipt':
sendReceiptMessage(senderID);
break;
default:
//getArticles(function(err,articles){
// sendTextMessage(senderID, articles[0].text);
//});
sendTextMessage(senderID, messageText);
/* client.converse('my-user-session-42', messageText, {})
.then((data) => {
console.log('the question asked :' + messageText);
sendTextMessage(senderID, data.msg);
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
}).catch(console.error);
*/
}
} else if (messageAttachments) {
sendTextMessage(senderID, "Message with attachment received");
}
}
Further more here are my require statements:
const bodyParser = require('body-parser');
var express = require('express');
var request = require('request');
var router = express.Router();
const fetch = require('node-fetch');
const {Wit, log} = require('node-wit');
Here is the rest of the functions used:
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: 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);
}
});
}
So I read somewhere that it all has to do with page ids or the way that facebook processes ints but I'm a little confused.
Any help would be much appreciated.
Upvotes: 12
Views: 19306
Reputation: 2488
for me I was trying to hit user API with these fields first_name,last_name,locale,gender,profile_pic,timezone
, I just removed profile_pic
and it worked, I started to use picture
field instead
Upvotes: 0
Reputation: 2809
I would like to share my experience. I was getting the same error when calling the v15.0/me/messages API.
I was using a test version of my app. When I started using my app directly, the error disappeared. It seemed, at least for my case, is that test apps do not look up users.
Upvotes: 1
Reputation: 29
i removed message echoes in events, and selected only messaging and postbacks, it solved the problem
Upvotes: 1
Reputation: 559
Make sure you have used correct ID of recipient. Recipient is not the page or app ID but it is (if you want to send message to the user) ID of the user.
You can configure webhook such as https://requestb.in and examine requests from messanger and the ID which you are looking for is:
{"sender":{"id":"1499894473423552"}}
Upvotes: 1
Reputation: 101
I went to Facebook Messenger Settings -> Webhooks -> Edit events and removed messenger_echoes from the subscribed events. This solved the issue.
Upvotes: 8
Reputation: 211
This error occurs because the incorrect token is being used to send messages back to the bot. Ensure you have the correct one (even by hard-coding it at first), which can be copied from your developers.facebook.com page under Messenger -> Settings -> Token Generation.
Upvotes: 21
Reputation: 1742
You just need to bypass your own messages.
Your Bot has an unique ID (it's not the App ID), so you can try this workaround in your POST logic:
var myID = '...' ;
.....
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text && sender != myID) {
.....
}
You can obtain your Bot id by reviewing your messages:
"sender":{
"id":"USER_ID"
},
JSON sample:
even.message:
{"sender":{"id":"**yourBotID**"},
"recipient":{"id":"**clientID**"},
"timestamp":1468241667962,
"message": {"**is_echo":true**,
"app_id":**appID**,
"mid":"mid....",
"seq":617,"text":"..."}}
Tip: to identify your BotID just look for "message": {"is_echo": true,.. in message payload.
Regards
Upvotes: 7
Reputation: 491
I followed this guide http://x-team.com/2016/04/how-to-get-started-with-facebook-messenger-bots/
and it all worked:
I have posted my code below:
'use strict'
const bodyParser = require('body-parser');
var express = require('express');
var request = require('request');
var app = express();
const fetch = require('node-fetch');
const {Wit, log} = require('node-wit');
app.use(bodyParser.urlencoded({extended: false}))
var PAGE_ACCESS_TOKEN = '********'
var MY_TOKEN = '********';
// Wit.ai code
const client = new Wit({accessToken: '*********'});
// GET home page.
app.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
app.get('/webhook/', function(req, res) {
if (req.query['hub.mode'] === 'subscribe' &&
req.query['hub.verify_token'] === 'hello_token_success') {
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);
}
});
//** Receive Messages **
app.post('/webhook/', function (req, res) {
var data = req.body;
var events = req.body.entry[0].messaging;
for (var i = 0; i < events.length ; i++) {
var event = events[i];
if (event.message && event.message.text && !event.message.is_echo) {
var text = event.message.text;
sendTextMessage(event.sender.id, "Text received, echo: "+ text.substring(0, 200));
}
}
// 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.
res.sendStatus(200);
});
function receivedMessage(event) {
var senderID = event.sender.id.toString();
var recipientID = event.recipient.id.toString();
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;
// You may get a text or attachment but not both
var messageText = message.text;
var messageAttachments = message.attachments;
if (messageText && !message.is_echo) {
// If we receive a text message, check to see if it matches any special
// keywords and send back the corresponding example. Otherwise, just echo
// the text we received.
switch (messageText) {
case 'image':
sendImageMessage(senderID);
break;
case 'button':
sendButtonMessage(senderID);
break;
case 'generic':
sendGenericMessage(senderID);
break;
case 'receipt':
sendReceiptMessage(senderID);
break;
default:
sendTextMessage(senderID, messageText);
}
} else if (messageAttachments) {
sendTextMessage(senderID, "Message with attachment received");
}
}
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 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");
}
function sendTextMessage(recipientId, messageText) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: messageText
}
};
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: 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);
}
});
}
module.exports = app;
Upvotes: 2