自定义电子邮件发件人 Lambda 触发器 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

自定义电子邮件发件人 Lambda 触发器

当您为用户群体分配自定义电子邮件发件人触发器时,如果用户事件要求 Amazon Cognito 发送电子邮件,则它会调用 Lambda 函数,而不是其原定设置行为。使用自定义发件人触发器,您的 Amazon Lambda 函数可以通过您选择的方法和提供商向用户发送电子邮件通知。您的函数的自定义代码必须处理和传递用户群体中的所有电子邮件。

此触发器适用于以下场景:您可能希望更好地控制用户池发送电子邮件消息的方式。您的 Lambda 函数可以自定义对 Amazon SES API 操作的调用,例如,当您想要管理多个经过验证的身份或跨 Amazon Web Services 区域时。您的函数还可能将消息重定向到另一个传递媒介或第三方服务。

要了解如何配置自定义电子邮件发件人触发器,请参阅激活自定义发件人 Lambda 触发器

自定义电子邮件发件人 Lambda 触发器源

下表显示了 Lambda 代码中自定义电子邮件触发器源的触发事件。

TriggerSource value 事件
CustomEmailSender_SignUp 用户注册,Amazon Cognito 随即发送欢迎消息。
CustomEmailSender_Authentication 用户会登录,且 Amazon Cognito 会发送多重身份验证(MFA)代码。
CustomEmailSender_ForgotPassword 用户请求代码以重置其密码。
CustomEmailSender_ResendCode 用户请求替换账号确认代码。
CustomEmailSender_UpdateUserAttribute 用户更新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。
CustomEmailSender_VerifyUserAttribute 用户创建新电子邮件地址或电话号码属性,而 Amazon Cognito 将发送代码用于验证该属性。
CustomEmailSender_AdminCreateUser 您在用户池中创建新用户,而 Amazon Cognito 向其发送临时密码。
CustomEmailSender_AccountTakeOverNotification Amazon Cognito 检测到接管用户账户的尝试并向用户发送通知。

自定义电子邮件发件人 Lambda 触发器参数

Amazon Cognito 传递给此 Lambda 函数的请求是以下参数和 Amazon Cognito 添加到所有请求中的常用参数的组合。

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

自定义电子邮件发件人请求参数

type

请求版本。对于自定义电子邮件发件人事件,此字符串的值始终为 customEmailSenderRequestV1

code

您的函数可以解密并发送给您的用户的加密代码。

clientMetadata

一个或多个键值对,您可以将它们作为自定义输入提供给自定义电子邮件发件人 Lambda 函数触发器。要将此数据传递给您的 Lambda 函数,您可以使用AdminRespondToAuthChallengeRespondToAuthChallengeAPI 操作中的 ClientMetadata 参数。Amazon Cognito 在传递给身份验证后函数的请求中不包含来自 ClientMetadata 参数AdminInitiateAuthInitiateAuthAPI 操作的数据。

注意

在具有以下触发源的事件中,Amazon Cognito 会向自定义电子邮件触发函数发送 ClientMetadata

  • CustomEmailSender_ForgotPassword

  • CustomEmailSender_SignUp

  • CustomEmailSender_Authentication

Amazon Cognito 不会在具有源 CustomEmailSender_AccountTakeOverNotification 的触发事件中发送 ClientMetadata

userAttributes

表示用户属性的一个或多个键值对。

自定义电子邮件发件人响应参数

Amazon Cognito 不需要自定义电子邮件发件人响应中有任何其他返回信息。您的 Lambda 函数必须解释事件并解密代码,然后传送消息内容。典型的函数会组装电子邮件消息并将其定向到第三方 SMTP 中继。

代码示例

以下 Node.js 示例在您的自定义电子邮件发件人 Lambda 函数中处理电子邮件事件。此示例假设您的函数定义了两个环境变量。

KEY_ID

您要用于加密和解密用户代码的 KMS 密钥的 ID。

KEY_ARN

要用于加密和解密用户代码的 KMS 密钥的 Amazon 资源名称 (ARN)。

部署此函数
  1. 在您的开发者工作区中安装最新版本的 NodeJS。

  2. 在您的工作空间中创建一个新的 NodeJS 项目。

  3. 使用初始化您的项目npm init -y

  4. 为 Lambda 函数创建脚本:。touch index.mjs

  5. 将以下示例的内容粘贴到index.mjs

  6. 下载项目依赖关系, Amazon Encryption SDK:npm install @aws-crypto/client-node.

  7. 将项目目录压缩成一个文件:zip -r my_deployment_package.zip ..

  8. 将 ZIP 文件部署到您的函数

此示例函数对代码进行解密,对于注册事件,它模拟向用户的电子邮件地址发送电子邮件。

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