Reputation: 2874
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:
twilio
and twilioClient.messages.create
to make sure the client and function definition didn't get wiped out somehow.context.callbackWaitsForEmptyEventLoop
so I changing it from false
to true
.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
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