

终止支持通知：2027 年 3 月 31 日， AWS 将终止对亚马逊 WorkMail的支持。2027 年 3 月 31 日之后，您将无法再访问亚马逊 WorkMail 控制台或亚马逊 WorkMail 资源。有关更多信息，请参阅 [Amazon WorkMail 终止支持](https://docs.aws.amazon.com/workmail/latest/adminguide/workmail-end-of-support.html)。

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

# 构建自定义可用性提供商 Lambda 函数
<a name="building_cap"></a>

自定义可用性提供程序 (CAPs) 使用基于 JSON 的请求和响应协议进行配置，该协议以明确定义的 JSON 架构编写。Lambda 函数将解析请求并提供有效的响应。

**Topics**
+ [请求和响应元素](#cap_request_response_elements)
+ [授予访问权限](#granting_access)
+ [亚马逊 WorkMail 使用 CAP Lambda 函数的示例](#cap_example_github)

## 请求和响应元素
<a name="cap_request_response_elements"></a>

### 请求元素
<a name="cap_request"></a>

以下是用于为 Amazon WorkMail 用户配置 CAP 的示例请求：

```
{
    "requester": {
        "email": "user1@internal.example.com",
        "userName": "user1",
        "organization": "m-0123456789abcdef0123456789abcdef",
        "userId": "S-1-5-18",
        "origin": "127.0.0.1"
    },
    "mailboxes": [
        "user2@external.example.com",
        "unknown@internal.example.com"
    ],
    "window": {
        "startDate": "2021-05-04T00:00:00.000Z",
        "endDate": "2021-05-06T00:00:00.000Z"
    }
}
```

请求由三个部分组成：**requester**、**mailboxes** 和 **window**。本指南的 [请求者](#cap_request_requester)、[Mailboxes](#cap_request_mailboxes) 和 [窗口](#cap_request_window) 部分分别介绍了这些内容。

#### 请求者
<a name="cap_request_requester"></a>

“*请求者*” 部分提供有关向 Amazon WorkMail 提出原始请求的用户的信息。 CAPs 使用此信息来更改提供商的行为。例如，此数据可用于模拟后端可用性提供商上的同一用户，或者可以在响应中省略某些详细信息。


| 字段 | 说明 | 必填 | 
| --- | --- | --- | 
| `Email` | 请求者的主要电子邮件地址。 | 是 | 
| `Username` | 请求者的用户名。 | 是 | 
| `Organization` | 请求者的组织 ID。 | 是 | 
| `UserID` | 请求者 ID。 | 是 | 
| `Origin` | 请求的远程地址。 | 否 | 
| `Bearer` | 留待将来使用。 | 否 | 

#### Mailboxes
<a name="cap_request_mailboxes"></a>

*mailboxes* 部分包含用户的以逗号分隔的电子邮件地址列表，用于请求其可用性信息。

#### 窗口
<a name="cap_request_window"></a>

*window* 部分包含请求可用性信息的时间窗口。`startDate` 和 `endDate` 均采用 UTC 格式指定，并根据 [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) 设置格式。预计事件不会被截断。换句话说，如果事件在定义的 `StartDate` 之前开始，则将使用原始开始时间。

### 响应元素
<a name="cap_response"></a>

亚马逊 WorkMail 将等待 25 秒钟才会收到来自 CAP Lambda 函数的响应。25 秒后，Amazon WorkMail 将假设该功能已失败，并在 EWS GetUserAvailability 响应中为关联的邮箱生成故障。这不会导致整个 GetUserAvailability 操作失败。

以下是来自本部分开头定义的配置的响应示例：

```
{
    "mailboxes": [{
        "mailbox": "user2@external.example.com",
        "events": [{
            "startTime": "2021-05-03T23:00:00.000Z",
            "endTime": "2021-05-04T03:00:00.000Z",
            "busyType": "BUSY"|"FREE"|"TENTATIVE",
            "details": {  // optional
                "subject": "Late meeting",
                "location": "Chime",
                "instanceType": "SINGLE_INSTANCE"|"RECURRING_INSTANCE"|"EXCEPTION",
                "isMeeting": true,
                "isReminderSet": true,
                "isPrivate": false
            }
        }],
        "workingHours": {
            "timezone": {
                "name": "W. Europe Standard Time"
                "bias": 60,
                "standardTime": {  // optional (not needed for fixed offsets)
                    "offset": 60,
                    "time": "02:00:00",
                    "month": "JAN"|"FEB"|"MAR"|"APR"|"JUN"|"JUL"|"AUG"|"SEP"|"OCT"|"NOV"|"DEC",
                    "week": "FIRST"|"SECOND"|"THIRD"|"FOURTH"|"LAST",
                    "dayOfWeek": "SUN"|"MON"|"TUE"|"WED"|"THU"|"FRI"|"SAT"
                },
                "daylightTime": {  // optional (not needed for fixed offsets)
                    "offset": 0,
                    "time": "03:00:00",
                    "month": "JAN"|"FEB"|"MAR"|"APR"|"JUN"|"JUL"|"AUG"|"SEP"|"OCT"|"NOV"|"DEC",
                    "week": "FIRST"|"SECOND"|"THIRD"|"FOURTH"|"LAST",
                    "dayOfWeek": "SUN"|"MON"|"TUE"|"WED"|"THU"|"FRI"|"SAT"
                },                
            },
            "workingPeriods":[{
                "startMinutes": 480,
                "endMinutes": 1040,
                "days": ["SUN"|"MON"|"TUE"|"WED"|"THU"|"FRI"|"SAT"]
            }]
        }
    },{
        "mailbox": "unknown@internal.example.com",
        "error": "MailboxNotFound"
    }]
}
```

响应由一个 *mailboxes* 部分组成，该部分包含邮箱列表。成功获取其可用性的每个邮箱均由三个部分组成：*mailbox*、*events* 和 *workinghours*。如果可用性提供商无法获取邮箱的可用性信息，则该部分由两个部分组成：*mailbox* 和 *error*。本指南的 [Mailbox](#cap_response_mailbox)、[Events](#cap_response_events)、[Working Hours](#cap_response_workinghours)、[Timezone](#cap_response_timezone)、[Working Periods](#cap_response_workingperiods) 和 [错误](#cap_response_error) 部分分别介绍了这些内容。

#### Mailbox
<a name="cap_response_mailbox"></a>

*mailbox* 部分是在请求的 *mailboxes* 部分中找到的用户的电子邮件地址。

#### Events
<a name="cap_response_events"></a>

*events* 部分是请求的窗口中发生的事件的列表。每个事件都使用以下参数进行定义：


| 字段 | 说明 | 必填 | 
| --- | --- | --- | 
| `startTime` | 事件的开始时间，采用 UTC 格式，并根据 [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) 设置格式。 | 是 | 
| `endTime` | 事件的结束时间，采用 UTC 格式，并根据 [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) 设置格式。 | 是 | 
| `busyType` | 事件的忙类型。可以是 `Busy`、`Free` 或 `Tentative`。 | 是 | 
| `details` | 事件的详细信息。 | 否 | 
| `details.subject` | 事件的主题。 | 是 | 
| `details.location` | 事件发生的位置。 | 是 | 
| `details.instanceType` | 事件的实例类型。可以是 `Single_Instance`、`Recurring_Instance` 或 `Exception`。 | 是 | 
| `details.isMeeting` | 一个布尔值，用于指示事件是否有参与者。 | 是 | 
| `details.isReminderSet` | 一个布尔值，用于指示事件是否设置了提醒。 | 是 | 
| `details.isPrivate` | 一个布尔值，用于指示事件是否设置为私有。 | 是 | 

#### Working Hours
<a name="cap_response_workinghours"></a>

*workingHours* 部分包含有关邮箱所有者的工作时间的信息。它包含两个部分：*timezone* 和 *workingPeriods*。

#### Timezone
<a name="cap_response_timezone"></a>

*timezone* 子部分说明了邮箱所有者所在的时区。当请求者在不同的时区工作时，正确呈现用户的工作时间非常重要。可用性提供商必须明确描述时区，而不是使用名称。使用标准化时区描述有助于避免时区不匹配。


| 字段 | 说明 | 必填 | 
| --- | --- | --- | 
| `name` | 时区的名称。 | 是 | 
| `bias` | 与 GMT 的默认偏移量（以分钟为单位）。 | 是 | 
| `standardTime` | 指定时区标准时间的开始时间。 | 否 | 
| `daylightTime` | 指定时区夏令时的开始时间。 | 否 | 

必须同时定义 `standardTime` 和 `daylightTime`，或者省略两者。`standardTime` 和 `daylightTime` 对象中的字段包括：


| 字段 | 说明 | 允许的值 | 
| --- | --- | --- | 
| `offset` | 相对于默认偏移量的偏移量（以分钟为单位）。 | NA | 
| `time` | 标准时间和夏令时之间发生转换的时间，指定为 `hh:mm:ss`。 | NA | 
| `month` | 标准时间和夏令时之间发生转换所在的月份。 | `JAN`,`FEB`, `MAR`, `APR`, `JUN`, `JUL`, `AUG`, `SEP`, `OCT`, `NOV`, `DEC` | 
| `week` | 指定月份内标准时间和夏令时之间发生转换所在的周。 | `FIRST`, `SECOND`, `THIRD`, `FOURTH`, `LAST` | 
| `dayOfWeek` | 指定周内标准时间和夏令时之间发生转换所在的当天。 | `SUN`, `MON`, `TUE`, `WED`, `THU`, `FRI`, `SAT` | 

#### Working Periods
<a name="cap_response_workingperiods"></a>

*workingPeriods* 部分包含一个或多个工作周期对象。每个周期定义一天或多天工作日的开始和结束。


| 字段 | 说明 | 允许的值 | 
| --- | --- | --- | 
| `startMinutes` | 工作日的开始，从午夜算起（以分钟为单位）。 | NA | 
| `endMinutes` | 工作日的结束，从午夜算起（以分钟为单位）。 | NA | 
| `days` | 此周期适用的工作日。 | `SUN`, `MON`, `TUE`, `WED`, `THU`, `FRI`, `SAT` | 

#### 错误
<a name="cap_response_error"></a>

*error* 字段可以包含任意错误消息。下表列出了已知代码到 EWS 错误代码的映射。所有其他消息都将映射到 `ERROR_FREE_BUSY_GENERATION_FAILED`。


| 值 | EWS 错误代码 | 
| --- | --- | 
| `MailboxNotFound` | `ERROR_MAIL_RECIPIENT_NOT_FOUND` | 
| `ErrorAvailabilityConfigNotFound` | `ERROR_AVAILABILITY_CONFIG_NOT_FOUND` | 
| `ErrorServerBusy` | `ERROR_SERVER_BUSY` | 
| `ErrorTimeoutExpired` | `ERROR_TIMEOUT_EXPIRED` | 
| `ErrorFreeBusyGenerationFailed` | `ERROR_FREE_BUSY_GENERATION_FAILED` | 
| `ErrorResponseSchemaValidation` | `ERROR_RESPONSE_SCHEMA_VALIDATION` | 

## 授予访问权限
<a name="granting_access"></a>

从 AWS Command Line Interface (AWS CLI) 运行以下 Lambda 命令。此命令可将资源策略添加到解析 CAP 的 Lambda 函数。此函数允许亚马逊 WorkMail 可用性服务调用您的 Lambda 函数。

```
aws lambda add-permission \
    --region {{LAMBDA_REGION}} \
    --function-name {{CAP_FUNCTION_NAME}} \
    --statement-id AllowWorkMail \
    --action "lambda:InvokeFunction" \
    --principal availability.workmail.{{WM_REGION}}.amazonaws.com \
    --source-account {{WM_ACCOUNT_ID}} \
    --source-arn arn:aws:workmail:{{WM_REGION}}:{{WM_ACCOUNT_ID}}:organization/{{ORGANIZATION_ID}}
```

在命令中，在指示的位置添加以下参数：
+ {{LAMBDA\_REGION}}— 部署 CAP Lambda 的区域的名称。例如 `us-east-1`。
+ {{CAP\_FUNCTION\_NAME}}— CAP Lambda 函数的名称。
**注意**  
这可以是 CAP Lambda 函数的名称、别名或者部分或全部 ARN。
+ {{WM\_REGION}}— 亚马逊 WorkMail 组织调用 Lambda 函数的区域名称。
**注意**  
只有以下区域可与 CAP 结合使用：  
美国东部（弗吉尼亚州北部）
美国西部（俄勒冈州）
欧洲地区（爱尔兰）
+ {{WM\_ACCOUNT\_ID}}— 组织账户的 ID。
+ {{ORGANIZATION\_ID}}— 调用 CAP Lambda 的组织的 ID。例如，组织 ID：m-934ebb9eb57145d0a6cab566ca81a21f。

**注意**  
{{LAMBDA\_REGION}}只有在{{WM\_REGION}}需要跨区域呼叫时才会有所不同。如果不需要跨区域调用，则它们将是相同的。

## 亚马逊 WorkMail 使用 CAP Lambda 函数的示例
<a name="cap_example_github"></a>

有关亚马逊 WorkMail 使用 CAP Lambda 函数查询 EWS 终端节点的示例，请参阅此关于*亚马逊存储库的无服务器应用程序的AWS *[示例应用程序](https://github.com/aws-samples/amazon-workmail-lambda-templates/tree/master/workmail-cap-exchange)。 WorkMail GitHub 