同じFacebook入門ガイドを使用する場合( https://developers.facebook.com/docs/messenger-platform/quickstart )
メッセージを入力してボットに送信すると、node.jsコンソールでエラーが発生します。
{ error:
{ message: '(#100) No matching user found',
type: 'OAuthException',
code: 100,
fbtrace_id: 'BLguK1o+VsH' } } }
Node.jsの最新バージョンを使用しており、Ngrokを使用してローカルホストを公開しています。
私のapp.postルーチンは以下のとおりです:(これはスタートガイドの正確なコピーです)
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);
}
});
これが呼び出されているreceivedMessage関数です
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");
}
}
さらにここに私のrequireステートメントがあります:
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');
使用される残りの関数は次のとおりです。
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);
}
});
}
だから私はどこかですべてがページIDまたはfacebookがintを処理する方法に関係しているとどこかで読んだが、私は少し混乱している。
どんな助けでも大歓迎です。
このエラーは、ボットにメッセージを送り返すために誤ったトークンが使用されているために発生します。正しいものがあることを確認してください(最初にハードコーディングした場合でも)。これは、developers.facebook.comページの[メッセンジャー]-> [設定]-> [トークンの生成]からコピーできます。
自分のメッセージをバイパスするだけです。
ボットには一意のID(アプリIDではない)があるため、この回避策をPOSTロジック:
var myID = '...' ;
.....
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text && sender != myID) {
.....
}
メッセージを確認することで、ボットIDを取得できます。
"sender":{
"id":"USER_ID"
},
JSONサンプル:
even.message:
{"sender":{"id":"**yourBotID**"},
"recipient":{"id":"**clientID**"},
"timestamp":1468241667962,
"message": {"**is_echo":true**,
"app_id":**appID**,
"mid":"mid....",
"seq":617,"text":"..."}}
ヒント:BotIDを特定するには、 "message":{"is_echo":true、..メッセージペイロード内。
よろしく
Facebookメッセンジャーの設定-> Webhook->イベントの編集に移動し、サブスクライブしたイベントからmessenger_echoesを削除しました。これで問題は解決しました。
私はこのガイドに従いました http://x-team.com/2016/04/how-to-get-started-with-facebook-messenger-bots/
そしてそれはすべてうまくいった:
以下にコードを投稿しました:
'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;
受信者の正しいIDを使用していることを確認してください。受信者はページやアプリのIDではありませんが、(ユーザーにメッセージを送信する場合は)ユーザーのIDです。
https://requestb.in などのWebhookを構成し、メッセンジャーからのリクエストを調べることができます。探しているIDは次のとおりです。
{"sender":{"id":"1499894473423552"}}
イベントのメッセージエコーを削除し、メッセージングとポストバックのみを選択すると、問題が解決しました