

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

# AWS Lambda 為 Amazon WorkMail 設定
<a name="lambda"></a>

使用傳入和傳出電子郵件流程規則中的**執行 Lambda** 動作，將符合規則的電子郵件訊息傳遞至 AWS Lambda 函數進行處理。

從下列組態中選擇 Amazon WorkMail 中的**執行 Lambda** 動作。

**同步**執行 Lambda** 組態**  
符合流程規則的電子郵件訊息會在傳送或交付之前傳遞至 Lambda 函數進行處理。使用此組態來修改電子郵件內容。您也可以控制不同使用案例的傳入或傳出電子郵件流程。例如，傳遞至 Lambda 函數的規則可能會封鎖敏感電子郵件訊息的傳遞、移除附件或新增免責聲明。

**非同步 **Run 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 區域中和所設定 AWS 帳戶 Amazon WorkMail 組織的 Lambda 函數。

## 適用於 Amazon WorkMail AWS Lambda 的 入門
<a name="start-lambda"></a>

若要開始使用 AWS Lambda 搭配 Amazon 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 至您的帳戶。函數具有所有必要的資源，以及為您設定的許可。如需更多範例，請參閱 GitHub 上的 [amazon-workmail-lambda-templates](https://github.com/aws-samples/amazon-workmail-lambda-templates) 儲存庫。

如果您選擇建立自己的 Lambda 函數，則必須使用 AWS Command Line Interface () 設定許可AWS CLI。在下列範例命令中，執行下列動作：
+ `MY_FUNCTION_NAME` 將 取代為 Lambda 函數的名稱。
+ `REGION` 將 取代為您的 Amazon WorkMail AWS 區域。可用的 Amazon WorkMail 區域包括 `us-east-1`（美國東部 （維吉尼亞北部）)、 `us-west-2` （美國西部 （奧勒岡）) 和 `eu-west-1`（歐洲 （愛爾蘭）)。
+ `AWS_ACCOUNT_ID` 將 取代為您的 12 位數 AWS 帳戶 ID。
+ `WORKMAIL_ORGANIZATION_ID` 將 取代為您的 Amazon WorkMail 組織 ID。您可以在 **Organizations** 頁面上的組織卡片上找到它。



