node.jstwilioexponential-backoff

Twilio API & Exponential Backoff when sending bulk SMS with Node.js


I am working on a bulk SMS application that will send one message to a group of people in case of an emergency. I have reviewed the Twilio Docs and implemented their code, at which point I was getting a 429 error from the API. So I've added the exponential backoff code to prevent that, but when I run the script, it's only sending to the second number listed in the array.

const accountSid = '[ACCOUNT SID]';
const authToken = '[AUTH TOKEN]';
const client = require('twilio')(accountSid, authToken);

var numbersToMessage = ["+1800XXXXXXX", "+1888XXXXXXX"]

numbersToMessage.forEach(function(number){
  var message = client.messages.create({
    body: 'This is test #2 from August 21, 2020.',
    from: '[TWILIO SENDER NUMBER]',
    statusCallback: '[PIPEDREAM API URL]',
    to: number
  })
  .then(message => console.log(message.status))
  return((err) => {
  // assumes that the error is "request made too soon"
  backoffTime *= 2;
  i--;
  console.log(err);
  return delay(backoffTime);
});
  done();
});

Exponential backoff is completely new to me, so I'm fairly certain that's where the issue is, but that's as far as I get. I've tried using the npm package exponential-backoff, too, without any luck.


Solution

  • To be clear this is not "exponential backoff" but it should work with about 100 numbers.

    Replace with your Twilio credentials, add your numbers to the array, replace PIPEDREAM_API_URL. All your 100 messages should be queued at Twilio in about 30 seconds.

    The response message.sid from Twilio means that the message was added to the sending queue, not that the message was actually sent.

    const accountSid = 'AC...';
    const authToken = '4f...';
    const client = require('twilio')(accountSid, authToken);
    
    const TWILIO_SENDER_NUMBER = '+1...';
    const TEXT_TO_SEND = 'This is test #2 from August 21, 2020.';
    const PIPEDREAM_API_URL = '...';
    
    // about 100 numbers
    let numbersToMessage = [
        "+1...",
        "+1...",
        "+1...",
        // "+1...",
    
    ];
    
    function sendAllMessagesWithTwilio(data) {
    
        // stop condition, nothing left in the array of numbers
        if (data.length === 0) {
            console.log('............... DONE');
            return;
        }
    
        // take the first number from the array of numbers
        let _number = data.shift();
        console.log(_number);
    
        client.messages
            .create({
                to: _number,
                from: TWILIO_SENDER_NUMBER,
                body: TEXT_TO_SEND,
                statusCallback: PIPEDREAM_API_URL
            })
            .then((message) => {
                // after Twilio responds, send the next message
                console.log(`${message.sid}`);
                // recursive call of function, pass the remaining numbers as argument
                // use setTimeout() to slow down, 300 milliseconds between requests
                setTimeout(sendAllMessagesWithTwilio.bind(null, data), 300);
            })
            .catch((err) => {
                // if an error is sent back from Twilio
                console.error(err);
            });
    
    }
    
    // first call of recursive function
    // takes the initial array of numbers as argument
    console.log('BEGIN ...............')
    sendAllMessagesWithTwilio(numbersToMessage);
    

    Good luck!