[英]Facebook Messenger bot not sending messages in order
我正在尝试构建一个简单的 Facebook Messenger 聊天机器人,但无法按顺序发送消息。
在上面的例子中,它应该按顺序打印“Hello!”、“1”、“2”、“3”。 我目前正在关注此处找到的 Facebook 文档以实现这个简单的短信功能。 我在下面包含了我的 Express Node.JS 服务器代码:
定义sendTextMessage()
函数:
var request = require("request");
function sendTextMessage(user, text) {
messageData = {
text: text
};
request({
url: "https://graph.facebook.com/v2.6/me/messages",
qs: {access_token: PAGE_ACCESS_TOKEN},
method: "POST",
json: {
recipient: {id: user},
message: messageData
}
}, function(error, response, body) {
if (error) {
console.log("Error sending message: ", error);
} else if (response.body.error) {
console.log("Error: ", response.body.error);
} else {
console.log("Message successfully send.")
}
});
}
使用它来发送响应:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
我什至尝试实现一个简单的队列,该队列对消息进行排队,并且在每个request
的成功回调后一次只发送一条消息。 这让我怀疑我没有正确地与 Messenger API 交互。
有没有人遇到过这个问题? 如何让消息按顺序发送? 谢谢!
因为我实现了一个简单的队列但仍然遇到这个问题,所以我在这里包含了我的简单队列系统的代码。
var queue = [];
var queueProcessing = false;
function queueRequest(request) {
queue.push(request);
if (queueProcessing) {
return;
}
queueProcessing = true;
processQueue();
}
function processQueue() {
if (queue.length == 0) {
queueProcessing = false;
return;
}
var currentRequest = queue.shift();
request(currentRequest, function(error, response, body) {
if (error || response.body.error) {
console.log("Error sending messages!");
}
processQueue();
});
}
queueRequest(/* Message 1 */);
queueRequest(/* Message 2 */);
queueRequest(/* Message 3 */);
这个“错误”已报告给 Facebook,但听起来他们不会修复它。 请在此处阅读 Facebook 帖子上的票务主题,了解有关他们所说内容的详细信息。 (感谢 Louise 引起 Facebook 对此的关注)
我向 Facebook 提交了一份关于此的错误报告,因为我遇到了同样的问题。 他们承认这确实是一个错误并正在努力修复它: https : //developers.facebook.com/bugs/565416400306038
在您向 /me/messages 发送 POST 后,您将收到一个带有消息 ID 的响应(我的以“mid”开头。这可能代表消息 ID?):
{ recipient_id: '1015411228555555',
message_id: 'mid.1464375085492:b9606c00ca33c12345' }
在被 FB Messenger API 完全接收后,您将收到一个对您的 webhook 的调用(没有消息事件)以确认接收:
{ sender: { id: '1015411228555555' },
recipient: { id: '566031806XXXXXX' },
delivery:
{ mids: [ 'mid.1464375085492:b9606c00ca33c12345' ],
watermark: 1464375085604,
seq: 176 } }
我认为送达回执是保证送达的最佳方式,然后发送下一条消息。
我将创建一个队列数据结构,而不是添加静态超时。 当机器人想要发送消息时,将内容附加到队列的末尾。 在消息发布回调中,检查队列中是否还有消息,并使用递归再次调用该函数并相应地从队列中删除。
将发送请求实现为一个 Promise,并且只有在前一个被解决后才发送后续消息
const send = (userId, messageData) => {
return new Promise((resolve, reject) => {
request
(
{
url : BASE_URL + "me/messages",
qs : { access_token : PAGE_ACCESS_TOKEN },
method : "POST",
json :
{
recipient: { id : userId },
message: messageData,
}
}, (error, response, body) =>
{
if (error) { console.log("Error sending message: " + response.error); return reject(response.error); }
else if (response.body.error) { console.log('Response body Error: ' + response.body.error); return reject(response.body.error); }
console.log("Message sent successfully to " + userId);
return resolve(response);
}
);
});
};
您可以通过承诺实现QUEUING
。
function delay(time) { return new Promise(function(resolve, reject) { setTimeout(resolve, time); }); } delay(2000).then(() => { console.log('hi'); delay(2000).then(() => { console.log('hello'); delay(2000).then(() => { console.log('welcome'); }) }) })
它们应该按照发送的顺序接收。 确保您实际上是按顺序发送它们并且没有调用异步函数 4 次(并且不能保证发送顺序)。 (我读到您已经对其进行了测试,但在我所有的测试中,如果保证发送顺序,我从未见过接收出现乱序。)
我向应用程序添加了一个 messageId 计数器,该计数器在每次开始处理消息时重置为 0。 然后我用那个数字 * 100 毫秒延迟。 通过这种方式,我也可以使用messageDelay += 15
类的代码添加有意的延迟
receivedMessage(event) {
messageDelay = 0;
//...
发送消息扩展:
function sendTextMessage(recipientId, messageText) {
//...
setTimeout(function() {
callSendAPI(messageData);
}, messageDelay++ * 100)
}
消息没有按顺序发送,因为请求是异步发送到 facebook 的,并且可以按任何顺序发送。
要解决这个问题,您必须在收到响应之前应该发送的消息时调用下一个sendTextMessage
。
基于@user3884594 提出的递归解决方案,我使用它让它工作(我删除了错误处理以简化):
send_messages (["message 01", "message 02", "message 03"]);
function send_messages (which, i = 0)
{
request({
url: 'https://graph.facebook.com/v2.10/me/messages',
qs: { access_token: FACEBOOK_ACCESS_TOKEN },
method: 'POST',
json: { recipient: { id: senderId }, message: { text: which [i] }
}, (error, response, body) =>
{
// You need to put your error handling logic here
if (i++ < which.length - 1)
send_messages (which, i);
});
}
我遇到了完全相同的问题,该解决方案对我有用:
function sendMessage(recipient, messages, accessToken, i) {
axios.post(baseURL + 'v2.11/me/messages/?access_token=' + accessToken,
Object.assign({}, {
messaging_type: "RESPONSE",
recipient: {
id: recipient
}
}, messages[i]['payload']) )
.then(response => {
if(i < messages.length) sendMessage( recipient, messages, accessToken, i+1 );
},
error => {})
.catch(error => {});
}
sendMessage(recipient, flow['messages'], flow['page']['accessToken'], 0);
那是我的问题: 使用 Facebook Send-API 发送顺序消息
您可以尝试将它们放入 setTimeout 函数中,这样每个函数都会在一段时间后运行。
所以替换这个:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
有了这个:
sendTextMessage(user, "Hello!");
// 1 second
setTimeout(function() {
sendTextMessage(user, "1");
}, 1000)
// 2 seconds
setTimeout(function() {
sendTextMessage(user, "2");
}, 2000)
// 3 seconds
setTimeout(function() {
sendTextMessage(user, "3");
}, 3000)
他们应该一个接一个地去。 如果需要,您还可以将这些功能相互嵌入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.