

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 自訂電子郵件寄件者 Lambda 觸發程序
<a name="user-pool-lambda-custom-email-sender"></a>

若您將自訂電子郵件寄件者觸發程序指派至使用者集區，Amazon Cognito 會在使用者事件要求傳送電子郵件訊息時，調用 Lambda 函數而非其預設行為。透過自訂寄件者觸發，您的 AWS Lambda 函數可以透過您選擇的方法和提供者傳送電子郵件通知給使用者。您函數的自訂程式碼必須從您的使用者集區處理並傳遞所有電子郵件訊息。

此觸發程序適用於您可能想要更好地控制使用者集區傳送電子郵件訊息的方式的情況。您的 Lambda 函數可以自訂對 Amazon SES API 操作的呼叫，例如當您想要管理多個已驗證的身分或跨 時 AWS 區域。您的函數也可能將訊息重新導向至另一個交付媒體或第三方服務。

若要了解如何設定自訂電子郵件寄件者觸發條件，請參閱 [啟用自訂寄件者 Lambda 觸發條件](user-pool-lambda-custom-sender-triggers.md#enable-custom-sender-lambda-trigger)。

## 自訂電子郵件寄件者 Lambda 觸發程序來源
<a name="trigger-source"></a>

下表說明 Lambda 程式碼中自訂電子郵件觸發程序來源的觸發事件。


| `TriggerSource value` | 事件 | 
| --- | --- | 
| CustomEmailSender\$1SignUp | 使用者註冊後，Amazon Cognito 會傳送歡迎訊息。 | 
| CustomEmailSender\$1Authentication | 使用者登入，Amazon Cognito 會傳送電子郵件 OTP 或 MFA 代碼。 | 
| CustomEmailSender\$1ForgotPassword | 使用者請求代碼以重置其密碼。 | 
| CustomEmailSender\$1ResendCode | 使用者請求替換帳戶確認碼。 | 
| CustomEmailSender\$1UpdateUserAttribute | 使用者更新電子郵件地址或電話號碼屬性，Amazon Cognito 會傳送代碼來驗證屬性。 | 
| CustomEmailSender\$1VerifyUserAttribute | 使用者建立新的電子郵件地址或電話號碼屬性，Amazon Cognito 會傳送代碼來驗證屬性。 | 
| CustomEmailSender\$1AdminCreateUser | 您可以在使用者集區中建立新使用者，Amazon Cognito 會將臨時密碼傳送給使用者。 | 
| CustomEmailSender\$1AccountTakeOverNotification | Amazon Cognito 偵測到有人嘗試接管使用者帳戶，並向使用者傳送通知。 | 

## 自訂電子郵件寄件者 Lambda 觸發程序參數
<a name="custom-email-sender-parameters"></a>

Amazon Cognito 傳遞至此 Lambda 函數的請求，是以下參數和 Amazon Cognito 新增至所有請求的[常用參數](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html#cognito-user-pools-lambda-trigger-syntax-shared)之組合。

------
#### [ JSON ]

```
{
    "request": {
        "type": "customEmailSenderRequestV1",
        "code": "string",
        "clientMetadata": {
            "string": "string",
             . . .
            },
        "userAttributes": {
            "string": "string",
            . . .
         }
}
```

------

### 自訂電子郵件寄件者請求參數
<a name="custom-email-sender-request-parameters"></a>

**type**  
請求版本。對於自訂電子郵件寄件者事件，此字串的值一律為 `customEmailSenderRequestV1`。

**code**  
您的函數可以解密並傳送給您使用者的加密代碼。

**clientMetadata**  
您可以做為自訂電子郵件寄件者 Lambda 函數觸發程序的自訂輸入提供的一個或多個鍵值組。若要將此資料傳遞至您的 Lambda 函數，您可以使用 [AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html) 和 [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html) API 動作中的 ClientMetadata 參數。Amazon Cognito 不包含其傳遞至身分驗證後函數的請求中的 [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html) 和 [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) API 操作的 ClientMetadata 參數中的資料。  
Amazon Cognito 會在具有下列觸發來源的事件中`ClientMetadata`傳送至自訂電子郵件觸發函數：  
+ `CustomEmailSender_ForgotPassword`
+ `CustomEmailSender_SignUp`
+ `CustomEmailSender_Authentication`
Amazon Cognito 不會`ClientMetadata`以來源 傳送觸發事件`CustomEmailSender_AccountTakeOverNotification`。

**userAttributes**  
代表使用者屬性的一個或多個鍵值組。

### 自訂電子郵件寄件者回應參數
<a name="custom-email-sender-response-parameters"></a>

Amazon Cognito 不預期會在自訂電子郵件寄件者回應中收到任何其他傳回的資訊。您的 Lambda 函數必須解譯事件並解密程式碼，然後傳遞訊息內容。典型的 函數會組合電子郵件訊息，並將其導向至第三方 SMTP 轉送。

## 程式碼範例
<a name="custom-email-sender-code-examples"></a>

下列 Node.js 範例處理您的自訂電子郵件寄件者 Lambda 函數中的電子郵件訊息事件。此範例假設您的函數定義了兩個環境變數。

**`KEY_ID`**  
您要用來加密和解密使用者程式碼的 KMS 金鑰 ID。

**`KEY_ARN`**  
您想要用來加密和解密使用者程式碼的 KMS 金鑰的 Amazon Resource Name (ARN)。

**部署此函數**

1. 在開發人員工作區中安裝最新版本的 NodeJS。

1. 在工作區中建立新的 NodeJS 專案。

1. 使用 初始化您的專案`npm init -y`。

1. 建立 Lambda 函數的指令碼：`touch index.mjs`。

1. 將下列範例的內容貼到 `index.mjs`。

1. 下載專案相依性： AWS Encryption SDK`npm install @aws-crypto/client-node`。

1. 將專案目錄壓縮為檔案：`zip -r my_deployment_package.zip .`。

1. [將 ZIP 檔案部署到您的 函數](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html)。

此範例函數會解密程式碼，對於註冊事件，則模擬傳送電子郵件訊息到使用者的電子郵件地址。

```
import { KmsKeyringNode, buildClient, CommitmentPolicy } from '@aws-crypto/client-node';

// Configure the encryption SDK client with the KMS key from the environment variables
const { encrypt, decrypt } = buildClient(
    CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT
);

const generatorKeyId = process.env.KEY_ID;
const keyIds = [process.env.KEY_ARN];
const keyring = new KmsKeyringNode({ generatorKeyId, keyIds });

// Example function to simulate sending email.
// This example logs message details to CloudWatch Logs from your Lambda function.
// Update this function with custom logic that sends an email message to 'emailaddress' with body 'message'.
const sendEmail = async (emailAddress, message) => {
    // Log the destination with the email address masked.
    console.log(`Simulating email send to ${emailAddress.replace(/[^@.]/g, '*')}`);
    // Log the message with the code masked.
    console.log(`Message content: ${message.replace(/\b\d{6,8}\b/g, '********')}`);
    // Simulate API delay
    await new Promise(resolve => setTimeout(resolve, 100));
    console.log('Email sent successfully');
    return true;
};

export const handler = async (event) => {
    try {
        // Decrypt the secret code using encryption SDK
        let plainTextCode;
        if (event.request.code) {
            const { plaintext, messageHeader } = await decrypt(keyring, Buffer.from(event.request.code, 'base64'));
            plainTextCode = Buffer.from(plaintext).toString('utf-8');
        }

        // Handle different trigger sources
        if (event.triggerSource == 'CustomEmailSender_SignUp') {
            const emailAddress = event.request.userAttributes.email;
            const message = `Welcome! Your verification code is: ${plainTextCode}`;
            await sendEmail(emailAddress, message);
        }
        else if (event.triggerSource == 'CustomEmailSender_ResendCode') {
            // Handle resend code
        }
        else if (event.triggerSource == 'CustomEmailSender_ForgotPassword') {
            // Handle forgot password
        }
        else if (event.triggerSource == 'CustomEmailSender_UpdateUserAttribute') {
            // Handle update attribute
        }
        else if (event.triggerSource == 'CustomEmailSender_VerifyUserAttribute') {
            // Handle verify attribute
        }
        else if (event.triggerSource == 'CustomEmailSender_AdminCreateUser') {
            // Handle admin create user
        }
        else if (event.triggerSource == 'CustomEmailSender_Authentication') {
            // Handle authentication
        }
        else if (event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification') {
            // Handle account takeover notification
        }

        return;
    } catch (error) {
        console.error('Error in custom email sender:', error);
        throw error;
    }
};
```