简体   繁体   English

Twilio API 调用适用于本地环境,但不适用于 AWS Lambda ZC1C425268E68385D1AB5074C17A94F

[英]Twilio API call works from local environment but not AWS Lambda function

The Problem问题

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,然后运行它,我只得到StartDone ,没有create和没有 SMS function。

Attempted Solutions尝试的解决方案

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.任何帮助都将不胜感激,我从来没有像现在这样相信恶作剧者。

Full Code完整代码

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_SIDprocess.env.AUTH_TOKEN被注销为undefined ,这表明它们没有正确设置。 Make sure they are configured in the correct environment .确保它们在正确的环境中配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM