Twilio API 调用适用于本地环境,但不适用于 AWS Lambda 函数
Posted
技术标签:
【中文标题】Twilio API 调用适用于本地环境,但不适用于 AWS Lambda 函数【英文标题】:Twilio API call works from local environment but not AWS Lambda function 【发布时间】:2022-01-17 08:50:03 【问题描述】:问题
我想从 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 并运行它时,我只得到 Start
和 Done
,没有create
函数的输出和没有短信。
尝试的解决方案
我已尝试将环境变量替换为实际值,以确保那里不存在问题,我检查了 Twilio 日志,除了我在本地进行的成功调用之外,没有其他任何内容。
我可以确认,每次运行时,它都会到达client.messages.create
,然后似乎只是跳过它,没有输出,接下来是Done
。
我让它工作了一次,通过在第一行之前添加 console.log(process.env.ACCOUNT_SID)
语句(这是在使用环境变量而不是硬编码值时),日志语句的输出是 undefined
但对于无论发送消息的原因是什么,它都会输出消息的 SID。然后它又停止工作了。
几个小时后,当我在创建client
后添加console.log(client.messages)
时,同样的事情发生了。之后它再次停止工作。
任何帮助都将不胜感激,我从来没有像现在这样相信恶作剧者。
完整代码
大部分内容来自here 和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");
);
;
当我在这里时,如果有人能解释为什么我可以打印 KEY_ALIAS 和 KEY_ID 环境变量,但 ACCOUNT_SID 和 AUTH_TOKEN 都被记录为 undefined
,则可以加分。它们都存在。
【问题讨论】:
您是否尝试在then
和catch
块中添加callback()
? Twilio messages.create 异步运行,因此您的函数可能在发送消息之前完成。这是我基于片状行为的最佳猜测。
【参考方案1】:
这里是 Twilio 开发者宣传员。
您正在使用标记为 async
的 Lambda 函数,只要在函数内完成所有处理(包括异步处理),只要它使用 await
关键字,该函数就会立即返回。问题是您调用了 Twilio API,这是一个异步函数,但不使用 await
,因此处理立即完成,Lambda 函数结束。
AWS 实际上会暂停 JS 事件循环并在再次调用 Lambda 时恢复它,因此您甚至可能会发现在运行函数 like this questioner did 后几秒或几分钟内传递的消息。
解决方法是await
调用API的结果。然后,您可以将其包装在 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_SID
和process.env.AUTH_TOKEN
被注销为undefined
,这表明它们没有正确设置。确保他们是configured in the correct environment。
【讨论】:
谢谢!这已经解决了!尽管如此,环境变量仍然很奇怪。它们都是通过控制台设置在一起的,我可以登录的两个使用了我不能登录的两个使用的所有字符,很奇怪。但据我所知,没有影响。 :) 很奇怪,但只要它不工作!以上是关于Twilio API 调用适用于本地环境,但不适用于 AWS Lambda 函数的主要内容,如果未能解决你的问题,请参考以下文章
对 On Premise Exchange 的 Graph API 调用仅适用于 Playground
使用 CORS 与 LocomotiveJs 一起休息 API。适用于本地机器,但不适用于 Amazon 或 Heroku