Jody Heavener
Jody Heavener

Reputation: 2874

Twilio programmable SMS not sending in deployed Lambda function

I am working on a Serverless AWS service that uses Twilio's programmable SMS to deliver text messages.

My setup is consistently delivering messages successfully when I run the stack locally (e.g. sls offline start), but in the deployed environment I seem to be unable to even call the method on the Twilio client.

Here's how the message delivery is set up:

const twilio = require('twilio');

const twilioClient = twilio(
  process.env.TWILIO_SID,
  process.env.TWILIO_TOKEN,
  {
    lazyLoading: true,
  }
);

export function sendMessage(user, message) {
  twilioClient.messages.create({
    from: process.env.TWILIO_NUMBER,
    to: user.phone,
    body: message,
  }, function(err, message) {
    console.log('error', err);
    console.log('message', message);
  });
}

// And then usage in a Serverless Function Handler

function example(event, context, callback) {
  context.callbackWaitsForEmptyEventLoop = false;

  // user is also determined here
  sendMessage(user, 'This is a message');

  return {
    body: JSON.stringify({}),
    statusCode: 200
  };
}

Locally, running this works and I am able to see the output of the message log, with nothing on the error log. However, when deployed, running this yields nothing -- the method appears to not even get called (and I can verify in the Twilio logs that no API call was made), therefor no error or message logs are made in the callback.

In debugging I've tried the following:

I have come up empty, I can't figure out why this would be working locally, but not when deployed.


Edit: per the Twilio client example, if you omit the callback function the method will return a Promise. I went ahead and tried to await the response of the method:

export function sendMessage(user, message) {
  return twilioClient.messages.create({
    from: process.env.TWILIO_NUMBER!,
    to: user.phone,
    body: message,
  });
}

// Usage...

async function example(event, context, callback) {
  context.callbackWaitsForEmptyEventLoop = false;

  try {
    const message = await sendMessage(user, 'This is a message');
    console.log('message', message)
  } catch (error) {
    console.log('error', error);
  }

  return {
    body: JSON.stringify({}),
    statusCode: 200
  };
}

In this example the Lambda function is successful, but neither the message nor the error are logged.

Upvotes: 2

Views: 843

Answers (1)

Alan
Alan

Reputation: 10771

I tried this and it works. I tried to make my code as similar to use, with a few changes.

const twilio = require('twilio');

const twilioClient = twilio(
  process.env.TWILIO_SID,
  process.env.TWILIO_TOKEN
);

let user = '+14075551212';

function sendMessage(user, message) {
  return twilioClient.messages.create({
    from: process.env.TWILIO_NUMBER,
    to: user,
    body: message,
  });
}

exports.handler = async function(event, context, callback) {
  try {
    const message = await sendMessage(user, 'This is a message');
    console.log('message', message);
    callback(null, {result: 'success'});
  } catch (error) {
    console.log('error', error);
    callback("error");
  }
};

Upvotes: 5

Related Questions