[英]Twilio API call works from local environment but not AWS Lambda function
I have the following code I want to run from a Lambda function (node.js v12 runtime):我想从 Lambda function (node.js v12 运行时)运行以下代码:
const client = require('twilio')(process.env.ACCOUNT_SID, process.env.AUTH_TOKEN);
console.log("Start.");
client.messages.create({
body: 'Msg',
to: '+1234567890',// a verified number
from: '+1234567890' // a valid Twilio number
})
.then((message) => {
console.log(message.sid);
})
.catch((e) => {
console.log(Error(e));
console.log("Error in Signup");
});
console.log("Done.");
I can run this locally and I receive the message to the target number as I should, but when I zip it all up, move it to Lambda, and run it, I only get Start
and Done
, no output and no SMS from the create
function.我可以在本地运行它,并且我应该收到目标号码的消息,但是当我 zip 全部完成时,将其移动到 Lambda,然后运行它,我只得到Start
和Done
,没有create
和没有 SMS function。
I've tried replacing the environment variables with the actual values just to make sure it's not an issue there, I've checked Twilio logs and there's nothing there aside from the successful calls I made locally.我尝试将环境变量替换为实际值,以确保那里没有问题,我检查了 Twilio 日志,除了我在本地进行的成功调用之外什么都没有。
I can confirm that every time it runs, it gets to client.messages.create
and then it seems to just skip it, no output, Done
is the next thing.我可以确认每次运行时,它都会到达client.messages.create
然后似乎只是跳过它,没有 output, Done
是下一件事。
I got it to work one time, by adding a console.log(process.env.ACCOUNT_SID)
statement before the first line (this was while using the environment variables and not the hard coded values), the output of the log statement was undefined
but for whatever reason the message sent and it output the message's SID.我让它工作了一次,通过在第一行之前添加一个console.log(process.env.ACCOUNT_SID)
语句(这是在使用环境变量而不是硬编码值时),日志语句的 output 是undefined
的但无论出于何种原因发送的消息和它 output 消息的 SID。 Then it stopped working again.然后它再次停止工作。
Then a few hours later the same thing happened when I added a console.log(client.messages)
after creating the client
.然后几个小时后,当我在创建client
后添加了一个console.log(client.messages)
时,同样的事情发生了。 And again it stopped working after that.之后它再次停止工作。
Any help would be hugely appreciated, I have never believed in poltergeists more than I do right now.任何帮助都将不胜感激,我从来没有像现在这样相信恶作剧者。
Most of this is taken from here and here .大部分内容来自这里和这里。
exports.handler = async (event, context, callback) => {
const AWS = require('aws-sdk');
const b64 = require('base64-js');
const encryptionSdk = require('@aws-crypto/client-node');
const Twilio = require('twilio');
// Configure the encryption SDK client with the KMS key from the environment variables.
const { encrypt, decrypt } = encryptionSdk.buildClient(encryptionSdk.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);
const generatorKeyId = process.env.KEY_ALIAS;
console.log(process.env.KEY_ALIAS);
const keyIds = [ process.env.KEY_ID ];
console.log(process.env.KEY_ID);
const keyring = new encryptionSdk.KmsKeyringNode({ generatorKeyId, keyIds });
// Decrypt the secret code using encryption SDK.
let plainTextCode;
if(event.request.code){
const { plaintext, messageHeader } = await decrypt(keyring, b64.toByteArray(event.request.code));
plainTextCode = plaintext;
}
// Your Account SID from www.twilio.com/console
// See http://twil.io/secure for important security information
const accountSid = process.env.ACCOUNT_SID;
console.log(process.env.ACCOUNT_SID);
// Your Auth Token from www.twilio.com/console
// See http://twil.io/secure for important security information
const authToken = process.env.AUTH_TOKEN;
console.log(authToken);
if(event.triggerSource == 'CustomSMSSender_SignUp'){
console.log('CustomSMSSender_SignUp');
// Send sms to end-user using custom or 3rd party provider.
// Import Twilio's Node Helper library
// Create an authenticated Twilio Client instance
const client = require('twilio')(process.env.ACCOUNT_SID, process.env.AUTH_TOKEN);
// Send a text message
client.messages.create({
body: `You're verification code is ${plainTextCode.toString()}.`,
to: event.request.userAttributes.phone_number, // user's phone number
from: '+1234567890' // redacted, actual value is a Twilio phone number
})
.then((message) => {
// Success, return message SID
console.log(message.sid);
})
.catch((e) => {
// Error, return error object
console.log(Error(e));
console.log("Error in Signup");
});
}
};
While I'm here, bonus points if anyone can explain why I can print the KEY_ALIAS and KEY_ID env vars but ACCOUNT_SID and AUTH_TOKEN both get logged as undefined
.当我在这里时,如果有人能解释为什么我可以打印 KEY_ALIAS 和 KEY_ID 环境变量,但 ACCOUNT_SID 和 AUTH_TOKEN 都被记录为undefined
,则可以加分。 They all do exist.它们都确实存在。
Twilio developer evangelist here. Twilio 开发人员布道师在这里。
You're using a Lambda function marked async
, which will return as soon as all processing is done within the function, including asynchronous processing as long as it uses the await
keyword .您正在使用标记为async
的 Lambda function ,只要在 function 中完成所有处理,它就会返回,包括异步处理,只要它使用await
关键字。 The issue is that you make the call to the Twilio API, which is an asynchronous function, but do not use await
, so the processing finishes straight after and the Lambda function is over. The issue is that you make the call to the Twilio API, which is an asynchronous function, but do not use await
, so the processing finishes straight after and the Lambda function is over.
AWS actually pauses the JS event loop and resumes it when the Lambda is called again, so you might even find messages being delivered seconds or minutes after you run the function, like this questioner did . AWS 实际上会暂停 JS 事件循环,并在再次调用 Lambda 时恢复它,因此您甚至可能会在运行 function 后发现消息正在传递几秒钟或几分钟, 就像这个提问者所做的那样。
The way to solve it is to await
the result of the call to the API.解决方法是await
调用 API 的结果。 You can then wrap this in a try/catch
to recover from errors, rather than using .then
and .catch
.然后,您可以将其包装在try/catch
中以从错误中恢复,而不是使用.then
和.catch
。
exports.handler = async (event, context, callback) => {
const b64 = require("base64-js");
const encryptionSdk = require("@aws-crypto/client-node");
const Twilio = require("twilio");
// Configure the encryption SDK client with the KMS key from the environment variables.
const { decrypt } = encryptionSdk.buildClient(
encryptionSdk.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT
);
const generatorKeyId = process.env.KEY_ALIAS;
console.log(process.env.KEY_ALIAS);
const keyIds = [process.env.KEY_ID];
console.log(process.env.KEY_ID);
const keyring = new encryptionSdk.KmsKeyringNode({ generatorKeyId, keyIds });
// Decrypt the secret code using encryption SDK.
let plainTextCode;
if (event.request.code) {
const { plaintext } = await decrypt(
keyring,
b64.toByteArray(event.request.code)
);
plainTextCode = plaintext;
}
if (event.triggerSource == "CustomSMSSender_SignUp") {
console.log("CustomSMSSender_SignUp");
// Create an authenticated Twilio Client instance
const client = Twilio(process.env.ACCOUNT_SID, process.env.AUTH_TOKEN);
try {
// Send a text message
const message = await client.messages.create({
body: `You're verification code is ${plainTextCode.toString()}.`,
to: event.request.userAttributes.phone_number, // user's phone number
from: "+1234567890", // redacted, actual value is a Twilio phone number
});
// Success, return message SID
console.log(message.sid);
} catch (error) {
// Error, return error object
console.log(Error(e));
console.log("Error in Signup");
}
}
};
As for process.env.ACCOUNT_SID
and process.env.AUTH_TOKEN
being logged out as undefined
, that suggests that they aren't set correctly.至于process.env.ACCOUNT_SID
和process.env.AUTH_TOKEN
被注销为undefined
,这表明它们没有正确设置。 Make sure they are configured in the correct environment .确保它们在正确的环境中配置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.