Twilio API调用在本地环境中工作,但不能在AWS Lambda函数中工作



问题

我有以下代码要从Lambda函数(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.");

我可以在本地运行它,并根据需要将消息接收到目标号码,但当我将其全部压缩,移动到Lambda并运行它时,我只从create函数获得StartDone,没有输出,也没有SMS。

尝试的解决方案

我试着用实际值替换环境变量,只是为了确保这不是一个问题,我检查了Twilio日志,除了在本地成功调用之外,什么都没有。

我可以确认,每次它运行时,它都会到达client.messages.create,然后它似乎只是跳过它,没有输出,接下来是Done

有一次,我在第一行之前添加了一个console.log(process.env.ACCOUNT_SID)语句(这是在使用环境变量而不是硬编码值时(,日志语句的输出是undefined,但无论出于什么原因,消息都会发送并输出消息的SID。然后它又停止工作了。

几个小时后,当我在创建client之后添加console.log(client.messages)时,同样的事情发生了。在那之后,它又一次停止了工作。

任何帮助都将不胜感激,我从未像现在这样相信恶作剧者。

完整代码

大部分都是从这里和这里拍摄的。

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");
});

}
};

当我在这里时,如果有人能解释为什么我可以打印KEY_ALIAS和KEY_ID env vars,但ACCOUNT_SID和AUTH_TOKEN都被记录为undefined,则可获得加分。它们都存在

这里是Twilio开发人员的传道者。

您使用的是一个标记为async的Lambda函数,只要它使用await关键字,它就会在函数内完成所有处理(包括异步处理(后立即返回。问题是您要调用Twilio API,这是一个异步函数,但不使用await,因此处理在之后立即完成,Lambda函数结束。

AWS实际上暂停了JS事件循环,并在再次调用Lambda时恢复它,所以你甚至可能会发现消息在你运行函数几秒钟或几分钟后就被传递了,就像这个提问者所做的那样。

解决该问题的方法是将调用API的结果await。然后,您可以将其封装在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");
}
}
};

至于process.env.ACCOUNT_SIDprocess.env.AUTH_TOKEN被注销为undefined,这表明它们的设置不正确。确保在正确的环境中配置它们。

最新更新