it-swarm.com.ru

Бот Facebook Messenger не отправляет сообщения в порядке

Я играю с созданием простого чата Facebook Messenger, и у меня возникают проблемы с последовательной отправкой сообщений.

 enter image description here

В приведенном выше примере он должен был напечатать «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. Это заставляет меня подозревать, что я неправильно взаимодействую с API Messenger.

Кто-нибудь сталкивался с этой проблемой? Как я могу получить сообщения для отправки в последовательности? Спасибо!

ПРАВКА

Поскольку я реализовал простую очередь, но все еще сталкиваюсь с этой проблемой, я включил здесь код для моей простой системы очередей.

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 здесь для подробностей о том, что, по их словам, происходит. (Спасибо Луизе за внимание Facebook к этому)

11
Brian

Я отправил в Facebook отчет об ошибке, потому что у меня была такая же проблема. Они признали, что это действительно ошибка, и работают над ее устранением: https://developers.facebook.com/bugs/565416400306038

9
Louise

После того, как вы отправите POST в/me/messages, вы получите ответ с идентификатором сообщения (мой начинается с 'mid.', Что, возможно, означает идентификатор сообщения?):

{ recipient_id: '1015411228555555',
  message_id: 'mid.1464375085492:b9606c00ca33c12345' }

После полного получения API FB Messenger вы получите вызов на ваш веб-крючок (без сообщений), подтверждающий получение:

{ sender: { id: '1015411228555555' },
  recipient: { id: '566031806XXXXXX' },
  delivery:
   { mids: [ 'mid.1464375085492:b9606c00ca33c12345' ],
     watermark: 1464375085604,
     seq: 176 } }

Я считаю, что квитанция о доставке - лучший способ обеспечить доставку, а затем отправить следующее сообщение.

4
younglion

Реализуйте запрос на отправку в качестве Обещания и отправляйте последовательные сообщения только после разрешения предыдущего.

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);
            }
        );    
    });
};
1
ninjadave

Вместо добавления статических тайм-аутов я бы создал структуру данных очереди. Когда бот хочет отправить сообщение, добавьте содержимое в конец очереди. При обратном вызове сообщения проверьте, есть ли еще какие-либо сообщения в очереди, и снова вызовите функцию, используя рекурсию, и удалите ее из очереди соответственно.

1
Corn Doggo

У меня была точно такая же проблема, у меня сработало это решение:

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

0
K. Kuksin

Основываясь на рекурсивном решении, предложенном @ 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);
    });
}
0
Emiliano Gonzalez

Я добавил счетчик messageId в приложение, которое сбрасывается в 0 при каждом запуске обработки сообщений. Затем я задерживаюсь с этим числом * 100 мс. Таким образом, я могу добавить намеренные задержки также с кодом, подобным messageDelay += 15

receivedMessage(event) {
  messageDelay = 0;
  //...

sendMessage extension:

function sendTextMessage(recipientId, messageText) {
//...
  setTimeout(function() {
    callSendAPI(messageData);
  }, messageDelay++ * 100)    
}
0
csomakk

Они должны быть получены в порядке их отправки. Убедитесь, что вы отправляете их по порядку и не вызываете асинхронную функцию 4 раза (и порядок отправки не гарантируется). (Я читал, что вы тестировали его, но во всех моих тестах я никогда не видел, чтобы получатель вышел из строя, если заказ на отправку был гарантирован.)

0
pschang

Сообщение не отправляется по порядку, поскольку запрос отправляется в Facebook асинхронно и может быть отправлен в любом порядке.

Чтобы решить эту проблему, вы должны вызвать следующий sendTextMessage, когда сообщение, которое должно быть отправлено до того, как он получил ответ.

0
Kayslay