

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

# 为 Amazon AWS Lambda 进行配置 WorkMail
<a name="lambda"></a>

在入站和出站电子邮件流规则中使用 “**运行 Lambda**” 操作，将符合规则的电子邮件传递给 AWS Lambda 函数进行处理。

从以下配置中选择 “在亚马逊上**运行 Lambda**” 操作。 WorkMail

**同步**运行 Lambda** 配置**  
在发送或传送与流规则匹配的电子邮件之前，会先将此电子邮件传递给 Lambda 函数进行处理。使用此配置修改电子邮件内容。您还可以针对不同的使用案例控制入站或出站电子邮件流。例如，传递到 Lambda 函数的规则可以阻止敏感电子邮件的传送、删除附件或添加免责声明。

**异步**运行 Lambda** 配置**  
在发送或传送与流规则匹配的电子邮件时，会将此电子邮件传递给 Lambda 函数进行处理。此配置不会影响电子邮件传递，并且用于收集入站或出站电子邮件的指标等任务。

无论您选择同步配置还是异步配置，传递到 Lambda 函数的事件对象都包含入站或出站电子邮件事件的元数据。您还可以使用元数据中的邮件 ID 来访问电子邮件的全部内容。有关更多信息，请参阅 [使用检索消息内容 AWS Lambda](lambda-content.md)。有关电子邮件事件的更多信息，请参阅 [Lambda 事件数据](#lambda-data)。

有关入站和出站电子邮件流规则的更多信息，请参阅[管理电子邮件流](email-flows.md)。有关 Lambda 的更多信息，请参阅 [https://docs.aws.amazon.com/lambda/latest/dg/welcome.html](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)。

**注意**  
目前，Lambda 电子邮件流规则仅引用同一 AWS 区域和正在配置的亚马逊 WorkMail 组织中的 Lambda 函数。 AWS 账户 

## Amazon AWS Lambda 版入门 WorkMail
<a name="start-lambda"></a>

要开始在亚马逊 AWS Lambda 上使用 WorkMail，我们建议将 [ WorkMail Hello World Lambda 函数](https://console.aws.amazon.com/lambda/home#/create/app?applicationId=arn:aws:serverlessrepo:us-east-1:489970191081:applications/workmail-hello-world-python)从部署 AWS Serverless Application Repository 到您的账户。该函数具有所有必要的资源及为您配置的权限。有关更多示例，请参阅上的[amazon-workmail-lambda-templates](https://github.com/aws-samples/amazon-workmail-lambda-templates)存储库 GitHub。

如果您选择创建自己的 Lambda 函数，则必须使用 AWS Command Line Interface ()AWS CLI配置权限。在以下示例命令中，请执行以下操作：
+ 将 `MY_FUNCTION_NAME` 替换为您的 Lambda 函数的名称。
+ `REGION`替换为您的 WorkMail Amazon AWS 区域。可用的 Amazon WorkMail 区域包括`us-east-1`（美国东部（弗吉尼亚北部））、`us-west-2`（美国西部（俄勒冈））和`eu-west-1`（欧洲（爱尔兰））。
+ 将 `AWS_ACCOUNT_ID` 替换为您的 12 位 AWS 账户 ID。
+ `WORKMAIL_ORGANIZATION_ID`用您的亚马逊 WorkMail组织编号替换。您可以在**组织**页面上贵组织对应的卡上找到该 ID。



```
aws --region REGION lambda add-permission --function-name MY_FUNCTION_NAME 
--statement-id AllowWorkMail 
--action "lambda:InvokeFunction" 
--principal workmail.REGION.amazonaws.com
--source-arn arn:aws:workmail:REGION:AWS_ACCOUNT_ID:organization/WORKMAIL_ORGANIZATION_ID
```

有关使用的更多信息 AWS CLI，请参阅《[https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)。

## 配置同步**运行 Lambda** 规则
<a name="synchronous-rules"></a>

要配置同步**运行 Lambda** 规则，请使用**运行 Lambda** 操作创建电子邮件流规则，然后选中**同步运行**复选框。有关创建邮件流规则的更多信息，请参阅[创建电子邮件流规则](create-email-rules.md)。

要完成同步规则的创建操作，请添加 Lambda Amazon 资源名称 (ARN) 并配置以下选项。

****Fallback action (回退操作)****  
当 Lambda 函数运行失败时，亚马逊将 WorkMail 应用该操作。如果未设置 **allRecipients** 标志，则此操作也适用于 Lambda 响应中省略的任何收件人。**回退操作**不能是另一项 Lambda 操作。

****Rule timeout (规则超时)**（以分钟为单位）**  
如果亚马逊 WorkMail 无法调用 Lambda 函数，则重试该函数的时间段。在此时间段结束时将应用 **Fallback action (回退操作)**。

**注意**  
同步**运行 Lambda** 规则仅支持 **\$1** 目标条件。

## Lambda 事件数据
<a name="lambda-data"></a>

使用以下事件数据触发 Lambda 函数。数据的呈现方式会有所不同，具体取决于用于 Lambda 函数的编程语言。

```
{
    "summaryVersion": "2018-10-10",
    "envelope": {
        "mailFrom" : {
            "address" : "from@example.com"
        },
        "recipients" : [
           { "address" : "recipient1@example.com" },
           { "address" : "recipient2@example.com" }
        ]
    },
    "sender" : {
        "address" :  "sender@example.com"
    },
    "subject" : "Hello From Amazon WorkMail!",
    "messageId": "00000000-0000-0000-0000-000000000000",
    "invocationId": "00000000000000000000000000000000",
    "flowDirection": "INBOUND",
    "truncated": false
}
```

事件 JSON 包含以下数据。

**summaryVersion**  
`LambdaEventData` 的版本号。仅当您在 `LambdaEventData` 中进行向后不兼容的更改时，此数据才会更新。

**envelope**  
电子邮件的信封，其中包括以下字段：    
**mailFrom**  
**From (发件人)** 地址，它通常是发送电子邮件的用户的电子邮件地址。如果该用户以其他用户名义或代表其他用户发送电子邮件，则 **mailFrom** 字段返回代表其发送电子邮件的用户的电子邮件地址，而不是实际发件人的电子邮件地址。  
**recipients**  
收件人电子邮件地址的列表。Amazon WorkMail 不区分 “收件人**”、“****抄送**” 或 “密**件抄送**”。  
对于入站电子邮件流规则，此列表包括您在其中创建规则的 Amazon WorkMail 组织中所有域中的收件人。Lambda 函数会针对发件人的每个 SMTP 会话进行单独调用，并且收件人字段将列出该 SMTP 对话中的收件人。不包括具有外部域的收件人。

**sender**  
代表其他用户发送电子邮件的用户的电子邮件地址。仅在代表其他用户发送电子邮件时设置此字段。

**subject**  
电子邮件主题行。当它超过 256 个字符限制时将被截断。

**messageId**  
在使用 Amazon Message Flow SDK 时，用于访问电子邮件 WorkMail 消息的全部内容的唯一 ID。

**invocationId**  
唯一 Lambda 调用的 ID。当因同一个 Lambda 函数被多次调用时，此 ID 保持不变。**LambdaEventData**用于检测重试并避免重复。

**flowDirection**  
指示电子邮件流的方向，即 **INBOUND (入站)** 或 **OUTBOUND (出站)**。

**truncated**  
适用于负载大小，而不是主题行长度。当为 `true` 时，负载大小超过 128 KB 的上限，因此收件人列表会被截断，以便满足限制。

## 同步**运行 Lambda** 响应架构
<a name="synchronous-schema"></a>

当具有同步 **Run Lambda** 操作的电子邮件流规则与入站或出站电子邮件匹配时，Amazon 会 WorkMail 调用配置的 Lambda 函数并等待回复，然后再对电子邮件采取行动。Lambda 函数根据预定义的架构返回响应，该架构列出了操作、操作类型、适用参数以及操作适用的收件人。

以下示例显示了同步**运行 Lambda** 响应。响应因用于 Lambda 函数的编程语言而异。

```
{
    "actions": [                          
      {
        "action" : {                       
          "type": "string",                 
          "parameters": { various }       
        },
        "recipients": [list of strings],      
        "allRecipients": boolean            
      }
    ]
}
```

响应 JSON 包含以下数据。

**action**  
要为收件人执行的操作。

**类型**  
操作类型。对于异步**运行 Lambda** 操作，不会返回操作类型。  
入站规则操作类型包括 **BOUNCE**、**DROP**、**DEFAULT**、**BYPASS\$1SPAM\$1CHECK** 和 **MOVE\$1TO\$1JUNK**。有关更多信息，请参阅 [入站电子邮件规则操作](email-flows.md#email-flows-rule-actions)。  
出站规则操作类型包括 **BOUNCE**、**DROP** 和 **DEFAULT**。有关更多信息，请参阅 [出站电子邮件规则操作](email-flows.md#email-flows-rule-outbound)。

**parameters**  
其他操作参数。支持 **BOUNCE** 操作类型作为具有键 **bounceMessage** 和值 **string** 的 JSON 对象。此退回邮件用于创建退回电子邮件。

**recipients**  
应对其执行操作的电子邮件地址的列表。可以向响应添加新的收件人，即使这些新收件人未包含在原始收件人列表中也是如此。如果操作的 **allRecipients** 为 true，则不需要此字段。  
当为入站电子邮件调用 Lambda 操作时，您只能添加来自贵组织的新收件人。新收件人将作为 **BCC (密件抄送)** 添加到响应中。

**allRecipients**  
如果为 true，则将操作应用于不受 Lambda 响应中的其他特定操作约束的所有收件人。

### 同步**运行 Lambda** 操作限制
<a name="synchronous-limits"></a>

**当亚马逊为同步运行 Lambda 操作 WorkMail 调用 Lambda 函数时，以下限制适用：**
+ Lambda 函数必须在 15 秒内进行响应，否则将被视为失败的调用。
**注意**  
系统将按照您指定的**规则超时**间隔重试调用。
+ Lambda 函数响应的最大允许大小为 256 KB。
+ 响应最多可包含 10 个唯一操作。10 个以外的操作将受配置的 **Fallback action (回退操作)** 的约束。
+ 出站 Lambda 函数最多允许 500 个收件人。
+ **Rule timeout (规则超时)** 的最大值为 240 分钟。如果将最小值配置为 0，则在 Amazon WorkMail 应用回退操作之前无需重试。

### 同步**运行 Lambda** 操作失败
<a name="synchronous-failures"></a>

**如果亚马逊由于错误、响应无效或 Lambda 超时而 WorkMail 无法调用您的 Lambda 函数，则亚马逊会使用指数级退避 WorkMail 重试调用，从而降低处理速率，直到规则超时时间结束。**然后，**Fallback action (回退操作)** 将应用于电子邮件的所有收件人。有关更多信息，请参阅 [配置同步**运行 Lambda** 规则](#synchronous-rules)。

## 同步**运行 Lambda** 响应示例
<a name="synchronous-responses"></a>

以下示例演示了常见同步**运行 Lambda** 响应的结构。

**Example ：从电子邮件中删除指定的收件人**  
以下示例演示了用于从电子邮件中删除收件人的同步**运行 Lambda** 响应的结构。  

```
{
    "actions": [
      {
        "action": {
          "type": "DEFAULT"
        },
        "allRecipients": true
      },
      {
        "action": {
          "type": "DROP"
        },
        "recipients": [
          "drop-recipient@example.com"
        ]
      }
    ]
}
```

**Example ：退回自定义电子邮件**  
以下示例演示了用于退回自定义电子邮件的同步**运行 Lambda** 响应的结构。  

```
{
    "actions" : [
      {
        "action" : {
          "type": 'BOUNCE',
          "parameters": {
            "bounceMessage" : "Email in breach of company policy."
          }
        },
        "allRecipients": true
      }
    ]
}
```

**Example ：将收件人添加到电子邮件**  
以下示例演示了用于将收件人添加到电子邮件的同步**运行 Lambda** 响应的结构。这不会更新电子邮件的 **To (收件人)** 或 **CC (抄送)** 字段。  

```
{
    "actions": [
      {
        "action": { 
          "type": "DEFAULT" 
        },
        "recipients": [
          "new-recipient@example.com"
         ]
      },
      {
        "action": { 
          "type": "DEFAULT" 
        },
        "allRecipients": true
      }
    ]
}
```

[有关为运行 Lambda 操作创建 Lambda 函数时要使用的更多代码示例，请参阅亚马逊 **Lambda** 模板。 WorkMail ](https://github.com/aws-samples/amazon-workmail-lambda-templates)

## 有关在亚马逊上使用 Lambda 的更多信息 WorkMail
<a name="lambda-more"></a>

您还可以访问触发 Lambda 函数的电子邮件的完整内容。有关更多信息，请参阅 [使用检索消息内容 AWS Lambda](lambda-content.md)。

# 使用检索消息内容 AWS Lambda
<a name="lambda-content"></a>

配置用于管理 Amazon 电子邮件流的 AWS Lambda 函数后 WorkMail，您可以访问使用 Lambda 处理的电子邮件的全部内容。有关开始使用亚马逊版 Lambda 的更多信息 WorkMail，请参阅。[为 Amazon AWS Lambda 进行配置 WorkMail](lambda.md)

要访问电子邮件的全部内容，请使用 Amazon Mess WorkMail age Flow API 中的`GetRawMessageContent`操作。调用时传递给 Lambda 函数的电子邮件 ID 会向该 API 发送请求。然后，该 API 会使用电子邮件的完整 MIME 内容进行响应。有关更多信息，请参阅《[亚马逊 * WorkMail API 参考》中的 “亚马逊 WorkMail *消息流](https://docs.aws.amazon.com/workmail/latest/APIReference/API_Operations_Amazon_WorkMail_Message_Flow.html)”。

以下示例显示了使用 Python 运行时环境的 Lambda 函数如何检索完整的邮件内容。

**提示**  
如果您首先从 AWS Serverless Application Repository 向您的账户部署 Amazon WorkMail [Hello World Lambda 函数](https://console.aws.amazon.com/lambda/home#/create/app?applicationId=arn:aws:serverlessrepo:us-east-1:489970191081:applications/workmail-hello-world-python)，则系统会在您的账户中创建一个具有所有必要资源和权限的 Lambda 函数。然后，您可以根据使用案例将业务逻辑添加到 lambda 函数。

```
import boto3
import email
import os

def email_handler(event, context):
    workmail = boto3.client('workmailmessageflow', region_name=os.environ["AWS_REGION"])
    msg_id = event['messageId']
    raw_msg = workmail.get_raw_message_content(messageId=msg_id)

    parsed_msg = email.message_from_bytes(raw_msg['messageContent'].read())
    print(parsed_msg)
```

有关分析传输中邮件内容的方法的更多详细示例，请参阅上的[amazon-workmail-lambda-templates](https://github.com/aws-samples/amazon-workmail-lambda-templates)存储库 GitHub。

**注意**  
您只能使用 Amazon WorkMail 消息流 API 来访问传输中的电子邮件。您只能在邮件发送或接收后 24 小时内访问。要以编程方式访问用户邮箱中的邮件，请使用亚马逊支持的其他协议之一 WorkMail，例如 IMAP 或 Exchange Web 服务 (EWS)。

# 使用 AWS Lambda 更新邮件内容
<a name="update-with-lambda"></a>

配置同步 AWS Lambda 函数来管理电子邮件流后，您可以使用 Amazon Mess WorkMail age Flow API 中的`PutRawMessageContent`操作来更新传输中的电子邮件的内容。有关开始使用适用于 Amazon 的 Lambda 函数的更多信息 WorkMail，请参阅。[配置同步**运行 Lambda** 规则](lambda.md#synchronous-rules)有关 API 的更多信息，请参阅 [ PutRawMessageContent](https://docs.aws.amazon.com/workmail/latest/APIReference/API_messageflow_PutRawMessageContent.html)。

**注意**  
 PutRawMessageContent API 需要 boto3 1.17.8，或者你可以在 Lambda 函数中添加一个层。要下载正确的 boto3 版本，请参阅上的 [boto 页面。 GitHub](https://github.com/boto/boto)有关添加层的更多信息，请参阅[配置函数以使用层](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-using)。  
下面是一个示例层：`"LayerArn":"arn:aws:lambda:${AWS::Region}:489970191081:layer:WorkMailLambdaLayer:2"`。在此示例中，将 `${AWS::Region}` 替换为适当的 AWS 区域，如 us-east-1。

**提示**  
如果您首先将 AWS Serverless 应用程序存储库中的 Amazon WorkMail [Hello World Lambda 函数](https://console.aws.amazon.com/lambda/home#/create/app?applicationId=arn:aws:serverlessrepo:us-east-1:489970191081:applications/workmail-hello-world-python)部署到您的账户，则系统会在您的账户中创建一个具有必要资源和权限的 Lambda 函数。然后，您可以根据使用案例将业务逻辑添加到 lambda 函数。

操作时请记住以下几点：
+ 使用 [ GetRawMessageContent](https://docs.aws.amazon.com/workmail/latest/APIReference/API_messageflow_GetRawMessageContent.html)API 检索原始消息内容。有关更多信息，请参阅 [使用检索消息内容 AWS Lambda](lambda-content.md)。
+ 获得原始邮件后，请更改 MIME 内容。完成后，将邮件上传到您账户中的 Amazon Simple Storage Service (Amazon S3) 存储桶。确保 S3 存储桶使用与您的 Amazon WorkMail 操作 AWS 账户 相同的 AWS 区域，并确保它使用与您的 API 调用相同的 AWS 区域。
+  WorkMail 为了让 Amazon 处理请求，您的 S3 存储桶必须具有正确的策略才能访问 S3 对象。有关更多信息，请参阅 [Example S3 policy](#s3example)。
+ 使用 [ PutRawMessageContent](https://docs.aws.amazon.com/workmail/latest/APIReference/API_messageflow_PutRawMessageContent.html)API 将更新后的消息内容发送回亚马逊 WorkMail。

**注意**  
`PutRawMessageContent`API 可确保更新消息的 MIME 内容符合 RFC 标准以及[RawMessageContent](https://docs.aws.amazon.com/workmail/latest/APIReference/API_messageflow_RawMessageContent.html)数据类型中提及的标准。入站到您的 Amazon WorkMail 组织的电子邮件并不总是符合这些标准，因此 `PutRawMessageContent` API 可能会拒绝这些标准。在这种情况下，您可以查阅返回的错误消息，了解有关如何解决任何问题的更多信息。

**Example S3 策略示例**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "workmail.REGION.amazonaws.com"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::My-Test-S3-Bucket/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "111122223333"
                },
                "Bool": {
                    "aws:SecureTransport": "true"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:workmailmessageflow:us-east-1:111122223333:message/WORKMAIL_ORGANIZATION_ID/*"
                }
            }
        }
    ]
}
```

以下示例显示了 Lambda 函数如何使用 Python 运行时更新传输中电子邮件的主题。

```
    import boto3
    import os
    import uuid
    import email
     
    def email_handler(event, context):
        workmail = boto3.client('workmailmessageflow', region_name=os.environ["AWS_REGION"])
        s3 = boto3.client('s3', region_name=os.environ["AWS_REGION"])
        
        msg_id = event['messageId']
        raw_msg = workmail.get_raw_message_content(messageId=msg_id)
        parsed_msg = email.message_from_bytes(raw_msg['messageContent'].read())
        
        # Updating subject. For more examples, see https://github.com/aws-samples/amazon-workmail-lambda-templates.
        parsed_msg.replace_header('Subject', "New Subject Updated From Lambda")
       
        # Store updated email in S3
        key = str(uuid.uuid4());
        s3.put_object(Body=parsed_msg.as_bytes(), Bucket="amzn-s3-demo-bucket", Key=key)
     
        # Update the email in WorkMail
        s3_reference = {
            'bucket': "amzn-s3-demo-bucket",
            'key': key
        }
        content = {
            's3Reference': s3_reference
        }
        workmail.put_raw_message_content(messageId=msg_id, content=content)
```

有关分析传输中消息内容的更多方法示例，请参阅中的[ amazon-workmail-lambda-templates](https://github.com/aws-samples/amazon-workmail-lambda-templates)存储库。 GitHub