```
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 Resource Name (ARN) 並設定下列選項。

****Fallback action (備用動作)****  
如果 Lambda 函數無法執行，Amazon WorkMail 會套用動作。如果未設定 **allRecipients** 旗標，則此動作也適用於從 Lambda 回應省略的任何收件人。**備用動作**不能是另一個 Lambda 動作。

****Rule timeout (規則逾時)** (以分鐘為單位)**  
如果 Amazon 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 不會區分 **To**、**CC** 或 **BCC**。  
對於傳入電子郵件流程規則，此清單包含您在其中建立規則的 Amazon WorkMail 組織中所有網域中的收件人。系統會針對來自寄件者的每個 SMTP 對話分別叫用 Lambda 函數，而收件人欄位會列出來自該 SMTP 對話的收件人。使用外部網域的收件人不包含在內。

**寄件者**  
代表另一位使用者傳送電子郵件訊息的使用者的電子郵件地址。只有在代表其他使用者傳送電子郵件訊息時，才會設定此欄位。

**subject**  
電子郵件主旨行。超過 256 個字元限制時就會遭到截斷。

**messageId**  
使用 Amazon WorkMail 訊息流程 SDK 時，用來存取電子郵件訊息完整內容的唯一 ID。

**invocationId**  
唯一 Lambda 調用的 ID。當針對相同的 **LambdaEventData** 呼叫 Lambda 函數多次時，此 ID 保持不變。用於偵測重試次數並避免重複。

**flowDirection**  
指出電子郵件流程的方向，即 **INBOUND (傳入)** 或 **OUTBOUND (傳出)**。

**truncated**  
適用於承載大小，而不是主旨行長度。若此值為 `true`，則負載大小會超過 128 KB 的限制，因此會截斷收件人清單以符合限制。

## 同步**執行 Lambda** 回應結構描述
<a name="synchronous-schema"></a>

當具有同步**執行 Lambda** 動作的電子郵件流程規則符合傳入或傳出電子郵件訊息時，Amazon WorkMail 會呼叫設定的 Lambda 函數，並等待回應，然後再對電子郵件訊息採取動作。Lambda 函數會根據預先定義的結構描述傳回回應，該結構描述會列出動作、動作類型、適用的參數和套用動作的收件人。

下列範例顯示同步**執行 Lambda** 回應。回應會根據用於 Lambda 函數的程式設計語言而有所不同。

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

回應 JSON 包含下列資料。

**動作**  
要為收件人採取的動作。

**type**  
動作類型。非同步 **Run 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** 和值**字串**的 JSON 物件。此退信訊息可用來建立退信電子郵件訊息。

**recipients**  
應對其採取動作的電子郵件地址清單。即使原始收件人清單中未包含收件人，您仍可將收件人新增至回應中。如果某個動作的 **allRecipients** 為 true，此欄位則非必填。  
當對傳入電子郵件呼叫 Lambda 動作時，您只能新增來自您組織的新收件人。新收件人會以 **BCC (密件副本)** 的形式新增至回應中。

**allRecipients**  
為 true 時， 會將動作套用至 Lambda 回應中不受其他特定動作限制的所有收件人。

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

當 Amazon WorkMail 針對同步**執行 Lambda 動作調用 Lambda** 函數時，適用下列限制：
+ Lambda 函數必須在 15 秒內回應，或視為失敗的調用。
**注意**  
系統會針對您指定的**規則逾時**間隔重試呼叫。
+ 允許最多 256 KB 的 Lambda 函數回應。
+ 回應中最多可允許 10 個唯一動作。10 個以上都動作會受到設定的 **Fallback action (備用動作)** 所約束。
+ 傳出 Lambda 函數最多允許 500 個收件人。
+ **Rule timeout (規則逾時)** 的最大值為 240 分鐘。如果已設定最小值 0，Amazon WorkMail 套用後援動作之前不會重試。

### 同步**執行 Lambda** 動作失敗
<a name="synchronous-failures"></a>

如果 Amazon WorkMail 因為錯誤、無效的回應或 Lambda 逾時而無法叫用 Lambda 函數，Amazon WorkMail 會以指數退避重試調用，以降低處理速率，直到**規則逾時**期間完成為止。接著，**Fallback action (備用動作)** 會套用至電子郵件訊息的所有收件人。如需詳細資訊，請參閱[設定同步**執行 Lambda** 規則](#synchronous-rules)。

## 同步**執行 Lambda** 回應範例
<a name="synchronous-responses"></a>

下列範例示範常見同步 **Run Lambda** 回應的結構。

**Example ：從電子郵件訊息中移除指定的收件人**  
下列範例示範從電子郵件訊息中移除收件人的同步 **Run Lambda** 回應結構。  

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

**Example ：自訂電子郵件訊息的退信**  
下列範例示範同步 **Run Lambda** 回應的結構，以便使用自訂電子郵件訊息進行彈跳。  

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

**Example ：將收件人新增至電子郵件訊息**  
下列範例示範將收件人新增至電子郵件訊息的同步 **Run Lambda** 回應結構。這不會更新電子郵件訊息的 **To (收件人)** 或 **CC (副本)** 欄位。  

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

如需為**執行 Lambda 動作建立 Lambda** 函數時要使用的更多程式碼範例，請參閱 [Amazon WorkMail Lambda 範本](https://github.com/aws-samples/amazon-workmail-lambda-templates)。

## 搭配 Amazon WorkMail 使用 Lambda 的詳細資訊
<a name="lambda-more"></a>

您也可以存取觸發 Lambda 函數之電子郵件訊息的完整內容。如需詳細資訊，請參閱[使用 擷取訊息內容 AWS Lambda](lambda-content.md)。

# 使用 擷取訊息內容 AWS Lambda
<a name="lambda-content"></a>

設定 AWS Lambda 函數以管理 Amazon WorkMail 的電子郵件流程後，您可以存取使用 Lambda 處理之電子郵件訊息的完整內容。如需 Lambda for Amazon WorkMail 入門的詳細資訊，請參閱 [AWS Lambda 為 Amazon WorkMail 設定](lambda.md)。

若要存取電子郵件訊息的完整內容，請使用 Amazon WorkMail Message Flow API 中的 `GetRawMessageContent`動作。呼叫時傳送到 Lambda 函數的電子郵件訊息 ID 會將請求傳送至 API。接著，API 會以電子郵件訊息的完整 MIME 內容來回應。如需詳細資訊，請參閱[《Amazon WorkMail API 參考》中的 Amazon WorkMail 訊息流程](https://docs.aws.amazon.com/workmail/latest/APIReference/API_Operations_Amazon_WorkMail_Message_Flow.html)。 *Amazon WorkMail *

下列範例顯示使用 Python 執行時間環境的 Lambda 函數如何擷取完整訊息內容。

**提示**  
如果您從 將 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)部署 AWS Serverless Application Repository 到您的帳戶開始，系統會使用所有必要的資源和許可在您的帳戶中建立 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)
```

