簡體   English   中英

Twilio API 調用適用於本地環境,但不適用於 AWS Lambda ZC1C425268E68385D1AB5074C17A94F

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

問題

我想從 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.");

我可以在本地運行它,並且我應該收到目標號碼的消息,但是當我 zip 全部完成時,將其移動到 Lambda,然后運行它,我只得到StartDone ,沒有create和沒有 SMS function。

嘗試的解決方案

我嘗試將環境變量替換為實際值,以確保那里沒有問題,我檢查了 Twilio 日志,除了我在本地進行的成功調用之外什么都沒有。

我可以確認每次運行時,它都會到達client.messages.create然后似乎只是跳過它,沒有 output, Done是下一件事。

我讓它工作了一次,通過在第一行之前添加一個console.log(process.env.ACCOUNT_SID)語句(這是在使用環境變量而不是硬編碼值時),日志語句的 output 是undefined的但無論出於何種原因發送的消息和它 output 消息的 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 環境變量,但 ACCOUNT_SID 和 AUTH_TOKEN 都被記錄為undefined ,則可以加分。 它們都確實存在。

Twilio 開發人員布道師在這里。

您正在使用標記為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.

AWS 實際上會暫停 JS 事件循環,並在再次調用 Lambda 時恢復它,因此您甚至可能會在運行 function 后發現消息正在傳遞幾秒鍾或幾分鍾, 就像這個提問者所做的那樣

解決方法是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_SIDprocess.env.AUTH_TOKEN被注銷為undefined ,這表明它們沒有正確設置。 確保它們在正確的環境中配置

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM