skip to Main Content

I’m trying to send messages using FB Send-Message API in sequential order, but have an issue with it. As a result my bot sends messages in wrong order. I have the following functions:

function sendMessage(recipient, payload, accessToken) {

    return axios.post(baseURL + 'v2.11/me/messages/?access_token=' + accessToken,
        Object.assign({}, {
            messaging_type: "RESPONSE",
            recipient: {
                id: recipient
            }
        }, payload) );
}

(1)(returns Promise of sending message);

let async_actions;
let promise_chain = Q.fcall(function(){});
async_actions = flow['messages'].map(message => {
    return sendMessage(recipient, message['payload'], flow['page']['accessToken'])
});


async_actions.forEach(async_action => {
    //console.log(async_action)
    promise_chain = promise_chain.then(f);
});

(2)(Loops through array with messages and executes function (1), then inserts it in a chain).

What should I do to send messages sequentially? For now it sends them randomly, I mean how to wait until one message is sent and then send another? Thank you.

Same issue:
(1) Facebook Messenger bot not sending messages in order

2

Answers


  1. Chosen as BEST ANSWER

    It was a Facebook bug reported here - https://developers.facebook.com/bugs/565416400306038

    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);
    

  2. When you call sendMessage, it will return a promise before the promise is actually resolved. Therefore, you don’t want to call the next sendMessage until the previous sendMessage call resolves. However, in your .map() call you do exactly that. Instead, you want to return a function that will call the correct sendMessage

    Simplest way would be to use a sequential promise library, or you can roll your own using reduce().

    const sequential = require('promise-sequential');
    
    const async_actions = flow['messages'].map(message => {
        // return a *function* which executes sendMessage when the function is called
        return () => {
          console.log(`sending message ${message['payload']}`);
          sendMessage(recipient, message['payload'], flow['page']['accessToken'])
        };
    });
    
    
    sequential(async_actions)
      .then(res => {
        console.log("all done");
        console.log(res);
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search