如需分析傳輸中訊息內容的更詳細範例，請參閱 GitHub 上的 [amazon-workmail-lambda-templates](https://github.com/aws-samples/amazon-workmail-lambda-templates) 儲存庫。

**注意**  
您只能使用 Amazon WorkMail Message Flow API 存取傳輸中的電子郵件訊息。您只能在傳送或接收訊息的 24 小時內存取訊息。若要以程式設計方式存取使用者信箱中的訊息，請使用 Amazon WorkMail 支援的其他通訊協定，例如 IMAP 或 Exchange Web Services (EWS)。

# 使用 AWS Lambda 更新訊息內容
<a name="update-with-lambda"></a>

設定同步 AWS Lambda 函數來管理電子郵件流程後，您可以使用 Amazon WorkMail Message Flow API 中的 `PutRawMessageContent`動作來更新傳輸中電子郵件訊息的內容。如需 Amazon WorkMail Lambda 函數入門的詳細資訊，請參閱 [設定同步**執行 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，或者您可以將 layer 新增至 Lambda 函數。若要下載正確的 boto3 版本，請參閱 [ GitHub 上的 boto 頁面](https://github.com/boto/boto)。如需新增層的詳細資訊，請參閱[設定函數以使用層](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-using)。  
以下是範例 layer：`"LayerArn":"arn:aws:lambda:${AWS::Region}:489970191081:layer:WorkMailLambdaLayer:2"`。在此範例中，`${AWS::Region}`以適當的 aws 區域取代，例如 us-east-1。

**提示**  
如果您從將 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)從 AWS Serverless Application Repository 部署到您的帳戶開始，系統會在您的帳戶中建立具有必要資源和許可的 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 帳戶 相同的 ，而且它使用與 API 呼叫相同的 AWS 區域。
+ 若要讓 Amazon WorkMail 處理請求，您的 S3 儲存貯體必須具有正確的政策，才能存取 S3 物件。如需詳細資訊，請參閱[Example S3 policy](#s3example)。
+ 使用 [ PutRawMessageContent](https://docs.aws.amazon.com/workmail/latest/APIReference/API_messageflow_PutRawMessageContent.html) API 將更新的訊息內容傳回 Amazon 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)
```

如需分析傳輸中訊息內容之方式的更多範例，請參閱 GitHub 上的 [ amazon-workmail-lambda-templates ](https://github.com/aws-samples/amazon-workmail-lambda-templates) 儲存庫。