2

I am trying to loop through an array to send multiple messages in Twilio sequentially. But in my final output in Whatsapp, the order is not sequential. For example, it displays in the order of: Image 2 -> Image 1 -> Image 3. I have tried to use the async / await library, but it did not help.

I have tried .reduce, as well as a normal for loop with an await inside of the loop.

Array:

str.text = ["Image 1", "Image 2", "Image 3"]
str.images = ["https://hatrabbits.com/wp-content/uploads/2017/01/random.jpg", "https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80", "https://www.computerhope.com/jargon/r/random-dice.jpg", ]

Code:

function sendMsg(img, txt) {
  context.getTwilioClient().messages.create({
    to: event.From,
    from: 'whatsapp:' + context.WHATSAPP_NUMBER,
    body: txt,
    mediaUrl: img
  }).then(message => {
    callback();
  }).catch(err => callback(err));
}

async function test(str) {
  (str.text).reduce(async (previousPromise, value, i) => {
      await previousPromise;
      return sendMsg(str.images[i], str.text[i])
  }, Promise.resolve());
}

request.post({
...
}, function (err, res, body) {

  var str = body.data.message;
  test(str);
}
John C
  • 517
  • 2
  • 6
  • 16

2 Answers2

0

Looks like you are mixing callback, promises without properly returning things. I would change following thins

  • return the promise from send msg
  • add await in your request.post
  • use for..of loop to process them sequentially

Something like this

str.text = ["Image 1", "Image 2", "Image 3"]
str.images = ["https://hatrabbits.com/wp-content/uploads/2017/01/random.jpg", "https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80", "https://www.computerhope.com/jargon/r/random-dice.jpg"];

function sendMsg(img, txt) {
  return context.getTwilioClient().messages.create({
    to: event.From,
    from: 'whatsapp:' + context.WHATSAPP_NUMBER,
    body: txt,
    mediaUrl: img
  }).catch(err => console.log(err));
}

async function test(str) {
  for (const [index, value] of str.text) {
    await sendMsg(str.images[index], str.text[index]);
  }
}

request.post({
  ...
  }, async function (err, res, body) {

    var str = body.data.message;
    await test(str);
  }

Ashish Modi
  • 7,529
  • 2
  • 20
  • 35
0

var items = [
    {
        text: "Image 1",
        image: "https://hatrabbits.com/wp-content/uploads/2017/01/random.jpg"
    },
    {
        text: "Image 2",
        image: "https://images.unsplash.com/photo-1494253109108-2e30c049369b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80"
    },
    {
        text: "Image 3",
        image: "https://www.computerhope.com/jargon/r/random-dice.jpg"
    }
];

sendMessage(items);

function sendMessage(items) {

    // stop condition
    if (!items.length) {
        // return;
        callback(null, '');
    }

    const currentItem = items.shift();

    context.getTwilioClient().messages.create({
        to: event.From,
        from: 'whatsapp:' + context.WHATSAPP_NUMBER,
        body: currentItem.text,
        mediaUrl: currentItem.image
    })
        .then(message => {
            setTimeout(sendMessage, 1500, items);
        })
        .catch(err => {
            // return;
            callback(err, null);
        });


}



If you need more time between messages play with 1500 from setTimeout(sendMessage, 1500, items);.
Alex Baban
  • 11,312
  • 4
  • 30
  • 44