

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

# 使用 Amazon SES 设置电子邮件发送
<a name="send-email"></a>

您可以使用 Amazon SES 控制台、Amazon SES 简单邮件传输协议（SMTP）接口或 Amazon SES API，通过 Amazon Simple Email Service（Amazon SES）发送电子邮件。您通常使用控制台发送测试电子邮件和管理发送活动。要发送批量电子邮件，您使用 SMTP 接口或 API。有关 Amazon SES 电子邮件定价的信息，请参阅 SES [定价](https://aws.amazon.com/ses/pricing)。
+ 如果您要使用支持 SMTP 的软件包、应用程序或编程语言通过 Amazon SES 发送电子邮件，或者将 SES 与您的现有邮件服务器集成，请使用 Amazon SES SMTP 接口。有关更多信息，请参阅 [通过 Amazon SES SMTP 接口以编程方式来发送电子邮件](send-using-smtp-programmatically.md)。
+ 如果您要使用原始 HTTP 请求来调用 Amazon SES，请使用 Amazon SES API。有关更多信息，请参阅 [使用 Amazon SES API 发送电子邮件](send-email-api.md)。

**重要**  
如果您向多个收件人（收件人包括“收件人”、“抄送”和“密件抄送”地址）发送一封电子邮件，而对 Amazon SES 的调用失败，那么整个电子邮件将被拒绝，并且任何收件人都不会收到预期的电子邮件。因此，我们建议您一次向一个收件人发送一封电子邮件。

# 使用 Amazon SES SMTP 接口发送电子邮件
<a name="send-email-smtp"></a>

要通过 Amazon SES 发送生产电子邮件，您可以使用简单邮件传输协议（SMTP）接口或 Amazon SES API。有关 Amazon SES API 的更多信息，请参阅[使用 Amazon SES API 发送电子邮件](send-email-api.md)。此部分介绍了 SMTP 接口。

Amazon SES 使用 SMTP（Internet 上最常见的电子邮件协议）发送电子邮件。您可以使用各种支持 SMTP 的编程语言和软件连接到 Amazon SES SMTP 接口，来通过 Amazon SES 发送电子邮件。本节介绍如何获取 Amazon SES SMTP 凭证、如何使用 SMTP 接口发送电子邮件以及如何将多个软件和邮件服务器配置为使用 SES 发送电子邮件。

有关您在通过 Amazon SES 的 SMTP 接口使用 SES 可能遇到的常见问题的解决方法，请参阅[Amazon SES SMTP 问题](troubleshoot-smtp.md)。

## 通过 SMTP 发送电子邮件的要求
<a name="send-email-smtp-requirements"></a>

要使用 Amazon SES SMTP 接口发送电子邮件，您需要以下内容：
+ SMTP 端点地址。有关 Amazon SES SMTP 端点的列表，请参阅[连接到 Amazon SES SMTP 端点](smtp-connect.md)。
+ SMTP 接口端口号。端口号因连接方法而异。有关更多信息，请参阅 [连接到 Amazon SES SMTP 端点](smtp-connect.md)。
+ SMTP 用户名和密码。SMTP 凭证对每个 AWS 区域唯一。如果计划使用 SMTP 接口在多个 AWS 区域中发送电子邮件，您需获取各个区域的 SMTP 凭证。
**重要**  
您的 SMTP 凭证与您的 AWS 访问密钥或用于登录 Amazon SES 控制台的凭证不同。有关如何生成 SMTP 凭证的信息，请参阅[获取 Amazon SES SMTP 凭证](smtp-credentials.md)。
+ 可使用传输层安全性协议（TLS）进行通信的客户端软件。有关更多信息，请参阅 [连接到 Amazon SES SMTP 端点](smtp-connect.md)。
+ 您已使用 Amazon SES 验证的电子邮件地址。有关更多信息，请参阅 [Amazon SES 中已验证的身份](verify-addresses-and-domains.md)。
+ 如果您想发送大量电子邮件，请增加发送配额。有关更多信息，请参阅 [管理您的 Amazon SES 发送限制](manage-sending-quotas.md)。

## 通过 SMTP 发送电子邮件的方法
<a name="send-email-methods"></a>

您可以通过以下任一方法通过 SMTP 发送电子邮件：
+ 要将支持 SMTP 的软件配置为通过 Amazon SES SMTP 接口发送电子邮件，请参阅[使用软件包通过 Amazon SES 发送电子邮件](send-email-smtp-software-package.md)。
+ 要将应用程序编程为通过 Amazon SES 发送电子邮件，请参阅[通过 Amazon SES SMTP 接口以编程方式来发送电子邮件](send-using-smtp-programmatically.md)。
+ 要将现有电子邮件服务器配置为通过 Amazon SES 发送所有传出邮件，请参阅[将 Amazon SES 与您的现有电子邮件服务器集成](send-email-smtp-existing-server.md)。
+ 要使用命令行与 Amazon SES SMTP 接口进行交互（这对测试很有用），请参阅[使用命令行来测试与 Amazon SES SMTP 接口的连接](send-email-smtp-client-command-line.md)。

有关 SMTP 响应代码的列表，请参阅[由 Amazon SES 返回的 SMTP 响应代码](troubleshoot-smtp.md#troubleshoot-smtp-response-codes)。

## 要提供的电子邮件信息
<a name="smtp-parameters"></a>

当您通过 SMTP 接口访问 Amazon SES 时，您的 SMTP 客户端应用程序会汇编此邮件，因此您需要提供的信息取决于您所使用的应用程序。客户端与服务器之间的 SMTP 交换至少需要以下信息：
+ 源地址
+ 目标地址
+ 邮件数据

如果您使用的是 SMTP 接口，并且已启用反馈转发功能，则您的退信、投诉和送达通知将发送到“MAIL FROM”地址。不会使用您指定的任何“Reply-To”地址。



# 获取 Amazon SES SMTP 凭证
<a name="smtp-credentials"></a>

您需要 Amazon SES SMTP 凭证才能访问 SES SMTP 接口。

您用于通过 SES SMTP 接口发送电子邮件的凭证在每个 AWS 区域都是唯一的。如果您使用 SES SMTP 接口在多个区域中发送电子邮件，那么您必须为计划使用的每个区域生成一组 SMTP 凭证。

您的 SMTP 密码与您的 AWS 私有访问密钥不同。有关凭证的更多信息，请参阅[Amazon SES 凭证的类型](send-email-concepts-credentials.md)。

**注意**  
有关当前可用的 SMTP 端点的列表，请参阅 *AWS 一般参考* 中的 [SMTP 端点](https://docs.aws.amazon.com/general/latest/gr/ses.html#ses_smtp_endpoints)。

## 使用 SES 控制台获取 SES SMTP 凭证
<a name="smtp-credentials-console"></a>

**要求**  
IAM 用户可以创建 SES SMTP 凭证，但该用户的策略必须授予这些凭证使用 IAM 自身的权限，因为 SES SMTP 凭证是通过使用 IAM 创建的。您的 IAM 策略必须允许您执行以下 IAM 操作：`iam:ListUsers`、`iam:CreateUser`、`iam:CreateAccessKey` 和 `iam:PutUserPolicy`。如果您尝试使用控制台创建 SES SMTP 证书，但您的 IAM 用户没有这些权限，则会看到一条错误消息，指出您的账户 *“无权执行 iam:” ListUsers。*

**重要**  
上述引用的 IAM 操作具有[权限管理](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_understand-policy-summary-access-level-summaries.html#access_policies_access-level)访问级别，这是最高的 IAM 级别，因为它授予在服务中授予或修改资源权限的权限。因此，为了提高 AWS 账户的安全性，强烈建议您限制或定期监控这些包含权限管理访问级别分类的策略。

**创建 SMTP 凭证**

1. 登录 AWS 管理控制台 并打开 Amazon SES 控制台，网址为[https://console.aws.amazon.com/ses/](https://console.aws.amazon.com/ses/)。

1. 在左侧的导航窗格中选择 **SMTP settings**（SMTP 设置）- 这将打开 **Simple Mail Transfer Protocol (SMTP) settings** [简单邮件传输协议（SMTP）设置] 页面。

1. 选择右上角的 **Create SMTP Credentials**（创建 SMTP 凭证）- IAM 控制台将打开。

1. （可选）如果您需要查看、编辑或删除已创建的 SMTP 用户，请选择右下角的 **Manage my existing SMTP credentials**（管理我现有的 SMTP 凭证）-IAM 控制台将打开。按照以下步骤给出了用于管理 SMTP 凭证的详细信息。

1. 在**为 SMTP 创建用户**中，在 **IAM 用户名**字段中键入一个名称。或者，您可以使用此字段中提供的默认值。完成后，选择右下角的**创建用户**。

1. 选择 *SMTP 密码*下的**显示** - 您的 SMTP 凭证显示在屏幕上。

1. 通过选择**下载 .csv 文件**以下载这些凭证，或将其复制并存储在安全的位置，因为您在关闭此对话框之后无法查看或保存凭证。

1. 选择**返回 SES 控制台**。

您可以在 IAM 控制台的 **Access management**（访问管理）下查看使用此过程创建的 SMTP 凭证列表，并可以选择 **Users**（用户），然后使用搜索栏查找已分配 SMTP 凭证的所有用户。

您也可以使用 IAM 控制台来删除现有 SMTP 用户。要了解有关删除用户的更多信息，请参阅*《IAM 入门指南》*中的[管理 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html)。

如果您要更改 SMTP 密码，请在 IAM 控制台中删除现有 SMTP 用户。然后，要生成一组新 SMTP 凭证，请完成前面的过程。

## 通过转换现有 AWS 凭证获取 SES SMTP 凭证
<a name="smtp-credentials-convert"></a>

如果您有使用 IAM 接口设置的用户，则可以从其证书中派生该用户的 SES SMTP AWS 证书。

**重要**  
不要使用临时 AWS 证书来获取 SMTP 证书。SES SMTP 接口不支持从临时安全凭证生成的 SMTP 凭证。

**使 IAM 用户能够使用 SES SMTP 接口发送电子邮件**

1. 按照以下步骤，使用本节中提供的算法，从用户 AWS 凭证中派生出用户的 SMTP 凭据。

   由于您是从 AWS 凭据开始的，因此 SMTP 用户名与 AWS 访问密钥 ID 相同，因此您只需要生成 SMTP 密码即可。

1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在**访问管理**下，选择**策略**，然后选择**创建策略**。

1. 在**策略编辑器**中，选择 **JSON**，然后删除编辑器中的所有示例代码。

1. 将下面的策略粘贴到编辑器中。

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

****  

   ```
   {
   "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
   "Effect": "Allow",
               "Action": "ses:SendRawEmail",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 选择**下一步**，然后在**策略名称**字段中输入 `AmazonSesSendingAccess`，接着选择**创建策略**。

1. 在**访问管理**下，选择**用户组**，然后选择**创建组**。

1. 在**用户组名称**字段中，输入 `AWSSESSendingGroupDoNotRename`。

1. 从**将用户添加到组**表中选择 SMTP 用户，即可将其添加到组中。

1. 附加之前创建的 `AmazonSesSendingAccess` 策略，方法是从**附加权限策略**表中选择该策略，然后选择**创建用户组**。

有关将 SES 与 IAM 搭配使用的更多信息，请参阅[Amazon SES 中的 Identity and Access Management](control-user-access.md)。

**注意**  
尽管您可以为任何 IAM 用户生成 SES SMTP 凭证，但我们建议您在生成 SMTP 凭证时创建单独的 IAM 用户。有关为何说这是为特定目的创建用户的最佳实践的原因的信息，请参阅 [IAM 最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/IAMBestPractices.html)。

以下伪代码显示了将私有访问 AWS 密钥转换为 SES SMTP 密码的算法。

```
 1. // Modify this variable to include your AWS secret access key
 2. key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
 3.             
 4. // Modify this variable to refer to the AWS Region that you want to use to send email.
 5. region = "us-west-2";
 6.             
 7. // The values of the following variables should always stay the same.
 8. date = "11111111";
 9. service = "ses";
10. terminal = "aws4_request";
11. message = "SendRawEmail";
12. version = 0x04;
13. 
14. kDate = HmacSha256(date, "AWS4" + key);
15. kRegion = HmacSha256(region, kDate);
16. kService = HmacSha256(service, kRegion);
17. kTerminal = HmacSha256(terminal, kService);
18. kMessage = HmacSha256(message, kTerminal);
19. signatureAndVersion = Concatenate(version, kMessage);
20. smtpPassword = Base64(signatureAndVersion);
```

一些编程语言包括可用于将 IAM 秘密访问密钥转换为 SMTP 密码的库。本节包含一个代码示例，您可以使用该示例使用 Python 将私有访问 AWS 密钥转换为 SES SMTP 密码。

**注意**  
以下示例使用 Python 3.6 中推出的 **f-string**；如果使用较旧的版本，那么它们无法工作。
在以下示例中，SMTP\$1REGIONS 列表仅是一个示例——您的实际区域列表可能更短或更长，具体取决于您计划在哪些区域发送电子邮件，因为您需要每个 AWS 区域的 SMTP 凭证。

------
#### [ Python ]

```
#!/usr/bin/env python3

import hmac
import hashlib
import base64
import argparse

SMTP_REGIONS = [
    "us-east-2",  # US East (Ohio)
    "us-east-1",  # US East (N. Virginia)
    "us-west-2",  # US West (Oregon)
    "ap-south-1",  # Asia Pacific (Mumbai)
    "ap-northeast-2",  # Asia Pacific (Seoul)
    "ap-southeast-1",  # Asia Pacific (Singapore)
    "ap-southeast-2",  # Asia Pacific (Sydney)
    "ap-northeast-1",  # Asia Pacific (Tokyo)
    "ca-central-1",  # Canada (Central)
    "eu-central-1",  # Europe (Frankfurt)
    "eu-west-1",  # Europe (Ireland)
    "eu-west-2",  # Europe (London)
    "eu-south-1",  # Europe (Milan)
    "eu-north-1",  # Europe (Stockholm)
    "sa-east-1",  # South America (Sao Paulo)
    "us-gov-west-1",  # AWS GovCloud (US)
    "us-gov-east-1",  # AWS GovCloud (US)
]

# These values are required to calculate the signature. Do not change them.
DATE = "11111111"
SERVICE = "ses"
MESSAGE = "SendRawEmail"
TERMINAL = "aws4_request"
VERSION = 0x04


def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()


def calculate_key(secret_access_key, region):
    if region not in SMTP_REGIONS:
        raise ValueError(f"The {region} Region doesn't have an SMTP endpoint.")

    signature = sign(("AWS4" + secret_access_key).encode("utf-8"), DATE)
    signature = sign(signature, region)
    signature = sign(signature, SERVICE)
    signature = sign(signature, TERMINAL)
    signature = sign(signature, MESSAGE)
    signature_and_version = bytes([VERSION]) + signature
    smtp_password = base64.b64encode(signature_and_version)
    return smtp_password.decode("utf-8")


def main():
    parser = argparse.ArgumentParser(
        description="Convert a Secret Access Key to an SMTP password."
    )
    parser.add_argument("secret", help="The Secret Access Key to convert.")
    parser.add_argument(
        "region",
        help="The AWS Region where the SMTP password will be used.",
        choices=SMTP_REGIONS,
    )
    args = parser.parse_args()
    print(calculate_key(args.secret, args.region))


if __name__ == "__main__":
    main()
```

要使用此脚本来获取 SMTP 密码，请将前面的代码保存为 `smtp_credentials_generate.py`。然后，在命令行处，运行以下命令：

```
python path/to/smtp_credentials_generate.py wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY us-east-1
```

在上述命令中，执行以下操作：
+ *path/to/*替换为保存位置的路径`smtp_credentials_generate.py`。
+ 将 *wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY* 替换为您要转换为 SMTP 密码的秘密访问密钥。
+ *us-east-1*替换为您要在其中使用 SMTP 凭证的 AWS 区域。

当此脚本成功运行时，唯一的输出是您的 SMTP 密码。

------

## 将 SMTP 用户从现有内联策略迁移到组策略（安全建议）
<a name="migrate-inline-policy-to-group"></a>

**重要**  
如果您在 2024 年 9 月 6 日之前创建了 SES SMTP 凭证，则已将内联策略和标签附加到您的 SMTP 用户。SES 不再使用内联策略，并出于安全建议，鼓励您也这样做。

在将 SMTP 用户从现有内联策略迁移到组策略之前，必须先创建一个具有 SES 权限策略的 IAM 用户组来取代内联策略。如果您已创建了此 IAM 用户组，或者它是从 2024 年 9 月 6 日起为您创建的 SMTP 凭证自动创建的，则可以直接跳到以下过程中的*步骤 10*。

**从现有内联策略迁移到托管组**

1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在**访问管理**下，选择**策略**，然后选择**创建策略**。

1. 在**策略编辑器**中，选择 **JSON**，然后删除编辑器中的所有示例代码。

1. 将下面的策略粘贴到编辑器中。

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

****  

   ```
   {
   "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
   "Effect": "Allow",
               "Action": "ses:SendRawEmail",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 选择**下一步**，然后在**策略名称**字段中输入 `AmazonSesSendingAccess`，接着选择**创建策略**。

1. 在**访问管理**下，选择**用户组**，然后选择**创建组**。

1. 在**用户组名称**字段中，输入 `AWSSESSendingGroupDoNotRename`。

1. 从**将用户添加到组**表中选择 SMTP 用户，即可将其添加到组中。

1. 附加之前创建的 `AmazonSesSendingAccess` 策略，方法是从**附加权限策略**表中选择该策略，然后选择**创建用户组**。

   现在，您已使用 SES 权限策略创建了 IAM 用户组，您可以按照其余步骤中所述，将 SMTP 用户从其当前的内联策略迁移到该组策略。

1. 在**访问管理**下，选择**用户**，然后选择要迁移的 SMTP 用户。

1. 选择**组**选项卡，然后选择**将用户添加到多个组**。

1. 选择 `AWSSESSendingGroupDoNotRename` 组，然后选择**将用户添加到组**。

1. 选择**权限**选项卡，确认在**策略名称**列中列出的两行均显示 `AmazonSesSendingAccess`，其中一行在**通过如下方式附加**列中显示为*内联*，另一行显示为*组 `AWSSESSendingGroupDoNotRename`*。

1. 仅选择**策略名称**列包含 `AmazonSesSendingAccess` 且**通过如下方式附加**列显示为*内联*的行，然后选择**移除**，接着确认**移除策略**。

   验证**通过如下方式附加**列中显示为*组 `AWSSESSendingGroupDoNotRename`* 的行仍然存在。

1. 选择**标签**选项卡，然后选择**管理标签**。

1. 选择 “**键**” 列和 *SESConsole*“**值**” 列*InvokedBy*中包含的行旁边的 “**删除**”，然后选择 “**保存更改**”。

**重要**  
必须将 `AmazonSesSendingAccess` 策略（无论是作为内联策略还是组策略，或者两者兼有）保持附加到 SMTP 用户，以确保他们的发送不受影响。只有在将组策略附加到用户之后，才能移除内联策略。

# 连接到 Amazon SES SMTP 端点
<a name="smtp-connect"></a>

要使用 Amazon SES SMTP 接口来发送电子邮件，您将连接到 SMTP 端点。有关 Amazon SES SMTP 端点的完整列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service 端点和限额](https://docs.aws.amazon.com/general/latest/gr/ses.html)。

Amazon SES SMTP 终端节点要求使用传输层安全性（TLS）对所有连接进行加密。（请注意，提及 TLS 时通常使用其前身协议的名称：SSL）。Amazon SES 支持两种建立 TLS 加密连接的机制：STARTTLS 和 TLS Wrapper。查看您的软件文档，以确定它是支持 STARTTLS 或 TLS Wrapper，还是同时支持二者。

默认情况下，Amazon Elastic Compute Cloud（Amazon EC2）会节流端口 25 上的电子邮件流量。为了避免在通过 SMTP 端点从 EC2 发送电子邮件时发生超时，请提交[删除电子邮件发送限制的请求](https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request)以删除限制。或者，您也可以使用不同的端口发送电子邮件，或者使用 [Amazon VPC 端点](send-email-set-up-vpc-endpoints.md)。

有关 SMTP 连接问题，请参阅[SMTP 问题](troubleshoot-smtp.md)。

## STARTTLS
<a name="smtp-connect-starttls"></a>

STARTTLS 是一种将未加密的连接升级到加密连接的方式。提供了适用于各种协议的 STARTTLS 版本；SMTP 版本已在 [RFC 3207](https://www.ietf.org/rfc/rfc3207.txt) 中定义。

要设置 STARTTLS 连接，SMTP 客户端连接到端口 25、587 或 2587 上的 Amazon SES SMTP 端点，发出 EHLO 命令，然后等待服务器宣布其支持 STARTTLS SMTP 扩展。之后，该客户端发出 STARTTLS 命令，同时启动 TLS 协商。在协商完成后，该客户端将通过新的加密连接发出 EHLO 命令，并且 SMTP 会话将正常继续。

## TLS Wrapper
<a name="smtp-connect-tlswrapper"></a>

TLS Wrapper（也称为 SMTPS 或握手协议）是一种在无需事先建立未加密连接的情况下启动加密连接的方式。利用 TLS Wrapper，Amazon SES SMTP 端点不执行 TLS 协商：客户端负责使用 TLS 连接到端点，然后继续对整个对话使用 TLS。虽然 TLS Wrapper 是一项旧协议，但许多客户端仍支持它。

要设置 TLS Wrapper 连接，SMTP 客户端将连接到端口 465 或 2465 上的 Amazon SES SMTP 端点。服务器将提供其证书，客户端将发出 EHLO 命令，并且 SMTP 会话将正常继续。

# 使用软件包通过 Amazon SES 发送电子邮件
<a name="send-email-smtp-software-package"></a>

有大量支持通过 SMTP 发送电子邮件的商业开源软件包。下面是一些示例：
+ 博客平台
+ RSS 聚合器
+ 列表管理软件
+ 工作流系统

您可以将任何类似的支持 SMTP 的软件配置为通过 Amazon SES SMTP 接口发送电子邮件。有关如何为特定软件包配置 SMTP 的说明，请参阅该软件的相关文档。

以下过程介绍如何在 JIRA（一个常用的问题跟踪解决方案）中设置 Amazon SES 发送。利用此配置，JIRA 可以在软件问题的状态发生改变时通过电子邮件通知用户。

**将 JIRA 配置为使用 Amazon SES 发送电子邮件**

1. 借助 Web 浏览器，使用管理员凭证登录 JIRA。

1. 在浏览器窗口中，选择 **Administration**。

1. 在 **System** 菜单上，选择 **Mail**。

1. 在 **Mail administration** 页面上，选择 **Mail Servers**。

1. 选择 **Configure new SMTP mail server**。

1. 在 **Add SMTP Mail Server** 表单上，填写以下字段：

   1. **Name**：此服务器的描述性名称。

   1. **From address**（发件人地址）– 发送电子邮件的地址。您必须先使用 Amazon SES 验证该电子邮件地址，然后才能从该地址发送电子邮件。有关验证的更多信息，请参阅[Amazon SES 中已验证的身份](verify-addresses-and-domains.md)。

   1. **Email prefix**：JIRA 在发送前添加到每个主题行前面的字符串。

   1. **Protocol**：选择 **SMTP**。
**注意**  
如果您无法使用此设置连接到 Amazon SES，请试用 **SECURE\$1SMTP**。

   1. **Hostname (主机名称)**：有关 Amazon SES SMTP 端点的列表，请参阅[连接到 Amazon SES SMTP 端点](smtp-connect.md)。例如，如果您要在美国西部（俄勒冈州）区域中使用 Amazon SES 端点，那么主机名会是 *email-smtp.us-west-2.amazonaws.com*。

   1. **SMTP port**：25、587 或 2587 (使用 STARTTLS 进行连接) 或者 465 或 2465 (使用 TLS Wrapper 进行连接)。

   1. **TLS**：选中此复选框。

   1. **User name**：您的 SMTP 用户名。

   1. **Password**：您的 SMTP 密码。

   您可以在下图中看到 TLS Wrapper 的设置。  
![\[JIRA 的 SMTP 电子邮件配置\]](http://docs.aws.amazon.com/zh_cn/ses/latest/dg/images/SMTP_jira.png)

1. 选择**测试连接**。如果 JIRA 通过 Amazon SES 发送的测试电子邮件成功送达，则表示您的配置已完成。

# 通过 Amazon SES SMTP 接口以编程方式来发送电子邮件
<a name="send-using-smtp-programmatically"></a>

要使用 Amazon SES SMTP 接口来发送电子邮件，您可以使用支持 SMTP 的编程语言、电子邮件服务器或应用程序。在开启之前，请完成[设置 Amazon Simple Email Service](setting-up.md)中的任务。建议您了解以下信息：
+ 您的 Amazon SES SMTP 凭证，用于连接到 Amazon SES SMTP 端点。要获取您的 Amazon SES SMTP 凭证，请参阅[获取 Amazon SES SMTP 凭证](smtp-credentials.md)。
**重要**  
您的 SMTP 凭证与您的 AWS 凭证不同。有关凭证的更多信息，请参阅[Amazon SES 凭证的类型](send-email-concepts-credentials.md)。
+ SMTP 端点地址。有关 Amazon SES SMTP 端点的列表，请参阅[连接到 Amazon SES SMTP 端点](smtp-connect.md)。
+ Amazon SES SMTP 接口端口号，取决于连接方式。有关更多信息，请参阅 [连接到 Amazon SES SMTP 端点](smtp-connect.md)。

## 代码示例
<a name="send-email-smtp-code-examples"></a>

您可以使用支持 SMTP 的编程语言来访问 Amazon SES SMTP 接口。您可以提供 Amazon SES SMTP 主机名和端口号以及您的 SMTP 凭证，然后使用编程语言的一般 SMTP 函数来发送电子邮件。

默认情况下，Amazon Elastic Compute Cloud（Amazon EC2）会限制端口 25 上的电子邮件流量。为了避免在通过 SMTP 端点从 Amazon EC2 发送电子邮件时发生超时，您可以请求移除这些限制。有关更多信息，请参阅[如何从我的 Amazon EC2 实例或 AWS Lambda 函数中移除对端口 25 的限制？](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-port-25-throttle/) 在 AWS 知识中心中。

本节中的 Java 和 PHP 代码示例使用端口 587 来避免此问题。

**注意**  
在这些教程中，您将向自己发送电子邮件，以便检查是否收到了该电子邮件。如需进一步试验或进行负载测试，请使用 Amazon SES 邮箱模拟器。您发送到邮箱模拟器的电子邮件不会计入您的发送配额或您的退信率和投诉率。有关更多信息，请参阅 [手动使用邮箱模拟器](send-an-email-from-console.md#send-email-simulator)。

**选择一种编程语言以查看该语言的示例：**

**警告**  
Amazon SES 不建议使用静态凭证。请参阅 [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)，了解如何通过从源代码中移除硬编码的凭证来改善安全状况。本教程仅用于在非生产环境中测试 Amazon SES SMTP 接口。

------
#### [ Java ]

此示例使用 [Eclipse IDE](http://www.eclipse.org/) 和 [JavaMail API](https://github.com/javaee/javamail/releases) 使用 SMTP 接口通过 Amazon SES 发送电子邮件。

执行以下步骤之前，请完成 [设置 Amazon Simple Email Service](setting-up.md) 中的任务。

**将 Amazon SES SMTP 接口与 Java 结合使用来发送电子邮件**

1. 在 Web 浏览器中，转到该[JavaMail GitHub 页面](https://github.com/javaee/javamail/releases)。在 “**资产**” 下，选择 **javax.mail.jar** 以下载最新版本的。 JavaMail
**重要**  
本教程需要 JavaMail 版本 1.5 或更高版本。这些程序已使用 JavaMail 版本 1.6.1 进行了测试。

1. **在网络浏览器中，进入[雅加达激活 GitHub 页面，在 “激JavaBeans 活](https://github.com/eclipse-ee4j/jaf/releases)[框架 1.2.1 最终版本](https://github.com/eclipse-ee4j/jaf/releases/tag/1.2.1)” 下，下载 jakarta.activation.jar**

1. 通过执行以下步骤在 Eclipse 中创建项目：

   1. 启动 Eclipse。

   1. 在 Eclipse 中，依次选择 **File**、**New** 和 **Java Project**。

   1. 在 **Create a Java Project** 对话框中，键入项目名称，然后选择 **Next**。

   1. 在 **Java Settings** 对话框中，选择 **Libraries** 选项卡。

   1. ****选择 **Classpath**，然后使用添加外部按钮添加两个外部 jar 文件 j **avax.mail.jar 和 jakarta.activation.jar。** JARs****

   1. 选择 “**添加外部**” JARs。

   1. 浏览到您下载的文件夹 JavaMail。选择文件 `javax.mail.jar`，然后选择 **Open**。

   1. 在 **Java Settings** 对话框中，选择 **Finish**。

1. 在 Eclipse 中的 **Package Explorer** 窗口中，展开您的项目。

1. 在您的项目下，右键单击 **src** 目录，选择 **New**，然后选择 **Class**。

1. 在 **New Java Class** 对话框中的 **Name** 字段中，键入 `AmazonSESSample`，然后选择 **Finish**。

1. 将 **Amazon SESSample .java** 的全部内容替换为以下代码：

   ```
     1. import java.util.Properties;
     2. 
     3. import javax.mail.Message;
     4. import javax.mail.Session;
     5. import javax.mail.Transport;
     6. import javax.mail.internet.InternetAddress;
     7. import javax.mail.internet.MimeMessage;
     8. 
     9. public class AmazonSESSample {
    10. 
    11.     // Replace sender@example.com with your "From" address.
    12.     // This address must be verified.
    13.     static final String FROM = "sender@example.com";
    14.     static final String FROMNAME = "Sender Name";
    15.     
    16.     // Replace recipient@example.com with a "To" address. If your account 
    17.     // is still in the sandbox, this address must be verified.
    18.     static final String TO = "recipient@example.com";
    19.     
    20.     // Replace smtp_username with your Amazon SES SMTP user name.
    21.     static final String SMTP_USERNAME = "smtp_username";
    22.       
    23.     // The name of the Configuration Set to use for this message.
    24.     // If you comment out or remove this variable, you will also need to
    25.     // comment out or remove the header below.
    26.     static final String CONFIGSET = "ConfigSet";
    27.     
    28.     // Amazon SES SMTP host name. This example uses the US West (Oregon) region.
    29.     // See https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html#region-endpoints
    30.     // for more information.
    31.     static final String HOST = "email-smtp.us-west-2.amazonaws.com";
    32.     
    33.     // The port you will connect to on the Amazon SES SMTP endpoint. 
    34.     static final int PORT = 587;
    35.     
    36.     static final String SUBJECT = "Amazon SES test (SMTP interface accessed using Java)";
    37.     
    38.     static final String BODY = String.join(
    39.             System.getProperty("line.separator"),
    40.             "<h1>Amazon SES SMTP Email Test</h1>",
    41.             "<p>This email was sent with Amazon SES using the ", 
    42.             "<a href='https://github.com/javaee/javamail'>Javamail Package</a>",
    43.             " for <a href='https://www.java.com'>Java</a>."
    44.         );
    45. 
    46.     public static void main(String[] args) throws Exception {
    47. 
    48.         // Create a Properties object to contain connection configuration information.
    49.         Properties props = System.getProperties();
    50.         props.put("mail.transport.protocol", "smtp");
    51.         props.put("mail.smtp.port", PORT); 
    52.         props.put("mail.smtp.starttls.enable", "true");
    53.         props.put("mail.smtp.auth", "true");
    54. 
    55.         // Create a Session object to represent a mail session with the specified properties. 
    56.         Session session = Session.getDefaultInstance(props);
    57. 
    58.         // Create a message with the specified information. 
    59.         MimeMessage msg = new MimeMessage(session);
    60.         msg.setFrom(new InternetAddress(FROM,FROMNAME));
    61.         msg.setRecipient(Message.RecipientType.TO, new InternetAddress(TO));
    62.         msg.setSubject(SUBJECT);
    63.         msg.setContent(BODY,"text/html");
    64.         
    65.         // Add a configuration set header. Comment or delete the 
    66.         // next line if you are not using a configuration set
    67.         msg.setHeader("X-SES-CONFIGURATION-SET", CONFIGSET);
    68.             
    69.         // Create a transport.
    70.         Transport transport = session.getTransport();
    71. 
    72.         // Get the password 
    73.         String SMTP_PASSWORD = fetchSMTPPasswordFromSecureStorage();
    74.                     
    75.         // Send the message.
    76.         try
    77.         {
    78.             System.out.println("Sending...");
    79.             
    80.             // Connect to Amazon SES using the SMTP username and password you specified above.
    81.             transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
    82.             
    83.             // Send the email.
    84.             transport.sendMessage(msg, msg.getAllRecipients());
    85.             System.out.println("Email sent!");
    86.         }
    87.         catch (Exception ex) {
    88.             System.out.println("The email was not sent.");
    89.             System.out.println("Error message: " + ex.getMessage());
    90.         }
    91.         finally
    92.         {
    93.             // Close and terminate the connection.
    94.             transport.close();
    95.         }
    96.     }
    97. 
    98.     static String fetchSMTPPasswordFromSecureStorage() {
    99.         /* IMPLEMENT THIS METHOD */
   100.         // For example, you might fetch it from a secure location or AWS Secrets Manager: https://aws.amazon.com/secrets-manager/
   101.     }
   102. }
   ```

1. 在 **Amazon SESSample .java** 中，用您自己的值替换以下电子邮件地址：
**重要**  
电子邮件地址区分大小写。请确保此处的地址与经验证的地址完全相同。
   + *sender@example.com*— 替换为您的 “发件人” 电子邮件地址。运行此程序之前，您必须验证该地址。有关更多信息，请参阅 [Amazon SES 中已验证的身份](verify-addresses-and-domains.md)。
   + *recipient@example.com*— 替换为您的 “收件人” 电子邮件地址。如果您的账户仍处于沙盒中，您还必须验证此地址，然后才能使用它。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。

1. 在 **Amazon SESSample .java** 中，将以下内容替换为你自己的值：
   + *smtp\$1username*— 替换为您的 SMTP 用户名凭证。请注意，您的 SMTP 用户名凭证是一个 20 个字符的字母数字字符串，而不是可识别的名称。
   + *smtp\$1password*— ``fetchSMTPPasswordFromSecureStorage`` 实现获取密码。

1. （可选）如果您想在以 AWS 区域 外的地方使用 Amazon SES SMTP 终端节点*email-smtp.us-west-2.amazonaws.com*，请`HOST`将变量的值更改为您要使用的终端节点。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

1. （可选）如果要在发送此电子邮件时使用配置集，请将变量 *ConfigSet* 的值更改为配置集的名称。有关配置集的更多信息，请参阅[在 SES 中使用配置集](using-configuration-sets.md)。

1. 保存 **Amazon SESSample .java。**

1. 要构建项目，请选择 **Project**，然后选择 **Build Project**。（如果禁用此选项，则您可能已启用自动构建。）

1. 要开始程序和发送电子邮件，请选择 **Run**，然后再次选择 **Run**。

1. 检查输出。如果已成功发送电子邮件，则控制台会显示“*Email sent\$1*”。否则，将显示一条错误消息。

1. 登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------
#### [ PHP  ]

此示例使用该 PHPMailer 类通过 SMTP 接口通过 Amazon SES 发送电子邮件。

执行以下步骤之前，必须完成 [设置 Amazon Simple Email Service](setting-up.md) 中的任务。除了设置 Amazon SES，您还必须完成以下先决条件才能使用 PHP 发送电子邮件：

**先决条件：**
+ **安装 PHP**：访问 [http://php.net/downloads.php](https://php.net/downloads.php) 可获得 PHP。安装 PHP 后，在环境变量中添加 PHP 的路径，这样就能通过任何命令提示符运行 PHP。
+ **安装 Composer 依赖项管理器** — 安装 Composer 依赖项管理器后，您可以下载并安装该 PHPMailer 类及其依赖项。要安装 Composer，请按照 pos [https://getcomer.org/downlo](https://getcomposer.org/download) ad 上的安装说明进行操作。
+ **安装该 PHPMailer 类** — 安装 Composer 后，运行以下命令进行安装 PHPMailer：

  ```
  path/to/composer require phpmailer/phpmailer
  ```

  在前面的命令中，*path/to/*替换为安装 Composer 的路径。

**将 Amazon SES SMTP 接口与 PHP 结合使用来发送电子邮件**

1. 创建一个名为 **amazon-ses-smtp-sample.php** 的文件。使用文本编辑器打开文件并粘贴以下代码：

   ```
    1. <?php
    2. 
    3. // Import PHPMailer classes into the global namespace
    4. // These must be at the top of your script, not inside a function
    5. use PHPMailer\PHPMailer\PHPMailer;
    6. use PHPMailer\PHPMailer\Exception;
    7. 
    8. // If necessary, modify the path in the require statement below to refer to the
    9. // location of your Composer autoload.php file.
   10. require 'vendor/autoload.php';
   11. 
   12. // Replace sender@example.com with your "From" address.
   13. // This address must be verified with Amazon SES.
   14. $sender = 'sender@example.com';
   15. $senderName = 'Sender Name';
   16. 
   17. // Replace recipient@example.com with a "To" address. If your account
   18. // is still in the sandbox, this address must be verified.
   19. $recipient = 'recipient@example.com';
   20. 
   21. // Replace smtp_username with your Amazon SES SMTP user name.
   22. $usernameSmtp = 'smtp_username';
   23. 
   24. // Specify a configuration set. If you do not want to use a configuration
   25. // set, comment or remove the next line.
   26. $configurationSet = 'ConfigSet';
   27. 
   28. // If you're using Amazon SES in a region other than US West (Oregon),
   29. // replace email-smtp.us-west-2.amazonaws.com with the Amazon SES SMTP
   30. // endpoint in the appropriate region.
   31. $host = 'email-smtp.us-west-2.amazonaws.com';
   32. $port = 587;
   33. 
   34. // The subject line of the email
   35. $subject = 'Amazon SES test (SMTP interface accessed using PHP)';
   36. 
   37. // The plain-text body of the email
   38. $bodyText =  "Email Test\r\nThis email was sent through the
   39.     Amazon SES SMTP interface using the PHPMailer class.";
   40. 
   41. // The HTML-formatted body of the email
   42. $bodyHtml = '<h1>Email Test</h1>
   43.     <p>This email was sent through the
   44.     <a href="https://aws.amazon.com/ses">Amazon SES</a> SMTP
   45.     interface using the <a href="https://github.com/PHPMailer/PHPMailer">
   46.     PHPMailer</a> class.</p>';
   47. 
   48. $mail = new PHPMailer(true);
   49. 
   50. try {
   51.     // Specify the SMTP settings.
   52.     $mail->isSMTP();
   53.     $mail->setFrom($sender, $senderName);
   54.     $mail->Username   = $usernameSmtp;
   55.     $mail->Password   = fetchSMTPPasswordFromSecureStorage();
   56.     $mail->Host       = $host;
   57.     $mail->Port       = $port;
   58.     $mail->SMTPAuth   = true;
   59.     $mail->SMTPSecure = 'tls';
   60.     $mail->addCustomHeader('X-SES-CONFIGURATION-SET', $configurationSet);
   61. 
   62.     // Specify the message recipients.
   63.     $mail->addAddress($recipient);
   64.     // You can also add CC, BCC, and additional To recipients here.
   65. 
   66.     // Specify the content of the message.
   67.     $mail->isHTML(true);
   68.     $mail->Subject    = $subject;
   69.     $mail->Body       = $bodyHtml;
   70.     $mail->AltBody    = $bodyText;
   71.     $mail->Send();
   72.     echo "Email sent!" , PHP_EOL;
   73. } catch (phpmailerException $e) {
   74.     echo "An error occurred. {$e->errorMessage()}", PHP_EOL; //Catch errors from PHPMailer.
   75. } catch (Exception $e) {
   76.     echo "Email not sent. {$mail->ErrorInfo}", PHP_EOL; //Catch errors from Amazon SES.
   77. }
   78. function fetchSMTPPasswordFromSecureStorage() {
   79. /* IMPLEMENT THIS METHOD */
   80. // For example, you might fetch it from a secure location or AWS Secrets Manager: https://aws.amazon.com/secrets-manager/
   81. }
   82. 
   83. ?>
   ```

1. 在 **amazon-ses-smtp-sample.php** 中，用你自己的值替换以下内容：
   + *sender@example.com*— 替换为您已通过 Amazon SES 验证的电子邮件地址。有关更多信息，请参阅 [已验证的身份](verify-addresses-and-domains.md)。Amazon SES 中的电子邮件地址区分大小写。请确保您输入的地址与经验证的地址完全相同。
   + *recipient@example.com*— 替换为收件人的地址。如果您的账户仍处于沙盒中，您还必须验证此地址，然后才能使用它。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。请确保您输入的地址与经验证的地址完全相同。
   + *smtp\$1username*— 替换为您从 Amazon SES 控制台的 [SMTP 设置页面获得的 SMTP](https://console.aws.amazon.com/ses/home?#smtp-settings:) 用户名证书。这与您的 ** 访问密钥 ID **不同 AWS 。请注意，您的 SMTP 用户名凭证是一个 20 个字符的字母数字字符串，而不是可识别的名称。
   + *smtp\$1password*— ``fetchSMTPPasswordFromSecureStorage`` 实现获取密码。
   + （可选）*ConfigSet*— 如果您想在发送此电子邮件时使用配置集，请将此值替换为配置集的名称。有关配置集的更多信息，请参阅[在 SES 中使用配置集](using-configuration-sets.md)。
   + （可选）*email-smtp.us-west-2.amazonaws.com*— 如果您想在美国西部（俄勒冈）以外的地区使用 Amazon SES SMTP 终端节点，请将其替换为您要使用的区域中的 Amazon SES SMTP 终端节点。有关可用 Amazon SES 的 SMTP 终端节点 URLs 列表，请参阅中的 AWS 区域 [亚马逊简单电子邮件服务 (Amazon SES) Service](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。*AWS 一般参考*

1. 保存 **amazon-ses-smtp-sample.php。**

1. 要运行该程序，请在与 **amazon-ses-smtp-sample.php** 相同的目录中打开命令提示符，然后键入**php amazon-ses-smtp-sample.php**。

1. 检查输出。如果已成功发送电子邮件，则控制台会显示“*Email sent\$1*”。否则，将显示一条错误消息。

1. 登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------

# 将 Amazon SES 与您的现有电子邮件服务器集成
<a name="send-email-smtp-existing-server"></a>

如果您目前管理自己的电子邮件服务器，那么您可以使用 Amazon SES SMTP 端点将所有传出电子邮件发送到 Amazon SES。您无需修改现有电子邮件客户端和应用程序；转换到 Amazon SES 的过程对它们来说是透明的。

一些邮件传输代理 (MTAs) 支持通过 SMTP 中继发送电子邮件。本节提供一般指导，说明如何配置一些常 MTAs 用的电子邮件以使用 Amazon SES SMTP 接口发送电子邮件。

Amazon SES SMTP 端点要求使用传输层安全性（TLS）对所有连接进行加密。

**Topics**
+ [将 Amazon SES 与 Postfix 集成](postfix.md)
+ [将 Amazon SES 与 Sendmail 集成](send-email-sendmail.md)
+ [将 Amazon SES 与 Microsoft Windows Server IIS SMTP 集成](send-email-windows-server.md)

# 将 Amazon SES 与 Postfix 集成
<a name="postfix"></a>

Postfix 是广泛使用的 Sendmail 邮件传输代理（MTA）的替代品。有关 Postfix 的更多信息，请转到 [http://www.postfix.org](http://www.postfix.org)。本主题中的步骤适用于 Linux、macOS 或 Unix。

**注意**  
Postfix 是第三方应用程序，不由 Amazon Web Services 开发或支持。本节中的步骤仅供参考，如有变更，恕不另行通知。

## 先决条件
<a name="send-email-postfix-prereqs"></a>

完成此部分中的过程之前，必须先执行以下任务：
+ 卸载 Sendmail 应用程序（如果它已安装在您的系统中）。根据您使用的不同操作系统，完成此步骤的过程会有差异。
**重要**  
以下对 *sendmail* 的引用指的是 Postfix 命令 `sendmail`，不要与 Sendmail 应用程序混淆。
+ 安装 Postfix。根据您使用的不同操作系统，完成此步骤的过程会有差异。
+ 安装 SASL 身份验证软件包。根据您使用的不同操作系统，完成此步骤的过程会有差异。例如，如果您使用 RedHat基于系统的系统，则应安装该`cyrus-sasl-plain`软件包。如果您使用基于 Debian 或 Ubuntu 的系统，则应安装 `libsasl2-modules` 软件包。
+ 验证您用来发送电子邮件的电子邮件地址或域。有关更多信息，请参阅 [创建电子邮件地址身份](creating-identities.md#verify-email-addresses-procedure)。
+ 如果您的账户仍处于沙盒中，您只能将电子邮件发送到已验证的电子邮件地址。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。

## 配置 Postfix
<a name="send-email-postfix"></a>

完成以下步骤来配置您的邮件服务器，以使用 Postfix 通过 Amazon SES 发送电子邮件。

**配置 Postfix**

1. 在命令行处，键入以下命令：

   ```
   sudo postconf -e "relayhost = [email-smtp.us-west-2.amazonaws.com]:587" \
   "smtp_sasl_auth_enable = yes" \
   "smtp_sasl_security_options = noanonymous" \
   "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \
   "smtp_use_tls = yes" \
   "smtp_tls_security_level = secure" \
   "smtp_tls_note_starttls_offer = yes"
   ```
**注意**  
如果您在美国西部（俄勒冈）以外的 AWS 地区使用 Amazon SES，请将前面的命令替换*email-smtp.us-west-2.amazonaws.com*为相应区域的 SMTP 终端节点。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

1. 在文本编辑器中，打开 `/etc/postfix/master.cf`文件。搜索以下条目：

   ```
   -o smtp_fallback_relay=
   ```

   如果找到此条目，请在行首放置 `#`（井号）字符将其注释掉。保存并关闭 文件。

   如果此条目不存在，请继续下一个步骤。

1. 在文本编辑器中，打开 `/etc/postfix/sasl_passwd`文件。如果该文件尚不存在，请创建它。

1. 将以下行添加到 `/etc/postfix/sasl_passwd`：

   ```
   [email-smtp.us-west-2.amazonaws.com]:587 SMTPUSERNAME:SMTPPASSWORD
   ```
**注意**  
将*SMTPUSERNAME*和*SMTPPASSWORD*替换为您的 SMTP 登录凭据。您的 SMTP 登录凭证与您的 AWS 访问密钥 ID 和秘密访问密钥不同。有关凭证的更多信息，请参阅[获取 Amazon SES SMTP 凭证](smtp-credentials.md)。  
如果您在美国西部（俄勒冈）以外的 AWS 地区使用 Amazon SES，请使用相应区域的 SMTP 终端节点替换上述示例*email-smtp.us-west-2.amazonaws.com*中的终端节点。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

   是否保存并关闭 `sasl_passwd`。

1. 在命令提示符处，键入以下命令以创建一个包含您的 SMTP 凭证的 Hashmap 数据库文件：

   ```
   sudo postmap hash:/etc/postfix/sasl_passwd
   ```

1. （可选）您在之前的步骤中创建的 `/etc/postfix/sasl_passwd` 和 `/etc/postfix/sasl_passwd.db` 文件未加密。由于这些文件包含您的 SMTP 凭证，我们建议您修改这些文件的所有权和权限以限制对它们的访问。要限制对这些文件的访问，请执行以下操作：

   1. 在命令提示符处，键入以下命令以更改文件的所有权：

      ```
      sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
      ```

   1. 在命令提示符处，键入以下命令以更改文件的权限，以便仅根用户可读取和写入它们：

      ```
      sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
      ```

1. 告诉 Postfix 在何处查找 CA 证书（需要使用它来验证 Amazon SES 服务器证书）。您在此步骤中使用的命令因所用操作系统而异。
   + 如果您使用 Amazon Linux、Red Hat Enterprise Linux 或相关分发，请键入以下命令：

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'
     ```
   + 如果您使用 Ubuntu 或相关分发，请键入以下命令：

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt'
     ```
   + 如果您使用 macOS，则可通过您的系统密钥链生成证书。要生成证书，请在命令行处键入以下命令：

     ```
     sudo security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain | sudo tee /etc/ssl/certs/ca-bundle.crt > /dev/null
     ```

     生成证书之后，请键入以下命令：

     ```
     sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt'
     ```

1. 键入以下命令以启动 Postfix 服务器（或在服务器已在运行的情况下，重新加载配置设置）：

   ```
   sudo postfix start; sudo postfix reload
   ```

1. 在命令行键入以下命令并在每行后按 Enter 以发送测试电子邮件。*sender@example.com*替换为您的 “发件人” 电子邮件地址。From (发件人) 地址必须经过验证才能用于 Amazon SES。*recipient@example.com*替换为目标地址。如果您的账户仍处于沙盒中，则还必须验证收件人地址。最后，邮件最后一行只能包含一个句点 (.)，不能再有其他内容。

   ```
   sendmail -f sender@example.com recipient@example.com
   From: Sender Name <sender@example.com>
   Subject: Amazon SES Test                
   This message was sent using Amazon SES.                
   .
   ```

1. 检查与收件人地址关联的邮箱。如果未收到电子邮件，请检查您的垃圾邮件文件夹。如果您仍然无法找到电子邮件，请检查用于发送电子邮件的系统上的邮件日志（通常位于 `/var/log/maillog`）以了解更多信息。

## 高级使用示例
<a name="send-email-postfix-advanced"></a>

此示例演示如何发送使用[配置集](using-configuration-sets.md)的电子邮件，以及如何使用 MIME 多部分编码发送纯文本和 HTML 版本的消息以及附件。它还包含一个[链接标签](faqs-metrics.md#sending-metric-faqs-clicks-q5)，可用于为单击事件分类。电子邮件的内容将在一个外部文件中指定，因此您不必在 Postfix 会话中手动键入命令。

**使用 Postfix 发送多部分 MIME 电子邮件**

1. 在文本编辑器中，创建一个名为 `mime-email.txt` 的新文件。

1. 在文本文件中，粘贴以下内容，并将红色的值替换为适用于您的账户的值：

   ```
   X-SES-CONFIGURATION-SET: ConfigSet
   From:Sender Name <sender@example.com>
   Subject:Amazon SES Test
   MIME-Version: 1.0
   Content-Type: multipart/mixed; boundary="YWVhZDFlY2QzMGQ2N2U0YTZmODU"
   
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU
   Content-Type: multipart/alternative; boundary="3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ"
   
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ
   Content-Type: text/plain; charset=UTF-8
   Content-Transfer-Encoding: quoted-printable
   
   Amazon SES Test
   
   This message was sent from Amazon SES using the SMTP interface.
   
   For more information, see:
   http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html
   
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ
   Content-Type: text/html; charset=UTF-8
   Content-Transfer-Encoding: quoted-printable
   
   <html>
     <head>
   </head>
     <body>
       <h1>Amazon SES Test</h1>
         <p>This message was sent from Amazon SES using the SMTP interface.</p>
         <p>For more information, see
         <a ses:tags="samplekey0:samplevalue0;samplekey1:samplevalue1;" 
         href="http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html">
         Using the Amazon SES SMTP Interface to Send Email</a> in the <em>Amazon SES
         Developer Guide</em>.</p>
     </body>
   </html>
   --3NjM0N2QwMTE4MWQ0ZTg2NTYxZQ--
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU
   Content-Type: application/octet-stream
   MIME-Version: 1.0
   Content-Transfer-Encoding: base64
   Content-Disposition: attachment; filename="customers.txt"
   
   SUQsRmlyc3ROYW1lLExhc3ROYW1lLENvdW50cnkKMzQ4LEpvaG4sU3RpbGVzLENh
   bmFkYQo5MjM4OSxKaWUsTGl1LENoaW5hCjczNCxTaGlybGV5LFJvZHJpZ3VleixV
   bml0ZWQgU3RhdGVzCjI4OTMsQW5heWEsSXllbmdhcixJbmRpYQ==
   --YWVhZDFlY2QzMGQ2N2U0YTZmODU--
   ```

   保存并关闭 文件。

1. 在命令行处，键入以下命令。*sender@example.com*替换为您的电子邮件地址，然后*recipient@example.com*替换为收件人的电子邮件地址。

   ```
   sendmail -f sender@example.com recipient@example.com < mime-email.txt
   ```

   如果该命令成功运行，它将退出并且不提供任何输出。

1. 查看收件箱中是否有该电子邮件。如果该邮件未送达，请查看系统的邮件日志。

# 将 Amazon SES 与 Sendmail 集成
<a name="send-email-sendmail"></a>

Sendmail 最初于 20 世纪 80 年代初发布，此后一直在不断改进。这是一个灵活且可配置的邮件传输代理 (MTA) 并拥有大型的用户社群。Sendmail 于 2013 年被 Proofpoint 收购，但 Proofpoint 继续提供开源版本的 Sendmail。您可以从 Proofpoint 网站或通过大多数 Linux 发行版的程序包管理器下载 [Sendmail 的开源版本](https://www.proofpoint.com/us/open-source-email-solution)。

本节中的操作步骤说明如何配置 Sendmail 以通过 Amazon SES 发送电子邮件。已在运行 Ubuntu 18.04.2 LTS 的服务器上测试此过程。

**注意**  
Sendmail 是第三方应用程序，不由 Amazon Web Services 开发或支持。本节中的步骤仅供参考，如有变更，恕不另行通知。

## 先决条件
<a name="send-email-sendmail-prerequisites"></a>

在完成本节中的过程之前，您应完成以下步骤：
+ 在您的服务器上安装 Sendmail 程序包。
**注意**  
根据您使用的操作系统发行版，可能还需要安装以下程序包：`sendmail-cf`、`m4` 和 `cyrus-sasl-plain`。
+ 验证要用作“From（发件人）”地址的身份。有关更多信息，请参阅 [创建电子邮件地址身份](creating-identities.md#verify-email-addresses-procedure)。

  如果您的账户仍在 Amazon SES 沙盒中，那么您还必须验证您将电子邮件发送到的地址。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。

如果您使用 Amazon SES 从 Amazon EC2 实例发送电子邮件，那么您还应该完成以下步骤：
+ 您可能需要将弹性 IP 地址发送到 Amazon EC2 实例，以便接收电子邮件提供商接受您的电子邮件。有关更多信息，请参阅《Amazon EC2 用户指南》**中的 [Amazon EC2 弹性 IP 地址](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)。
+ 默认情况下，Amazon Elastic Compute Cloud（Amazon EC2）会限制端口 25 上的电子邮件流量。为了避免在通过 SMTP 端点从 Amazon EC2 发送电子邮件时发生超时，您可以请求移除这些限制。有关更多信息，请参阅[如何从我的 Amazon EC2 实例或 AWS Lambda 函数中移除对端口 25 的限制？](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-port-25-throttle/) 在 AWS 知识中心中。

  或者，您可以修改本节中的操作步骤，以使用端口 587 而不是端口 25。

## 配置 Sendmail
<a name="send-email-sendmail-procedure"></a>

完成本节中的步骤，通过使用 Amazon SES 配置 Sendmail 来发送电子邮件。

**重要**  
本节中的步骤假设您想在美国西部（俄勒冈）使用 Amazon SES AWS 区域。如果您要使用其他区域，请将此过程中的所有 *email-smtp.us-west-2.amazonaws.com* 实例替换为所需区域的 SMTP 端点。有关可用 Amazon SES 的 SMTP 终端节点 URLs 列表，请参阅中的 AWS 区域 [亚马逊简单电子邮件服务 (Amazon SES) Service](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。*AWS 一般参考*

**配置 Sendmail**

1. 在文件编辑器中，打开文件 `/etc/mail/authinfo`。如果该文件不存在，请创建它。

   在*/*中添加以下行etc/mail/authinfo：

   ```
   AuthInfo:email-smtp.us-west-2.amazonaws.com "U:root" "I:smtpUsername" "P:smtpPassword" "M:PLAIN"
   ```

   在前面的示例中，进行以下更改：
   + *email-smtp.us-west-2.amazonaws.com*替换为您要使用的 Amazon SES SMTP 终端节点。
   + *smtpUsername*替换为您的 Amazon SES SMTP 用户名。
   + *smtpPassword*替换为您的 Amazon SES SMTP 密码。
**注意**  
您的 SMTP 登录凭据不同于您的 AWS 访问密钥 ID 和私有访问密钥。有关获取您的 SMTP 登录凭证的更多信息，请参阅[获取 Amazon SES SMTP 凭证](smtp-credentials.md)。

   完成后，保存 `authinfo`。

1. 在命令行中，输入以下命令可生成 `/etc/mail/authinfo.db` 文件：

   ```
   sudo sh -c 'makemap hash /etc/mail/authinfo.db < /etc/mail/authinfo'
   ```

1. 在命令行中，键入以下命令可添加对中继到 Amazon SES SMTP 端点的支持。

   ```
   sudo sh -c 'echo "Connect:email-smtp.us-west-2.amazonaws.com RELAY" >> /etc/mail/access'
   ```

   在前面的命令中，*email-smtp.us-west-2.amazonaws.com*替换为您要使用的 Amazon SES SMTP 终端节点的地址。

1. 在命令行中，键入以下命令以重新生成*/etc/mail/access.db*：

   ```
   sudo sh -c 'makemap hash /etc/mail/access.db < /etc/mail/access'
   ```

1. 在命令行中，键入以下命令可创建 `sendmail.cf` 和 `sendmail.mc` 文件的备份：

   ```
   sudo sh -c 'cp /etc/mail/sendmail.cf /etc/mail/sendmail_cf.backup && cp /etc/mail/sendmail.mc /etc/mail/sendmail_mc.backup'
   ```

1. 将以下几行添加到*/etc/mail/sendmail.mc* 文件中，然后再进行任何`MAILER()`定义。

   ```
   define(`SMART_HOST', `email-smtp.us-west-2.amazonaws.com')dnl
   define(`RELAY_MAILER_ARGS', `TCP $h 25')dnl
   define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
   FEATURE(`authinfo', `hash -o /etc/mail/authinfo.db')dnl
   MASQUERADE_AS(`example.com')dnl
   FEATURE(masquerade_envelope)dnl
   FEATURE(masquerade_entire_domain)dnl
   ```

   在上述文本中，执行以下操作：
   + *email-smtp.us-west-2.amazonaws.com*替换为您要使用的 Amazon SES SMTP 终端节点。
   + *example.com*替换为您要用于发送电子邮件的域名。

   完成后，保存该文件。
**注意**  
Amazon EC2 默认情况下限制端口 25 上的通信。如果您在 Amazon EC2 实例中使用 Sendmail，则应完成[请求删除电子邮件发送限制](https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request)。

1. 在命令行中，键入以下命令可将 *sendmail.cf* 设为可写：

   ```
   sudo chmod 666 /etc/mail/sendmail.cf
   ```

1. 在命令行中，键入以下命令可重新生成 *sendmail.cf*：

   ```
   sudo sh -c 'm4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf'
   ```
**注意**  
如果您遇到“Command not found（找不到命令）”和“No such file or directory（无此类文件或目录）”等错误，请确保您的系统上安装了 `m4` 和 `sendmail-cf` 程序包。

1. 在命令行中，键入以下命令可将 *sendmail.cf* 的权限重置为只读：

   ```
   sudo chmod 644 /etc/mail/sendmail.cf
   ```

1. 在命令行中，键入以下命令可重新启动 Sendmail：

   ```
   sudo /etc/init.d/sendmail restart
   ```

   *如果上述方法不起作用，请尝试以下操作，具体取决于 Linux 或 Sendmail 的版本：*

   ```
   sudo su service sendmail restart
   ```

1. 完成以下步骤可发送测试电子邮件：

   1. 在命令行输入以下命令。

      ```
      /usr/sbin/sendmail -vf sender@example.com recipient@example.com
      ```

      *sender@example.com*替换为您的 “发件人” 电子邮件地址。*recipient@example.com*替换为收件人地址。完成后，按 Enter。

   1. 输入以下消息内容。在每行的结尾处按 Enter。

      ```
      From: sender@example.com
      To: recipient@example.com
      Subject: Amazon SES test email
      
      This is a test message sent from Amazon SES using Sendmail.
      ```

      在输入完电子邮件内容后，按 Ctrl\$1D 发送电子邮件。

1. 检查收件人的电子邮件客户端是否收到这封电子邮件。如果您无法找到电子邮件，请检查垃圾邮件文件夹。如果您仍无法找到电子邮件，请查看邮件服务器上的 Sendmail 日志。日志通常位于*/var/log/mail.log* 或*/var/log/maillog*。

# 将 Amazon SES 与 Microsoft Windows Server IIS SMTP 集成
<a name="send-email-windows-server"></a>

您可以将 Microsoft Windows Server 的 IIS SMTP 服务器配置为通过 Amazon SES 发送电子邮件。这些说明是在亚马逊 EC2 实例上使用微软 Windows Server 2022 编写的。您可以在 Microsoft Windows Server 2016 上使用相同的配置。

**注意**  
Windows Server 是第三方应用程序，不由 Amazon Web Services 开发或支持。本节中的步骤仅供参考，如有变更，恕不另行通知。

**将 Microsoft Windows Server IIS SMTP 服务器与 Amazon SES 集成**

1. 首先，按照以下说明设置微软 Windows Server 2022。

   1. 从[亚马逊 EC2 管理控制台](https://console.aws.amazon.com/ec2/home)启动新的微软 Windows Server 2022 Base 亚马逊 EC2 实例。

   1. 按照 [Amazon EC2 Windows 实例入门](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2Win_GetStarted.html)中的说明，使用远程桌面连接到实例并登录。

   1. 启动服务器管理器控制面板。

   1. 安装 **Web Server** 角色。请确保包含 **IIS 10 Management Compatibility tools**（**Web Server** 复选框下的一个选项）。

   1. 安装 **SMTP Server** 特征。

1. 接下来，使用以下说明配置 IIS SMTP 服务。

   1. 返回到服务器管理器控制面板。

   1. 从 **Tools（工具）**菜单中，选择 **Internet Information Services（IIS）10.0 Manager**。

   1. 右键单击 **SMTP Virtual Server \$11**，然后选择 **Properties**。

   1. 在 **Access** 选项卡的 **Relay Restrictions** 下，选择 **Relay**。

   1. 在 **Relay Restrictions** 对话框中，选择 **Add**。

   1. 在 **Single Computer** 下，输入 **127.0.0.1** 作为 IP 地址。您现在已授予此服务器访问权限，以通过 IIS SMTP 服务将电子邮件中继到 Amazon SES。

      在此过程中，我们假定电子邮件是在此服务器上生成的。如果生成电子邮件的应用程序在其他服务器上运行，则您必须在 IIS SMTP 中为该服务器授予中继访问权限。
**注意**  
要将 SMTP 中继扩展到私有子网，对于 **Relay Restriction**，请使用 **Single Computer** 127.0.0.1 和 **Group of Computers** 172.1.1.0：255.255.255.0（在网络掩码部分中）。在 **Connection**（连接）中，请使用 **Single Computer** 127.0.0.1 和 **Group of Computers** 172.1.1.0：255.255.255.0（在网络掩码部分中）。

1. 最后，使用以下说明将服务器配置为通过 Amazon SES 发送电子邮件。

   1. 返回到 **SMTP Virtual Server \$11 Properties** 对话框，然后选择 **Delivery** 选项卡。

   1. 在 **Delivery** 选项卡上，选择 **Outbound Security**。

   1. 选择 **Basic Authentication**（基本身份验证），然后输入您的 Amazon SES SMTP 凭证。您可以使用[获取 Amazon SES SMTP 凭证](smtp-credentials.md)中的过程从 Amazon SES 控制台获取这些凭证。
**重要**  
您的 SMTP 凭证与您的 AWS 访问密钥 ID 和私有访问密钥不同。请勿尝试使用您的 AWS 凭据通过 SMTP 端点对自己进行身份验证。有关凭证的更多信息，请参阅[Amazon SES 凭证的类型](send-email-concepts-credentials.md)。

   1. 确保已选中 **TLS encryption**。

   1. 返回到 **Delivery** 选项卡。

   1. 选择 **Outbound Connections**。

   1. 在 **Outbound Connections** 对话框中，确保端口为 25 或 587。

   1. 选择 **Advanced**（高级）。

   1. 对于 **Smart host**（智能主机）名称，输入您将使用的 Amazon SES 端点（例如，*email-smtp.us-west-2.amazonaws.com*）。有关可用 Amazon SES URLs AWS 区域 的终端节点列表，请参阅中的[*AWS 一般参考*亚马逊简单电子邮件服务 (Amazon SES)](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region) Service。

   1. 返回到服务器管理器控制面板。

   1. 在服务器管理器控制面板上，右键单击 **SMTP Virtual Server \$11**，然后重新启动该服务以选择新配置。

   1. 通过此服务器发送电子邮件。您可以检查邮件标头，以确认邮件已通过 Amazon SES 送达。

# 使用命令行来测试与 Amazon SES SMTP 接口的连接
<a name="send-email-smtp-client-command-line"></a>

您可以从命令行使用本节中介绍的方法来测试与 Amazon SES SMTP 端点的连接、验证 SMTP 凭证以及解决连接问题。这些过程将使用大多数常见操作系统附带的工具和库。

有关解决 SMTP 连接问题的其他信息，请参阅 [Amazon SES SMTP 问题](troubleshoot-smtp.md)。

## 先决条件
<a name="send-email-smtp-client-command-line-prereqs"></a>

在连接到 Amazon SES SMTP 接口时，您必须提供一组 SMTP 凭证。这些 SMTP 凭证不同于您的标准 AWS 凭证。这两种类型的凭证不可互换。有关获取您的 SMTP 凭证的更多信息，请参阅[获取 Amazon SES SMTP 凭证](smtp-credentials.md)。

## 测试到 Amazon SES SMTP 接口的连接
<a name="send-email-smtp-client-command-line-testing"></a>

您可以使用命令行来测试您到 Amazon SES SMTP 接口的连接，而无需验证或发送任何消息。此过程可用于基本连接问题的故障排除。如果测试连接失败，请参阅[SMTP 问题](troubleshoot-smtp.md)。

本节包括使用 OpenSSL（大多数 Linux、macOS 和 Unix 发行版中都包含此功能，也适用于 Windows）和中的 `Test-NetConnection` cmdlet PowerShell （包含在最新版本的 Windows 中）测试连接的过程。

------
#### [ Linux, macOS, or Unix ]

可通过两种方式使用 OpenSSL 连接到 Amazon SES SMTP 接口：在端口 587 上使用显式 SSL，或在端口 465 上使用隐式 SSL。

**使用显式 SSL 连接到 SMTP 接口**
+ 在命令行上，输入以下命令来连接到 Amazon SES SMTP 服务器：

  ```
  openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.us-west-2.amazonaws.com:587
  ```

  在前面的命令中，*email-smtp.us-west-2.amazonaws.com*替换为您所在 AWS 地区的 Amazon SES SMTP 终端节点的网址。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

  如果连接成功，则将显示类似于以下内容的输出：

  ```
  depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
  verify return:1
  depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
  verify return:1
  depth=0 CN = email-smtp.us-west-2.amazonaws.com
  verify return:1
  250 Ok
  ```

  连接会在处于不活动状态大约 10 秒后自动关闭。

或者，您可以使用隐式 SSL 通过端口 465 连接到 SMTP 接口。

**使用隐式 SSL 连接到 SMTP 接口**
+ 在命令行上，输入以下命令来连接到 Amazon SES SMTP 服务器：

  ```
  openssl s_client -crlf -quiet -connect email-smtp.us-west-2.amazonaws.com:465
  ```

  在前面的命令中，*email-smtp.us-west-2.amazonaws.com*替换为您所在 AWS 地区的 Amazon SES SMTP 终端节点的网址。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

  如果连接成功，则将显示类似于以下内容的输出：

  ```
  depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
  verify return:1
  depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
  verify return:1
  depth=0 CN = email-smtp.us-west-2.amazonaws.com
  verify return:1
  220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-VCSHDP1YZ A1b2C3d4E5f6G7h8I9j0
  ```

  连接会在处于不活动状态大约 10 秒后自动关闭。

------
#### [ PowerShell ]

你可以使用 T [est-NetConnection](https://docs.microsoft.com/en-us/powershell/module/nettcpip/test-netconnection) cmdlet 连接 PowerShell 到 Amazon SES SMTP 服务器。

**注意**  
`Test-NetConnection` cmdlet 可以确定您的计算机是否能连接到 Amazon SES SMTP 端点。但是，它不会测试您的计算机是否能建立与 SMTP 端点的隐式或显式 SSL 连接。要测试 SSL 连接，您可以安装 OpenSSL for Windows 来发送测试电子邮件。

**使用 `Test-NetConnection` cmdlet 连接到 SMTP 接口**
+ 在中 PowerShell，输入以下命令连接到 Amazon SES SMTP 服务器：

  ```
  Test-NetConnection -Port 587 -ComputerName email-smtp.us-west-2.amazonaws.com
  ```

  在前面的命令中，*email-smtp.us-west-2.amazonaws.com*替换为您所在 AWS 地区的 Amazon SES SMTP 终端节点的 URL，并*587*替换为端口号。有关 Amazon SES 中的区域端点的更多信息，请参阅[区域和 Amazon SES](regions.md)。

  如果连接成功，您会看到与以下示例类似的输出：

  ```
  ComputerName     : email-smtp.us-west-2.amazonaws.com
  RemoteAddress    : 198.51.100.126
  RemotePort       : 587
  InterfaceAlias   : Ethernet
  SourceAddress    : 203.0.113.46
  TcpTestSucceeded : True
  ```

------

## 使用命令行通过 Amazon SES SMTP 接口发送电子邮件
<a name="send-email-using-openssl"></a>

您也可以使用命令行通过 Amazon SES SMTP 接口发送邮件。此过程对于测试 SMTP 凭证以及测试特定收件人能否接收您使用 Amazon SES 发送的消息非常有用。

------
#### [ Linux, macOS, or Unix ]

当电子邮件发件人连接到 SMTP 服务器时，客户端会发出一组标准请求，而服务器会使用标准响应来回复每个请求。这一系列的请求和响应称为 *SMTP 对话*。当您使用 OpenSSL 连接到 Amazon SES SMTP 服务器时，服务器需要进行 SMTP 对话。

在使用 OpenSSL 连接到 SMTP 接口时，您必须使用 base64 编码对 SMTP 凭证进行编码。此部分包含使用 base64 对凭证进行编码的过程。

**从命令行使用 SMTP 接口发送电子邮件**

1. 在命令行中输入以下内容，并*email-smtp.us-west-2.amazonaws.com*替换为您的 Amazon SES SMTP 终端节点的 AWS 区域 URL。有关更多信息，请参阅[区域和 Amazon SES](regions.md)。 :

   ```
    1. #!/bin/bash
    2. 
    3. # Prompt user to provide following information
    4. read -p "Configuration set: " CONFIGSET
    5. read -p "Enter SMTP username: " SMTPUsername
    6. read -p "Enter SMTP password: " SMTPPassword
    7. read -p "Sender email address: " MAILFROM
    8. read -p "Receiver email address: " RCPT
    9. read -p "Email subject: " SUBJECT
   10. read -p "Message to send: " DATA
   11. 
   12. echo
   13. 
   14. # Encode SMTP username and password using base64
   15. EncodedSMTPUsername=$(echo -n "$SMTPUsername" | openssl enc -base64)
   16. EncodedSMTPPassword=$(echo -n "$SMTPPassword" | openssl enc -base64)
   17. 
   18. # Construct the email
   19. Email="EHLO example.com
   20. AUTH LOGIN
   21. $EncodedSMTPUsername
   22. $EncodedSMTPPassword
   23. MAIL FROM: $MAILFROM
   24. RCPT TO: $RCPT
   25. DATA
   26. X-SES-CONFIGURATION-SET: $CONFIGSET
   27. From: $MAILFROM
   28. To: $RCPT
   29. Subject: $SUBJECT
   30. 
   31. $DATA
   32. .
   33. QUIT"
   34. 
   35. echo "$Email" | openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.us-west-2.amazonaws.com:587
   ```

1. 在提示输入每个变量时，输入您的值。

1. 
   + 要通过端口 465 使用隐式 SSL 发送，请使用：

     ```
     openssl s_client -crlf -quiet -connect email-smtp.us-west-2.amazonaws.com:465
     ```

   如果消息已被 Amazon SES 接受，您将看到与以下示例类似的输出：

   ```
   250 Ok 01010160d7de98d8-21e57d9a-JZho-416c-bbe1-8ebaAexample-000000
   ```

   `250 Ok` 后面的数字和文本字符串是电子邮件的邮件 ID。
**注意**  
连接会在处于不活动状态大约 10 秒后自动关闭。

------
#### [ PowerShell ]

你可以使用 [Net.Mail。 SmtpClient](https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=netframework-4.8)使用显式 SSL 通过端口 587 发送电子邮件的类。

**注意**  
`Net.Mail.SmtpClient` 类已正式被弃用，Microsoft 建议您使用第三方库。此代码仅用于测试目的，而不应用于生产工作负载。

**PowerShell 使用显式 SSL 发送电子邮件**

1. 在文本编辑器中，创建一个新文件。将以下代码粘贴到该文件中：

   ```
   function SendEmail($Server, $Port, $Sender, $Recipient, $Subject, $Body) {
       $Credentials = [Net.NetworkCredential](Get-Credential)
   
       $SMTPClient = New-Object Net.Mail.SmtpClient($Server, $Port)
       $SMTPClient.EnableSsl = $true
       $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Credentials.Username, $Credentials.Password);
   
       try {
           Write-Output "Sending message..."
           $SMTPClient.Send($Sender, $Recipient, $Subject, $Body)
           Write-Output "Message successfully sent to $($Recipient)"
       } catch [System.Exception] {
           Write-Output "An error occurred:"
           Write-Error $_
       }
   }
   
   function SendTestEmail(){
       $Server = "email-smtp.us-west-2.amazonaws.com"
       $Port = 587
   
       $Subject = "Test email sent from Amazon SES"
       $Body = "This message was sent from Amazon SES using PowerShell (explicit SSL, port 587)."
   
       $Sender = "sender@example.com"
       $Recipient = "recipient@example.com"
   
       SendEmail $Server $Port $Sender $Recipient $Subject $Body
   }
   
   SendTestEmail
   ```

   完成后，将文件另存为 `SendEmail.ps1`。

1. 对您在上一步中创建的文件进行以下更改：
   + *sender@example.com*替换为您要从中发送消息的电子邮件地址。
   + *recipient@example.com*替换为您要向其发送消息的电子邮件地址。
   + *email-smtp.us-west-2.amazonaws.com*替换为您所在 AWS 地区的 Amazon SES SMTP 终端节点的网址。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

1. 在中 PowerShell，输入以下命令：

   ```
   .\path\to\SendEmail.ps1
   ```

   在前面的命令中，*path\$1to\$1SendEmail.ps1*替换为您在步骤 1 中创建的文件的路径。

1. 在系统提示时，输入您的 SMTP 用户名和密码。

或者，你可以使用 [System.Web.Mail。 SmtpMail](https://docs.microsoft.com/en-us/dotnet/api/system.web.mail.smtpmail?view=netframework-4.8)使用隐式 SSL 通过端口 465 发送电子邮件的类。

**注意**  
`System.Web.Mail.SmtpMail` 类已正式被弃用，Microsoft 建议您使用第三方库。此代码仅用于测试目的，而不应用于生产工作负载。

**PowerShell 使用隐式 SSL 发送电子邮件**

1. 在文本编辑器中，创建一个新文件。将以下代码粘贴到该文件中：

   ```
   [System.Reflection.Assembly]::LoadWithPartialName("System.Web") > $null
   
   function SendEmail($Server, $Port, $Sender, $Recipient, $Subject, $Body) {
       $Credentials = [Net.NetworkCredential](Get-Credential)
   
       $mail = New-Object System.Web.Mail.MailMessage
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserver", $Server)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", $Port)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", $true)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", $Credentials.UserName)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", $Credentials.Password)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout", $timeout / 1000)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusing", 2)
       $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1)
   
       $mail.From = $Sender
       $mail.To = $Recipient
       $mail.Subject = $Subject
       $mail.Body = $Body
   
       try {
           Write-Output "Sending message..."
           [System.Web.Mail.SmtpMail]::Send($mail)
           Write-Output "Message successfully sent to $($Recipient)"
       } catch [System.Exception] {
           Write-Output "An error occurred:"
           Write-Error $_
       }
   }
   
   function SendTestEmail(){
       $Server = "email-smtp.us-west-2.amazonaws.com"
       $Port = 465
       
       $Subject = "Test email sent from Amazon SES"
       $Body = "This message was sent from Amazon SES using PowerShell (implicit SSL, port 465)."
   
       $Sender = "sender@example.com"
       $Recipient = "recipient@example.com"
   
       SendEmail $Server $Port $Sender $Recipient $Subject $Body
   }
   
   SendTestEmail
   ```

   完成后，将文件另存为 `SendEmail.ps1`。

1. 对您在上一步中创建的文件进行以下更改：
   + *sender@example.com*替换为您要从中发送消息的电子邮件地址。
   + *recipient@example.com*替换为您要向其发送消息的电子邮件地址。
   + *email-smtp.us-west-2.amazonaws.com*替换为您所在 AWS 地区的 Amazon SES SMTP 终端节点的网址。有关更多信息，请参阅 [区域和 Amazon SES](regions.md)。

1. 在中 PowerShell，输入以下命令：

   ```
   .\path\to\SendEmail.ps1
   ```

   在前面的命令中，*path\$1to\$1SendEmail.ps1*替换为您在步骤 1 中创建的文件的路径。

1. 在系统提示时，输入您的 SMTP 用户名和密码。

------

# 使用 Amazon SES API 发送电子邮件
<a name="send-email-api"></a>

要通过 Amazon SES 发送生产电子邮件，您可以使用简单邮件传输协议（SMTP）接口或 Amazon SES API。有关 SMTP 接口的更多信息，请参阅[使用 Amazon SES SMTP 接口发送电子邮件](send-email-smtp.md)。此部分介绍如何使用 API 发送电子邮件。

当您使用 Amazon SES API 发送电子邮件时，您可以指定邮件的内容，而 Amazon SES 会为您汇编 MIME 电子邮件。或者，您可以自行组装电子邮件，以便完全控制邮件的内容。有关 API 的更多信息，请参阅 [Amazon Simple Email Service API 参考](https://docs.aws.amazon.com/ses/latest/APIReference/)。有关可用 Amazon SES 的终端节点 URLs 列表，请参阅中的[亚马逊简单电子邮件服务终端节点和配额*AWS 一般参考*](https://docs.aws.amazon.com/general/latest/gr/ses.html)。 AWS 区域 

您可通过以下方式调用 API：
+ **发出直接 HTTPS 请求：**这是最先进的方法，因为您必须手动处理您的请求的身份验证和签名，然后手动构建请求。有关 Amazon SES API 的信息，请参阅 *API v2 参考*中的[欢迎](https://docs.aws.amazon.com/ses/latest/APIReference-V2/Welcome.html)页面。
+ **使用 AWS 软件开发工具包 —**AWS SDKs 便于访问多种 AWS 服务，包括 Amazon SES。 APIs 当您使用开发工具包时，它会负责身份验证、请求签名、重试逻辑、错误处理以及其他低级功能，以便您可以专注于构建让客户满意的应用程序。
+ **使用命令行接口：**[AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是 Amazon SES 的命令行工具。我们还[ PowerShell为那些在 PowerShell环境中编写脚本的人提供AWS 工具](https://aws.amazon.com/powershell/)。

无论您是直接访问 Amazon SES API 还是通过 AWS 软件开发工具包、 AWS Command Line Interface 或 AWS 工具间接访问 Amazon SES API，Amazon SES API 都为您提供了两种不同的发送电子邮件的方式，具体取决于您对电子邮件构成的控制程度： PowerShell
+ **已设置格式：**Amazon SES 编写并发送格式正确的电子邮件。您只需提供 From: (发件人:) 和 To: (收件人:) 地址、主题和邮件正文。Amazon SES 将负责完成所有余下工作。有关更多信息，请参阅 [使用 Amazon SES API 发送格式化的电子邮件](send-email-formatted.md)。
+ **原始 - **您手动编写和发送电子邮件，并指定您自己的电子邮件标头和 MIME 类型。如果您在设置自己的电子邮件格式方面有经验，则原始接口会为您提供对邮件内容的更多控制。有关更多信息，请参阅 [使用 Amazon SES API v2 发送原始电子邮件](send-email-raw.md)。

**Topics**
+ [使用 Amazon SES API 发送格式化的电子邮件](send-email-formatted.md)
+ [使用 Amazon SES API v2 发送原始电子邮件](send-email-raw.md)
+ [使用模板通过 Amazon SES API 发送个性化电子邮件](send-personalized-email-api.md)
+ [使用软件开发工具包通过 Amazon AWS SES 发送电子邮件](send-an-email-using-sdk-programmatically.md)
+ [Amazon SES 支持的内容编码](content-encodings.md)

# 使用 Amazon SES API 发送格式化的电子邮件
<a name="send-email-formatted"></a>

您可以使用 AWS 管理控制台 或通过应用程序直接调用 Amazon SES API 来发送格式化电子邮件，也可以通过软件开发工具包间接调用 Amazon AWS SES API AWS Command Line Interface、或 AWS Tools for Windows PowerShell。

Amazon SES API 提供 `SendEmail` 操作，让您能够编写和发送格式化电子邮件。`SendEmail` 需要发件人地址、收件人地址、邮件主题和邮件正文（文本和/或 HTML）。有关更多信息，请参阅 [SendEmail](https://docs.aws.amazon.com/ses/latest/APIReference/API_SendEmail.html)（API 参考）或 [SendEmail](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html)（API v2 参考）。

**注意**  
电子邮件地址字符串必须为 7 位 ASCII 字符。如果您希望向或从某个地址的域部分中包含 Unicode 字符的电子邮件地址发送邮件，则必须使用 Punycode 对域进行编码。有关更多信息，请参见 [RFC 3492](https://tools.ietf.org/html/rfc3492)。

有关如何使用各种编程语言编写格式化邮件的示例，请参阅 [代码示例](send-an-email-using-sdk-programmatically.md#send-an-email-using-sdk-programmatically-examples)。

有关对 `SendEmail` 进行多个调用时如何加快电子邮件发送速度的提示，请参阅[增加 Amazon SES 吞吐量](troubleshoot-throughput-problems.md)。

# 使用 Amazon SES API v2 发送原始电子邮件
<a name="send-email-raw"></a>

您可以通过内容类型指定为 `raw` 的 Amazon SES API v2 `SendEmail` 操作，使用原始电子邮件格式向收件人发送自定义消息。

## 关于电子邮件标头字段
<a name="send-email-raw-headers"></a>

简单邮件传输协议（SMTP）通过定义邮件信封及其部分参数来指定电子邮件将如何发送，但它本身与邮件内容无关。相反，Internet 邮件格式（[RFC 5322](https://www.ietf.org/rfc/rfc5322.txt)）定义了如何创建邮件。

根据 Internet 邮件格式规范，每封电子邮件都包含标题和正文。标题包含邮件元数据，正文包含邮件本身。有关电子邮件标题和正文的更多信息，请参阅[Amazon SES 中的电子邮件格式](send-email-concepts-email-format.md)。

## 使用原始电子邮件 MIME 消息构建
<a name="send-email-raw-mime"></a>

SMTP 协议最初设计用于发送仅包含 7 位 ASCII 字符的电子邮件。此规范使得 SMTP 不足以应对非 ASCII 文本编码（如 Unicode）、二进制内容或附件。多用途 Internet 邮件扩展标准（MIME）是为了能够使用 SMTP 发送许多其他种类的内容而制定的。

MIME 标准的工作方式是将邮件正文拆分为多个段，然后指定要对每个段执行的操作。例如，电子邮件正文的一个段可能是纯文本，另一个段可能是 HTML。此外，MIME 还允许电子邮件包含一个或多个附件。邮件收件人可以在电子邮件客户端内查看附件，也可以保存附件。

邮件标题和内容由一个空白行分隔。电子邮件的每个段都由一个边界（表示每个段的开头和末尾的一个字符串）分隔。

以下示例中的多段邮件包含文本、HTML 部分和附件。附件应放在[附件标题](#send-email-mime-encoding-files)的正下方，并且通常按照该示例中所示采用 `base64` 编码。

```
 1. From: "Sender Name" <sender@example.com>
 2. To: recipient@example.com
 3. Subject: Customer service contact info
 4. Content-Type: multipart/mixed;
 5.     boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"
 6. 
 7. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
 8. Content-Type: multipart/alternative;
 9.     boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"
10. 
11. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
12. Content-Type: text/plain; charset=iso-8859-1
13. Content-Transfer-Encoding: quoted-printable
14. 
15. Please see the attached file for a list of customers to contact.
16. 
17. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
18. Content-Type: text/html; charset=iso-8859-1
19. Content-Transfer-Encoding: quoted-printable
20. 
21. <html>
22. <head></head>
23. <body>
24. <h1>Hello!</h1>
25. <p>Please see the attached file for a list of customers to contact.</p>
26. </body>
27. </html>
28. 
29. --sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
30. 
31. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
32. Content-Type: text/plain; name="customers.txt"
33. Content-Description: customers.txt
34. Content-Disposition: attachment;filename="customers.txt";
35.     creation-date="Sat, 05 Aug 2017 19:35:36 GMT";
36. Content-Transfer-Encoding: base64
37. 
38. SUQsRmlyc3ROYW1lLExhc3ROYW1lLENvdW50cnkKMzQ4LEpvaG4sU3RpbGVzLENhbmFkYQo5MjM4
39. OSxKaWUsTGl1LENoaW5hCjczNCxTaGlybGV5LFJvZHJpZ3VleixVbml0ZWQgU3RhdGVzCjI4OTMs
40. QW5heWEsSXllbmdhcixJbmRpYQ==
41. 
42. --a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
```

邮件的内容类型为 `multipart/mixed`，这表示邮件有很多个段（在本例中为一个正文和一个附件），且接收客户端必须单独处理每个段。

还有一个嵌套在正文部分中的段，该段使用 `multipart/alternative` 内容类型。此内容类型表示每个段都包含同一内容的替代版本（在本例中为一个文本版本和一个 HTML 版本）。如果收件人的电子邮件客户端可以显示 HTML 内容，则它显示邮件正文的 HTML 版本。如果收件人的电子邮件客户端无法显示 HTML 内容，则它显示邮件正文的纯文本版本。

邮件的两个版本还将包含一个附件（在本例中为包含一些客户名称的短文本文件）。

当您将一个 MIME 段嵌套在另一个段中时（如本示例所示），嵌套的段必须使用与父段中的 `boundary` 参数不同的 `boundary` 参数。这些边界应该是唯一的字符串。要定义 MIME 段之间的边界，请键入两个连字符 (--) 后跟边界字符串。在 MIME 段的末尾，在边界字符串的开头和末尾处放置两个连字符。

**注意**  
一封邮件的 MIME 部分不得超过 500 个。

### MIME 编码
<a name="send-email-mime-encoding"></a>

为了保持与旧系统的兼容性，Amazon SES 遵循 [RFC 2821](https://tools.ietf.org/html/rfc2821) 中定义的 SMTP 7 位 ASCII 限制。如果要发送包含非 ASCII 字符的内容，则必须将这些字符编码为使用 7 位 ASCII 字符的格式。

#### 电子邮件地址
<a name="send-email-mime-encoding-addresses"></a>

电子邮件地址字符串必须为 7 位 ASCII 字符。如果您希望向或从某个地址的域部分中包含 Unicode 字符的电子邮件地址发送邮件，则必须使用 Punycode 对域进行编码。不允许在电子邮件地址的本地部分（@ 符号前面的部分）中使用 Punycode，也不允许在“易记发件人”名称中使用。如果要在“易记发件人”名称中使用 Unicode 字符，必须使用 MIME 编码字语法进行编码“易记发件人”名称，如本节所述。有关 Punycode 的更多信息，请参阅 [RFC 3492](http://tools.ietf.org/html/rfc3492)。

**注意**  
此规则仅适用于您在邮件信封中指定的电子邮件地址，不适用于邮件标头。使用 Amazon SES API v2 `SendEmail` 操作时，您在 `Source` 和 `Destinations` 参数中指定的地址分别定义信封发件人和收件人。

#### 电子邮件标头
<a name="send-email-mime-encoding-headers"></a>

要对邮件标头进行编码，请使用 MIME encoded-word 语法。MIME encoded-word 语法使用以下格式：

```
=?charset?encoding?encoded-text?=
```

`encoding` 的值可以是 `Q` 或 `B`。如果编码值为 `Q`，则 `encoded-text` 的值必须使用 Q 编码。如果编码值为 `B`，则 `encoded-text` 的值必须使用 base64 编码。

例如，如果您要在电子邮件的主题行中使用字符串“Як ти поживаєш?”，那么您可以使用以下任一编码：
+ **Q 编码**

  ```
  =?utf-8?Q?=D0=AF=D0=BA_=D1=82=D0=B8_=D0=BF=D0=BE=D0=B6=D0=B8=D0=B2=D0=B0=D1=94=D1=88=3F?=
  ```
+ **Base64 编码**

  ```
  =?utf-8?B?0K/QuiDRgtC4INC/0L7QttC40LLQsNGU0Yg/?=
  ```

有关 Q 编码的更多信息，请参阅 [RFC 2047](https://tools.ietf.org/html/rfc2047)。有关 base64 编码的更多信息，请参阅 [RFC 2045](https://tools.ietf.org/html/rfc2045)。

#### 消息正文
<a name="send-email-mime-encoding-body"></a>

要对邮件正文进行编码，可以使用 quoted-printable 编码或 base64 编码。然后，使用 `Content-Transfer-Encoding` 标头指示您使用的编码方案。

例如，假设邮件正文包含以下文本：

१९७२ मे रे टॉमलिंसन ने पहला ई-मेल संदेश भेजा \$1 रे टॉमलिंसन ने ही सर्वप्रथम @ चिन्ह का चयन किया और इन्ही को ईमेल का आविष्कारक माना जाता है

如果选择使用 base64 编码对此文本进行编码，请首先指定以下标头：

```
Content-Transfer-Encoding: base64
```

然后，在电子邮件的正文部分中，包含 base64 编码的文本：

```
4KWn4KWv4KWt4KWoIOCkruClhyDgpLDgpYcg4KSf4KWJ4KSu4KSy4KS/4KSC4KS44KSoIOCkqOCl
hyDgpKrgpLngpLLgpL4g4KSILeCkruClh+CksiDgpLjgpILgpKbgpYfgpLYg4KSt4KWH4KSc4KS+
IHwg4KSw4KWHIOCkn+ClieCkruCksuCkv+CkguCkuOCkqCDgpKjgpYcg4KS54KWAIOCkuOCksOCl
jeCkteCkquCljeCksOCkpeCkriBAIOCkmuCkv+CkqOCljeCkuSDgpJXgpL4g4KSa4KSv4KSoIOCk
leCkv+Ckr+CkviDgpJTgpLAg4KSH4KSo4KWN4KS54KWAIOCkleCliyDgpIjgpK7gpYfgpLIg4KSV
4KS+IOCkhuCkteCkv+Ckt+CljeCkleCkvuCksOCklSDgpK7gpL7gpKjgpL4g4KSc4KS+4KSk4KS+
IOCkueCliAo=
```

**注意**  
在某些情况下，您可以在使用 Amazon SES 发送的邮件中使用 8 位 `Content-Transfer-Encoding`。但是，如果 Amazon SES 必须对邮件进行任何更改（例如，当您使用[打开和单击跟踪](faqs-metrics.md)）时，8 位编码的内容在到达收件人的收件箱时可能无法正确显示。因此，您应始终对不是 7 位 ASCII 的内容进行编码。

#### 文件附件
<a name="send-email-mime-encoding-files"></a>

要将文件附加到电子邮件，您必须使用 base64 编码对附件进行编码。附件通常放在专用的 MIME 邮件部分中，其中包括以下标头：
+ **Content-Type**：附件的文件类型。以下是常见 MIME Content-Type 声明的示例：
  + **纯文本文件**：`Content-Type: text/plain; name="sample.txt"`
  + **Microsoft Word 文档**：`Content-Type: application/msword; name="document.docx"`
  + **JPG 图像**：`Content-Type: image/jpeg; name="photo.jpeg"`
+ **Content-Disposition**：指定收件人的电子邮件客户端应如何处理内容。对于附件，此值为 `Content-Disposition: attachment`。
+ **Content-Transfer-Encoding**：用于对附件进行编码的方案。对于文件附件，此值几乎总是 `base64`。
+ **编码的附件**：您必须对实际附件进行编码，并将其包含在附件标题下方的正文中，[如示例所示](#send-email-raw-mime)。

Amazon SES 接受最常见的文件类型。有关 Amazon SES 不接受的文件类型的列表，请参阅[SES 不支持的附件类型](attachments.md#mime-types)。

## 使用 Amazon SES API v2 发送原始电子邮件
<a name="send-email-raw-api"></a>

Amazon SES API v2 提供 `SendEmail` 操作，当您将内容类型设置为简单、原始或模板化时，该操作使您可以指定的格式编写和发送电子邮件。有关的完整说明，请参阅 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html)。以下示例将内容类型指定为 `raw`，以使用原始电子邮件格式发送消息。

**注意**  
有关对 `SendEmail` 进行多个调用时如何加快电子邮件发送速度的提示，请参阅[增加 Amazon SES 吞吐量](troubleshoot-throughput-problems.md)。

邮件正文必须包含格式正确的原始电子邮件，后者具有适当的标头字段和邮件正文编码。尽管能够在应用程序内手动构建原始邮件，但使用现有邮件库执行此操作轻松得多。

------
#### [ Java ]

以下代码示例说明如何使用[JavaMail](https://javaee.github.io/javamail/)库和[适用于 Java 的 AWS SDK](https://aws.amazon.com/sdk-for-java)来撰写和发送原始电子邮件。

```
  1. package com.amazonaws.samples;
  2. 
  3. import java.io.ByteArrayOutputStream;
  4. import java.io.IOException;
  5. import java.io.PrintStream;
  6. import java.nio.ByteBuffer;
  7. import java.util.Properties;
  8. 
  9. // JavaMail libraries. Download the JavaMail API 
 10. // from https://javaee.github.io/javamail/
 11. import javax.activation.DataHandler;
 12. import javax.activation.DataSource;
 13. import javax.activation.FileDataSource;
 14. import javax.mail.Message;
 15. import javax.mail.MessagingException;
 16. import javax.mail.Session;
 17. import javax.mail.internet.AddressException;
 18. import javax.mail.internet.InternetAddress;
 19. import javax.mail.internet.MimeBodyPart;
 20. import javax.mail.internet.MimeMessage;
 21. import javax.mail.internet.MimeMultipart;
 22. 
 23. // AWS SDK libraries. Download the 适用于 Java 的 AWS SDK // from https://aws.amazon.com/sdk-for-java
 24. import com.amazonaws.regions.Regions;
 25. import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
 26. import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
 27. import com.amazonaws.services.simpleemail.model.RawMessage;
 28. import com.amazonaws.services.simpleemail.model.SendRawEmailRequest;
 29. 
 30. public class AmazonSESSample {
 31. 
 32. 	// Replace sender@example.com with your "From" address.
 33. 	// This address must be verified with Amazon SES.
 34. 	private static String SENDER = "Sender Name <sender@example.com>";
 35. 
 36. 	// Replace recipient@example.com with a "To" address. If your account 
 37. 	// is still in the sandbox, this address must be verified.
 38. 	private static String RECIPIENT = "recipient@example.com";
 39. 
 40. 	// Specify a configuration set. If you do not want to use a configuration
 41. 	// set, comment the following variable, and the 
 42. 	// ConfigurationSetName=CONFIGURATION_SET argument below.
 43. 	private static String CONFIGURATION_SET = "ConfigSet";
 44. 
 45. 	// The subject line for the email.
 46. 	private static String SUBJECT = "Customer service contact info";
 47. 
 48. 	// The full path to the file that will be attached to the email.
 49. 	// If you're using Windows, escape backslashes as shown in this variable.
 50. 	private static String ATTACHMENT = "C:\\Users\\sender\\customers-to-contact.xlsx";
 51. 
 52. 	// The email body for recipients with non-HTML email clients.
 53. 	private static String BODY_TEXT = "Hello,\r\n"
 54.                                         + "Please see the attached file for a list "
 55.                                         + "of customers to contact.";
 56. 
 57. 	// The HTML body of the email.
 58. 	private static String BODY_HTML = "<html>"
 59.                                         + "<head></head>"
 60.                                         + "<body>"
 61.                                         + "<h1>Hello!</h1>"
 62.                                         + "<p>Please see the attached file for a "
 63.                                         + "list of customers to contact.</p>"
 64.                                         + "</body>"
 65.                                         + "</html>";
 66. 
 67.     public static void main(String[] args) throws AddressException, MessagingException, IOException {
 68.             	
 69.     	Session session = Session.getDefaultInstance(new Properties());
 70.         
 71.         // Create a new MimeMessage object.
 72.         MimeMessage message = new MimeMessage(session);
 73.         
 74.         // Add subject, from and to lines.
 75.         message.setSubject(SUBJECT, "UTF-8");
 76.         message.setFrom(new InternetAddress(SENDER));
 77.         message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
 78. 
 79.         // Create a multipart/alternative child container.
 80.         MimeMultipart msg_body = new MimeMultipart("alternative");
 81.         
 82.         // Create a wrapper for the HTML and text parts.        
 83.         MimeBodyPart wrap = new MimeBodyPart();
 84.         
 85.         // Define the text part.
 86.         MimeBodyPart textPart = new MimeBodyPart();
 87.         textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8");
 88.                 
 89.         // Define the HTML part.
 90.         MimeBodyPart htmlPart = new MimeBodyPart();
 91.         htmlPart.setContent(BODY_HTML,"text/html; charset=UTF-8");
 92.                 
 93.         // Add the text and HTML parts to the child container.
 94.         msg_body.addBodyPart(textPart);
 95.         msg_body.addBodyPart(htmlPart);
 96.         
 97.         // Add the child container to the wrapper object.
 98.         wrap.setContent(msg_body);
 99.         
100.         // Create a multipart/mixed parent container.
101.         MimeMultipart msg = new MimeMultipart("mixed");
102.         
103.         // Add the parent container to the message.
104.         message.setContent(msg);
105.         
106.         // Add the multipart/alternative part to the message.
107.         msg.addBodyPart(wrap);
108.         
109.         // Define the attachment
110.         MimeBodyPart att = new MimeBodyPart();
111.         DataSource fds = new FileDataSource(ATTACHMENT);
112.         att.setDataHandler(new DataHandler(fds));
113.         att.setFileName(fds.getName());
114.         
115.         // Add the attachment to the message.
116.         msg.addBodyPart(att);
117. 
118.         // Try to send the email.
119.         try {
120.             System.out.println("Attempting to send an email through Amazon SES "
121.                               +"using the AWS SDK for Java...");
122. 
123.             // Instantiate an Amazon SES client, which will make the service 
124.             // call with the supplied AWS credentials.
125.             AmazonSimpleEmailService client = 
126.                     AmazonSimpleEmailServiceClientBuilder.standard()
127.                     // Replace US_WEST_2 with the AWS Region you're using for
128.                     // Amazon SES.
129.                     .withRegion(Regions.US_WEST_2).build();
130.             
131.             // Print the raw email content on the console
132.             PrintStream out = System.out;
133.             message.writeTo(out);
134. 
135.             // Send the email.
136.             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
137.             message.writeTo(outputStream);
138.             RawMessage rawMessage = 
139.             		new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
140. 
141.             SendRawEmailRequest rawEmailRequest = 
142.             		new SendRawEmailRequest(rawMessage)
143.             		    .withConfigurationSetName(CONFIGURATION_SET);
144.             
145.             client.sendRawEmail(rawEmailRequest);
146.             System.out.println("Email sent!");
147.         // Display an error if something goes wrong.
148.         } catch (Exception ex) {
149.           System.out.println("Email Failed");
150.             System.err.println("Error message: " + ex.getMessage());
151.             ex.printStackTrace();
152.         }
153.     }
154. }
```

------
#### [ Python ]

下面的代码示例说明如何使用 [Python email.mime](https://docs.python.org/3.8/library/email.mime.html) 程序包和[AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python) 编写和发送原始电子邮件。

```
 1. import json
 2. import boto3
 3. from botocore.exceptions import ClientError
 4. from email.mime.multipart import MIMEMultipart
 5. from email.mime.text import MIMEText
 6. from email.mime.application import MIMEApplication
 7. import os
 8. 
 9. def boto3_rawemailv2():
10.     SENDER = "Sender <sender@example.com>"
11.     RECIPIENT = "recipient@example.com"
12.     CONFIGURATION_SET = "ConfigSet"
13.     AWS_REGION = "us-east-1"
14.     SUBJECT = "Customer service contact info"
15.     ATTACHMENT = "path/to/customers-to-contact.xlsx"
16.     BODY_TEXT = "Hello,\r\nPlease see the attached file for a list of customers to contact."
17. 
18.     # The HTML body of the email.
19.     BODY_HTML = """\
20.     <html>
21.     <head/>
22.     <body>
23.     <h1>Hello!</h1>
24.     <p>Please see the attached file for a list of customers to contact.</p>
25.     </body>
26.     </html>
27.     """
28. 
29.     # The character encoding for the email.
30.     CHARSET = "utf-8"
31.     msg = MIMEMultipart('mixed')
32.     # Add subject, from and to lines.
33.     msg['Subject'] = SUBJECT 
34.     msg['From'] = SENDER 
35.     msg['To'] = RECIPIENT
36.     
37.     # Create a multipart/alternative child container.
38.     msg_body = MIMEMultipart('alternative')
39.     
40.     # Encode the text and HTML content and set the character encoding. This step is
41.     # necessary if you're sending a message with characters outside the ASCII range.
42.     textpart = MIMEText(BODY_TEXT.encode(CHARSET), 'plain', CHARSET)
43.     htmlpart = MIMEText(BODY_HTML.encode(CHARSET), 'html', CHARSET)
44.     
45.     # Add the text and HTML parts to the child container.
46.     msg_body.attach(textpart)
47.     msg_body.attach(htmlpart)
48.     
49.     # Define the attachment part and encode it using MIMEApplication.
50.     att = MIMEApplication(open(ATTACHMENT, 'rb').read())
51.     
52.     # Add a header to tell the email client to treat this part as an attachment,
53.     # and to give the attachment a name.
54.     att.add_header('Content-Disposition','attachment',filename=os.path.basename(ATTACHMENT))
55.     
56.     # Attach the multipart/alternative child container to the multipart/mixed
57.     # parent container.
58.     msg.attach(msg_body)
59.     msg.attach(att)
60. 
61.     #changes start from here
62.     strmsg = str(msg)
63.     body = bytes (strmsg, 'utf-8')
64. 
65. 
66. 
67.     
68.     client = boto3.client('sesv2')
69.     response = client.send_email(
70.     FromEmailAddress=SENDER,
71.     Destination={
72.         'ToAddresses': [RECIPIENT]
73.     },
74.     Content={
75.         'Raw': {
76.             'Data': body
77.         }
78.     }
79.     )
80.     print(response)
81. boto3_rawemailv2 ()
```

------

# 使用模板通过 Amazon SES API 发送个性化电子邮件
<a name="send-personalized-email-api"></a>

在 Amazon SES 中，您可以使用*存储的模板*或*内联模板*来发送模板化电子邮件。
+ **存储的模板**：指通过使用 Amazon SES v2 API 中的 `CreateEmailTemplate` 操作创建并保存在 SES 中的 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html) 资源。该模板包含电子邮件的主题和正文，其中包含与书面内容内联的变量（占位符）。存储模板的名称以及模板中占位符变量的动态数据在调用 `SendEmail` 或 `SendBulkEmail` v2 API 操作时提供。

  *存储的模板*可以轻松重复使用，并且可以在发送类似类型的电子邮件时为您节省时间和精力。您无需从头开始创建每封电子邮件，只需创建一次基本结构和设计，然后只需更新模板中的动态内容。
+ **内联模板**：不使用 `Template` 资源，而是在调用 `SendEmail` 或 `SendBulkEmail` v2 API 操作时，提供包含与书面内容内联的变量（占位符）的电子邮件主题和正文以及这些占位符变量的值。

  *内联模板*通过消除在 SES 账户中管理模板资源的需要来简化批量电子邮件发送过程，并通过允许您将模板内容直接包含在应用程序逻辑中来简化集成过程。它们不计入每个 20,000 个模板的限制。 AWS 区域

使用*存储的模板*时适用以下限制：
+ 每个模板中最多可以创建 20,000 个电子邮件模板 AWS 区域。
+ 每个模板的大小最多为 500 KB（包括文本和 HTML 部分）。

使用*内联模板*时适用以下限制：
+ 每个输入 JSON 文件的大小最多为 1 MB，包括文本和 HTML 部分。

以下内容适用于*存储的*和*内联模板*：
+ 可以使用的替换变量数量没有限制。
+ 在对 `SendBulkEmail` 操作的每次调用中，您可以将电子邮件发送到最多 50 个目标对象。该[https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html)对象可以包含**ToAddresses**CcAddresses****、和中定义的多个收件人**BccAddresses**。您可以在单次 v2 API 调用中联系的目标数可能受您的账户的最大发送速率限制。有关更多信息，请参阅 [管理您的 Amazon SES 发送限制](manage-sending-quotas.md)。

本章包含使用*存储的模板*和*内联模板*的示例过程。

**注意**  
本节中的过程假定您已安装和配置 AWS CLI。有关安装和配置的更多信息 AWS CLI，请参阅《[AWS Command Line Interface 用户指南》](https://docs.aws.amazon.com/cli/latest/userguide/)。

## （可选）第 1 部分：设置呈现失败事件通知
<a name="send-personalized-email-set-up-notifications"></a>

 如果您发送一封包含无效的个性化内容的电子邮件，那么 Amazon SES 可能接受该邮件，但无法传递它。因此，如果您计划发送个性化电子邮件，则应将 SES 配置为通过 Amazon SNS 发送呈现失败事件通知。当您收到呈现失败事件通知时，您可以验证哪些邮件包含无效的内容、修复问题，然后重新发送邮件。

此部分中的过程可选，不过强烈建议使用。

**配置呈现失败事件通知**

1. 创建 Amazon SNS 主题。有关操作步骤，请参阅《Amazon Simple Notification Service 开发人员指南》**中的[创建主题](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html)。

1. 订阅 Amazon SNS 主题。例如，如果您希望通过电子邮件接收呈现失败通知，请使用电子邮件端点 (即，您的电子邮件地址) 订阅主题。

   有关操作步骤，请参阅《Amazon Simple Notification Service 开发人员指南》**中的[订阅主题](https://docs.aws.amazon.com/sns/latest/dg/SubscribeTopic.html)。

1. 完成[针对事件发布设置 Amazon SNS 事件目标](event-publishing-add-event-destination-sns.md)中的操作步骤来设置您的配置集，以将呈现失败事件发送到您的 Amazon SNS 主题。

## （可选）第 2 部分：创建电子邮件模板
<a name="send-personalized-email-create-template"></a>

如果您打算使用*存储的模板*，本节将向您展示如何使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html) SES v2 API 操作来创建模板。如果您要使用*内联模板*，则可跳过该步骤。

此过程假定您已安装和配置 AWS CLI。有关安装和配置的更多信息 AWS CLI，请参阅《[AWS Command Line Interface 用户指南》](https://docs.aws.amazon.com/cli/latest/userguide/)。

**创建模板**

1. 在文本编辑器中，创建一个新文件并粘贴以下代码，根据需要对其进行自定义。

   ```
   {
       "TemplateName": "MyTemplate",
       "TemplateContent": {
           "Subject": "Greetings, {{name}}!",
           "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
           "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
       }
   }
   ```

   此代码包含以下属性：
   + **TemplateName**— `Template` 资源的名称。当您发送电子邮件时，您将引用此名称。
   + **TemplateContent**— 用于存放以下属性的容器：
     + **主题** – 电子邮件的主题行。此属性可能包含替换标签。这些标签使用以下格式：`{{tagname}}`。当您发送电子邮件时，您可以为每个目标的 `tagname` 指定一个值。
     + **Html**：电子邮件的 HTML 正文。此属性可能包含替换标签。前面的示例包含两个标签：`{{name}}` 和 `{{favoriteanimal}}`。
     + **Text**：电子邮件的文本正文。电子邮件客户端不显示 HTML 内容的收件人将会看到此版本的电子邮件。此属性还可能包含替换标签。

1. 自定义前面的示例以满足您的需求，然后将该文件另存为 *mytemplate.json*。

1. 在命令行中键入以下命令，使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_CreateEmailTemplate.html) v2 API 操作创建新的模板：

   ```
   aws sesv2 create-email-template --cli-input-json file://mytemplate.json
   ```

## 第 3 部分：发送个性化电子邮件
<a name="send-personalized-email-api-operations"></a>

您可以使用以下两个 SES v2 API 操作来发送使用*存储的模板*或*内联模板*的电子邮件：
+ [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) 操作适用于向单个目标对象发送自定义电子邮件。v2 API [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html)对象可以包含*ToAddresses*CcAddresses**、和*BccAddresses*属性。这些可以以任何组合使用，并且可以包含一个或多个将接收相同电子邮件的电子邮件地址。
+ [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html) 操作对于在对 v2 API 的单次调用中将唯一电子邮件发送到多个目标对象很有用。

本节提供了如何通过这两个 AWS CLI 发送操作使用发送模板化电子邮件的示例。

### 将模板化电子邮件发送到单个目标对象
<a name="send-templated-email-single-destination"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) 操作向单个目标对象中定义的一个或多个收件人发送电子邮件。[https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) 对象中的所有收件人都会收到同一电子邮件。

**将模板化电子邮件发送到单个目标对象**

1. 根据您是想使用*存储的模板*还是*内联模板*，选择相应的代码示例粘贴到文本编辑器中，并根据需要进行自定义。

------
#### [ Stored template code example ]

   请注意，您在上一步中创建的模板被引用为`TemplateName`参数的值。*MyTemplate*

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "Destination": {
           "ToAddresses": [
               "alejandro.rosalez@example.com", "jimmy.jet@example.com"
           ]
       },
       "Content": {
           "Template": {
               "TemplateName": "MyTemplate",
               "TemplateData": "{ \"name\":\"Alejandro\", \"favoriteanimal\": \"alligator\" }"
           }
       },
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   此代码包含以下属性：
   + **FromEmailAddress**— 发件人的电子邮件地址。
   + **目标**-包含在*ToAddresses*、*CcAddresses*和*BccAddresses*属性中定义的电子邮件收件人的对象。这些可以以任何组合使用，并且可以包含一个或多个将接收相同电子邮件的电子邮件地址。
   + **TemplateName**— 要应用于电子邮件的`Template`资源名称。
   + **TemplateData**— 包含键值对的转义的 JSON 字符串。键对应于存储模板中 `TemplateContent` 属性定义的变量，例如 `{{name}}`。值表示用来替换变量的内容。
   + **ConfigurationSetName**— 发送电子邮件时要使用的配置集的名称。
**注意**  
我们建议您使用配置为将呈现失败事件发布到 Amazon SNS 的配置集。有关更多信息，请参阅 [（可选）第 1 部分：设置呈现失败事件通知](#send-personalized-email-set-up-notifications)。

------
#### [ Inline template code example ]

   请注意，`TemplateContent` 属性（通常会在*存储的模板*中定义）正在与 `TemplateData` 属性一起*内联*定义，这使其成为*内联模板*。

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "Destination": {
           "ToAddresses": [
               "alejandro.rosalez@example.com", "jimmy.jet@example.com"
           ]
       },
       "Content": {
           "Template": {
               "TemplateContent": {
                   "Subject": "Greetings, {{name}}!",
                   "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
                   "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
               },
               "TemplateData": "{ \"name\":\"Alejandro\", \"favoriteanimal\": \"alligator\" }"
           }
       },
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   此代码包含以下属性：
   + **FromEmailAddress**— 发件人的电子邮件地址。
   + **目标**-包含在*ToAddresses*、*CcAddresses*和*BccAddresses*属性中定义的电子邮件收件人的对象。这些可以以任何组合使用，并且可以包含一个或多个将接收相同电子邮件的电子邮件地址。
   + **TemplateContent**— 用于存放以下属性的容器：
     + **主题** – 电子邮件的主题行。此属性可能包含替换标签。这些标签使用以下格式：`{{tagname}}`。当您发送电子邮件时，您可以为每个目标的 `tagname` 指定一个值。
     + **Html**：电子邮件的 HTML 正文。此属性可能包含替换标签。前面的示例包含两个标签：`{{name}}` 和 `{{favoriteanimal}}`。
     + **Text**：电子邮件的文本正文。电子邮件客户端不显示 HTML 内容的收件人将会看到此版本的电子邮件。此属性还可能包含替换标签。
   + **TemplateData**— 包含键值对的转义的 JSON 字符串。这些键对应于本文件中 `TemplateContent` 属性定义的变量，例如 `{{name}}`。值表示用来替换变量的内容。
   + **ConfigurationSetName**— 发送电子邮件时要使用的配置集的名称。
**注意**  
我们建议您使用配置为将呈现失败事件发布到 Amazon SNS 的配置集。有关更多信息，请参阅 [（可选）第 1 部分：设置呈现失败事件通知](#send-personalized-email-set-up-notifications)。

------

1. 自定义前面的示例以满足您的需求，然后将该文件另存为 *myemail.json*。

1. 在命令行键入以下 v2 API 命令，发送电子邮件：

   ```
   aws sesv2 send-email --cli-input-json file://myemail.json
   ```

### 将模板化电子邮件发送到多个目标对象
<a name="send-templated-email-multiple-destinations"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html) 操作在单次调用 SES v2 API 时向多个目标对象发送电子邮件。SES 会向每个 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Destination.html) 对象中的收件人发送唯一的电子邮件。

**将模板化电子邮件发送到多个目标对象**

1. 根据您是想使用*存储的模板*还是*内联模板*，选择相应的代码示例粘贴到文本编辑器中，并根据需要进行自定义。

------
#### [ Stored template code example ]

   请注意，您在上一步中创建的模板被引用为`TemplateName`参数的值。*MyTemplate*

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "DefaultContent": {
           "Template": {
               "TemplateName": "MyTemplate",
               "TemplateData": "{ \"name\":\"friend\", \"favoriteanimal\":\"unknown\" }"
           }
       },
       "BulkEmailEntries": [
           {
               "Destination": {
                   "ToAddresses": [
                       "anaya.iyengar@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Anaya\", \"favoriteanimal\":\"angelfish\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "liu.jie@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Liu\", \"favoriteanimal\":\"lion\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "shirley.rodriguez@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Shirley\", \"favoriteanimal\":\"shark\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "richard.roe@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{}"
                   }
               }
           }
       ],
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   此代码包含以下属性：
   + **FromEmailAddress**— 发件人的电子邮件地址。
   + **DefaultContent**— 包含`TemplateName`和对象的 JSON `TemplateData` 对象。
   + **TemplateName**— 要应用于电子邮件的`Template`资源名称。
   + **TemplateData**— 包含键值对，如果对象在属性中包含空的 JSON `ReplacementEmailContent` 对象`{}`，则将使用这些`ReplacementTemplateData`键值对。
   + **BulkEmailEntries**— 包含一个或多个`Destination`对象的数组。
   + **目标**-包含在*ToAddresses*、*CcAddresses*和*BccAddresses*属性中定义的电子邮件收件人的对象。这些可以以任何组合使用，并且可以包含一个或多个将接收相同电子邮件的电子邮件地址。
   + **ReplacementTemplateData**— 包含键值对的转义的 JSON 字符串。键与模板中的变量（例如 `{{name}}`）对应。值表示用来替换电子邮件中的变量的内容。（如果此处的 JSON 字符串为空，由 `{}` 表示，则将使用在 `DefaultContent` 对象内的 `TemplateData` 属性中定义的键值对。）
   + **ConfigurationSetName**— 发送电子邮件时要使用的配置集的名称。
**注意**  
我们建议您使用配置为将呈现失败事件发布到 Amazon SNS 的配置集。有关更多信息，请参阅 [（可选）第 1 部分：设置呈现失败事件通知](#send-personalized-email-set-up-notifications)。

------
#### [ Inline template code example ]

   请注意，`TemplateContent` 属性（通常会在*存储的模板*中定义）正在与 `TemplateData` 属性一起*内联*定义，这使其成为*内联模板*。

   ```
   {
       "FromEmailAddress": "Mary Major <mary.major@example.com>",
       "DefaultContent": {
           "Template": {
               "TemplateContent": {
                   "Subject": "Greetings, {{name}}!",
                   "Text": "Dear {{name}},\r\nYour favorite animal is {{favoriteanimal}}.",
                   "Html": "<h1>Hello {{name}},</h1><p>Your favorite animal is {{favoriteanimal}}.</p>"
               },
               "TemplateData": "{ \"name\":\"friend\", \"favoriteanimal\":\"unknown\" }"
           }
       },
       "BulkEmailEntries": [
           {
               "Destination": {
                   "ToAddresses": [
                       "anaya.iyengar@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Anaya\", \"favoriteanimal\":\"angelfish\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "liu.jie@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Liu\", \"favoriteanimal\":\"lion\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "shirley.rodriguez@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{ \"name\":\"Shirley\", \"favoriteanimal\":\"shark\" }"
                   }
               }
           },
           {
               "Destination": {
                   "ToAddresses": [
                       "richard.roe@example.com"
                   ]
               },
               "ReplacementEmailContent": {
                   "ReplacementTemplate": {
                       "ReplacementTemplateData": "{}"
                   }
               }
           }
       ],
       "ConfigurationSetName": "ConfigSet"
   }
   ```

   此代码包含以下属性：
   + **FromEmailAddress**— 发件人的电子邮件地址。
   + **DefaultContent**— 包含`TemplateContent`和对象的 JSON `TemplateData` 对象。
   + **TemplateContent**— 用于存放以下属性的容器：
     + **主题** – 电子邮件的主题行。此属性可能包含替换标签。这些标签使用以下格式：`{{tagname}}`。当您发送电子邮件时，您可以为每个目标的 `tagname` 指定一个值。
     + **Html**：电子邮件的 HTML 正文。此属性可能包含替换标签。前面的示例包含两个标签：`{{name}}` 和 `{{favoriteanimal}}`。
     + **Text**：电子邮件的文本正文。电子邮件客户端不显示 HTML 内容的收件人将会看到此版本的电子邮件。此属性还可能包含替换标签。
   + **TemplateData**— 包含键值对，如果对象在属性中包含空的 JSON `ReplacementEmailContent` 对象`{}`，则将使用这些`ReplacementTemplateData`键值对。
   + **BulkEmailEntries**— 包含一个或多个`Destination`对象的数组。
   + **目标**-包含在*ToAddresses*、*CcAddresses*和*BccAddresses*属性中定义的电子邮件收件人的对象。这些可以以任何组合使用，并且可以包含一个或多个将接收相同电子邮件的电子邮件地址。
   + **ReplacementTemplateData**— 包含键值对的转义的 JSON 字符串。这些键对应于本文件中 `TemplateContent` 属性定义的变量，例如 `{{name}}`。值表示用来替换电子邮件中的变量的内容。（如果此处的 JSON 字符串为空，由 `{}` 表示，则将使用在 `DefaultContent` 对象内的 `TemplateData` 属性中定义的键值对。）
   + **ConfigurationSetName**— 发送电子邮件时要使用的配置集的名称。
**注意**  
我们建议您使用配置为将呈现失败事件发布到 Amazon SNS 的配置集。有关更多信息，请参阅 [（可选）第 1 部分：设置呈现失败事件通知](#send-personalized-email-set-up-notifications)。

------

1. 更改上一步骤代码中的值以满足您的需求，然后将该文件另存为 *mybulkemail.json*。

1. 在命令行中，键入以下 v2 API 命令来发送批量电子邮件：

   ```
   aws sesv2 send-bulk-email --cli-input-json file://mybulkemail.json
   ```

# 高级电子邮件个性化
<a name="send-personalized-email-advanced"></a>

 如果您使用的是*存储的模板*，即您已通过使用 SES v2 API 的 `CreateEmailTemplate` 操作在 Amazon SES 中创建了 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Template.html) 资源，您可以利用 Handlebars 系统创建包含高级功能的模板，例如嵌套属性、数组迭代、基本条件语句和创建内联部分。本部分提供有关这些特征的一些示例。

除本部分介绍的特征以外，Handlebars 还包含许多其他特征。有关更多信息，请参阅[handlebarsjs.com](https://handlebarsjs.com/guide/builtin-helpers.html) 上的 [Built-In Helpers](http://handlebarsjs.com)。

**注意**  
为消息呈现 HTML 模板时，SES 不会转义 HTML 内容。这意味着，如果您包括用户输入的数据，例如联系人表单的用户输入数据，则需要在客户端将其转义。

**Topics**
+ [解析嵌套属性](#send-personalized-email-advanced-nested)
+ [遍历列表](#send-personalized-email-advanced-iterating)
+ [使用基本条件语句](#send-personalized-email-advanced-conditionals)
+ [创建内联部分](#send-personalized-email-advanced-inline-partials)

## 解析嵌套属性
<a name="send-personalized-email-advanced-nested"></a>

Handlebars 包括对嵌套路径的支持，这让您能够轻松组织复杂的客户数据，然后在电子邮件模板中引用这些数据。

例如，您可以将收件人数据组织到多个常规类别中。在每个类别中，您可以包含详细信息。以下代码示例显示了包含单一收件人的此种结构：

```
{
  "meta":{
    "userId":"51806220607"
  },
  "contact":{
    "firstName":"Anaya",
    "lastName":"Iyengar",
    "city":"Bengaluru",
    "country":"India",
    "postalCode":"560052"
  },
  "subscription":[
    {
      "interest":"Sports"
    },
    {
      "interest":"Travel"
    },
    {
      "interest":"Cooking"
    }
  ]
}
```

在电子邮件模板中，您可以通过以下方式引用嵌套属性：提供父属性名称，后跟句点 (.)，然后是要包含其值的属性的名称。例如，对于上例中显示的数据结构，要在电子邮件模板中包含每个收件人的名字，请在电子邮件模板中包含以下文本：`Hello {{contact.firstName}}!`

Handlebars 能够解析多层嵌套路径，这意味着您可以灵活地组织模板数据结构。

## 遍历列表
<a name="send-personalized-email-advanced-iterating"></a>

`each` 帮助程序函数可遍历数组中的项目。以下代码是一个电子邮件模板的示例，此模板使用 `each` 帮助程序函数创建每个收件人兴趣的明细列表。

```
{
  "Template": {
    "TemplateName": "Preferences",
    "SubjectPart": "Subscription Preferences for {{contact.firstName}} {{contact.lastName}}",
    "HtmlPart": "<h1>Your Preferences</h1>
                 <p>You have indicated that you are interested in receiving 
                   information about the following subjects:</p>
                 <ul>
                   {{#each subscription}}
                     <li>{{interest}}</li>
                   {{/each}}
                 </ul>
                 <p>You can change these settings at any time by visiting 
                    the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                    Preference Center</a>.</p>",
    "TextPart": "Your Preferences\n\nYou have indicated that you are interested in 
                 receiving information about the following subjects:\n
                 {{#each subscription}}
                   - {{interest}}\n
                 {{/each}}
                 \nYou can change these settings at any time by 
                 visiting the Preference Center at 
                 https://www.example.com/prefererences/i.aspx?id={{meta.userId}}"
  }
}
```

**重要**  
在前面的代码示例中，`HtmlPart` 和 `TextPart` 属性的值包含换行符，以便提高示例的可读性。您的模板的 JSON 文件不能在这些值中包含换行符。如果您将此示例复制并粘贴到自己的 JSON 文件中，请在继续前从 `HtmlPart` 和 `TextPart` 部分中删除换行符和多余空格。

创建模板后，您可以使用 `SendEmail` 或 `SendBulkEmail` 操作使用此模板向收件人发送电子邮件。只要每个收件人在 `Interests` 对象中至少有一个值，他们就会收到包含其兴趣明细列表的电子邮件。以下示例显示了可用于使用上述模板向多个收件人发送电子邮件的 JSON 文件：

```
{
  "Source":"Sender Name <sender@example.com>",
  "Template":"Preferences",
  "Destinations":[
    {
      "Destination":{
        "ToAddresses":[
          "anaya.iyengar@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"51806220607\"},\"contact\":{\"firstName\":\"Anaya\",\"lastName\":\"Iyengar\"},\"subscription\":[{\"interest\":\"Sports\"},{\"interest\":\"Travel\"},{\"interest\":\"Cooking\"}]}"
      },
    {
      "Destination":{ 
        "ToAddresses":[
          "shirley.rodriguez@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"1981624758263\"},\"contact\":{\"firstName\":\"Shirley\",\"lastName\":\"Rodriguez\"},\"subscription\":[{\"interest\":\"Technology\"},{\"interest\":\"Politics\"}]}"
    }
  ],
  "DefaultTemplateData":"{\"meta\":{\"userId\":\"\"},\"contact\":{\"firstName\":\"Friend\",\"lastName\":\"\"},\"subscription\":[]}"
}
```

当您使用 `SendBulkEmail` 操作向前面示例中列出的收件人发送电子邮件时，他们会收到类似下图所示示例的邮件：

![\[Preferences notification listing Sports, Travel, and Cooking as selected interests.\]](http://docs.aws.amazon.com/zh_cn/ses/latest/dg/images/send-personalized-email-advanced-condition-interest.png)


## 使用基本条件语句
<a name="send-personalized-email-advanced-conditionals"></a>

本部分基于前一部分中介绍的示例。前一部分中的示例使用 `each` 帮助程序遍历兴趣列表。但是，未指定兴趣的收件人会收到包含空列表的电子邮件。通过使用 `{{if}}` 帮助程序，您可根据模板数据中是否存在特定属性以不同方式设置电子邮件格式。以下代码使用了 `{{if}}` 帮助程序：如果 `Subscription` 数组包含任何值，则显示前一部分中的项目符号列表。如果数组为空，则显示其他的文本块。

```
{
  "Template": {
    "TemplateName": "Preferences2",
    "SubjectPart": "Subscription Preferences for {{contact.firstName}} {{contact.lastName}}",
    "HtmlPart": "<h1>Your Preferences</h1>
                 <p>Dear {{contact.firstName}},</p>
                 {{#if subscription}}
                   <p>You have indicated that you are interested in receiving 
                     information about the following subjects:</p>
                     <ul>
                     {{#each subscription}}
                       <li>{{interest}}</li>
                     {{/each}}
                     </ul>
                     <p>You can change these settings at any time by visiting 
                       the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                       Preference Center</a>.</p>
                 {{else}}
                   <p>Please update your subscription preferences by visiting 
                     the <a href=https://www.example.com/prefererences/i.aspx?id={{meta.userId}}>
                     Preference Center</a>.
                 {{/if}}",
    "TextPart": "Your Preferences\n\nDear {{contact.firstName}},\n\n
                 {{#if subscription}}
                   You have indicated that you are interested in receiving 
                   information about the following subjects:\n
                   {{#each subscription}}
                     - {{interest}}\n
                   {{/each}}
                   \nYou can change these settings at any time by visiting the 
                   Preference Center at https://www.example.com/prefererences/i.aspx?id={{meta.userId}}.
                 {{else}}
                   Please update your subscription preferences by visiting the 
                   Preference Center at https://www.example.com/prefererences/i.aspx?id={{meta.userId}}.
                 {{/if}}"
  }
}
```

**重要**  
在前面的代码示例中，`HtmlPart` 和 `TextPart` 属性的值包含换行符，以便提高示例的可读性。您的模板的 JSON 文件不能在这些值中包含换行符。如果您将此示例复制并粘贴到自己的 JSON 文件中，请在继续前从 `HtmlPart` 和 `TextPart` 部分中删除换行符和多余空格。

以下示例显示了可用于使用上述模板向多个收件人发送电子邮件的 JSON 文件：

```
{
  "Source":"Sender Name <sender@example.com>",
  "Template":"Preferences2",
  "Destinations":[
    {
      "Destination":{
        "ToAddresses":[
          "anaya.iyengar@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"51806220607\"},\"contact\":{\"firstName\":\"Anaya\",\"lastName\":\"Iyengar\"},\"subscription\":[{\"interest\":\"Sports\"},{\"interest\":\"Cooking\"}]}"
      },
    {
      "Destination":{ 
        "ToAddresses":[
          "shirley.rodriguez@example.com"
        ]
      },
      "ReplacementTemplateData":"{\"meta\":{\"userId\":\"1981624758263\"},\"contact\":{\"firstName\":\"Shirley\",\"lastName\":\"Rodriguez\"}}"
    }
  ],
  "DefaultTemplateData":"{\"meta\":{\"userId\":\"\"},\"contact\":{\"firstName\":\"Friend\",\"lastName\":\"\"},\"subscription\":[]}"
}
```

在此示例中，模板数据包含兴趣列表的收件人会收到与前一部分中所示示例相同的电子邮件。模板数据不包含任何兴趣的收件人会收到类似下图所示示例的电子邮件：

![\[Email message with header "Your Preferences" and text about updating subscription preferences.\]](http://docs.aws.amazon.com/zh_cn/ses/latest/dg/images/send-personalized-email-advanced-condition-nointerest.png)


## 创建内联部分
<a name="send-personalized-email-advanced-inline-partials"></a>

您可以使用内联部分简化包含重复字符串的模板。例如，您可以在模板开头添加以下代码，从而创建一个内联部分，其中包含收件人的名字和姓氏 (如果可用)：

```
{{#* inline \"fullName\"}}{{firstName}}{{#if lastName}} {{lastName}}{{/if}}{{/inline}}\n
```

**注意**  
需要使用换行符 (`\n`) 将 `{{inline}}` 块与模板内容分开。最终输出中不显示换行符。

创建 `fullName` 部分后，您可以通过在此部分的名称前加上一个大于号 (>) 并后跟一个空格来将其包含在模板中的任何位置，如下例所示：`{{> fullName}}`。内联部分不会在电子邮件部分间转移。例如，要在电子邮件的 HTML 和文本版本中使用相同的内联部分，则必须在 `HtmlPart` 和 `TextPart` 部分中都定义此部分。

遍历数组时，也可以使用内联部分。您可以使用以下代码创建使用 `fullName` 内联部分的模板。在此示例中，内联部分应用至收件人姓名和一个其他名称数组：

```
{
  "Template": {
    "TemplateName": "Preferences3",
    "SubjectPart": "{{firstName}}'s Subscription Preferences",
    "HtmlPart": "{{#* inline \"fullName\"}}
                   {{firstName}}{{#if lastName}} {{lastName}}{{/if}}
                 {{/inline~}}\n
                 <h1>Hello {{> fullName}}!</h1>
                 <p>You have listed the following people as your friends:</p>
                 <ul>
                 {{#each friends}}
                   <li>{{> fullName}}</li>
                 {{/each}}</ul>",
    "TextPart": "{{#* inline \"fullName\"}}
                   {{firstName}}{{#if lastName}} {{lastName}}{{/if}}
                 {{/inline~}}\n
                 Hello {{> fullName}}! You have listed the following people 
                 as your friends:\n
                 {{#each friends}}
                   - {{> fullName}}\n
                 {{/each}}"
  }
}
```

**重要**  
在前面的代码示例中，`HtmlPart` 和 `TextPart` 属性的值包含换行符，以便提高示例的可读性。您的模板的 JSON 文件不能在这些值中包含换行符。如果您将此示例复制并粘贴到自己的 JSON 文件中，请从这些部分中删除换行符和多余空格。

# 管理电子邮件模板
<a name="send-personalized-email-manage-templates"></a>

除了[创建电子邮件模板](send-personalized-email-api.md)之外，您还可以使用 Amazon SES v2 API 来更新或删除现有模板、列出所有现有模板或者查看模板的内容。

本节包含使用执行 AWS CLI 与 SES 模板相关的任务的过程。

**注意**  
本节中的过程假定您已安装和配置 AWS CLI。有关安装和配置的更多信息 AWS CLI，请参阅《[AWS Command Line Interface 用户指南》](https://docs.aws.amazon.com/cli/latest/userguide/)。

## 查看电子邮件模板列表
<a name="send-personalized-email-manage-templates-list"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_ListEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_ListEmailTemplate.html) SES v2 API 操作来查看您的所有现有电子邮件模板的列表。

**查看电子邮件模板列表**
+ 在命令行输入以下命令：

  ```
  aws sesv2 list-email-templates
  ```

  如果您的 SES 账户在当前区域中存在现有电子邮件模板，那么此命令将返回类似于以下示例的响应：

  ```
  {
      "TemplatesMetadata": [
          {
              "Name": "SpecialOffers",
              "CreatedTimestamp": "2020-08-05T16:04:12.640Z"
          },
          {
              "Name": "NewsAndUpdates",
              "CreatedTimestamp": "2019-10-03T20:03:34.574Z"
          }
      ]
  }
  ```

  如果您尚未创建任何模板，那么该命令会返回没有任何成员的 `TemplatesMetadata` 对象。

## 查看特定电子邮件模板的内容
<a name="send-personalized-email-manage-templates-get"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html) SES v2 API 操作来查看特定电子邮件模板的内容。

**查看电子邮件模板的内容**
+ 在命令行输入以下命令：

  ```
  aws sesv2 get-email-template --template-name MyTemplate
  ```

  在前面的命令中，*MyTemplate*替换为要查看的模板的名称。

  如果您提供的模板名称与 SES 账户中存在的模板匹配，那么此命令将返回类似于以下示例的响应：

  ```
  {
      "Template": {
          "TemplateName": "TestMessage",
          "SubjectPart": "Amazon SES Test Message",
          "TextPart": "Hello! This is the text part of the message.",
          "HtmlPart": "<html>\n<body>\n<h2>Hello!</h2>\n<p>This is the HTML part of the message.</p></body>\n</html>"
      }
  }
  ```

  如果您提供的模板名称与 SES 账户中存在的模板不匹配，那么该命令将返回 `NotFoundException` 错误。

## 删除电子邮件模板
<a name="send-personalized-email-manage-templates-delete"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DeleteEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DeleteEmailTemplate.html) SES v2 API 操作来删除特定电子邮件模板。

**删除电子邮件模板**
+ 在命令行输入以下命令：

  ```
  aws sesv2 delete-email-template --template-name MyTemplate
  ```

  在前面的命令中，*MyTemplate*替换为要删除的模板的名称。

  此命令不提供任何输出。您可以使用[GetTemplate](#send-personalized-email-manage-templates-get)操作来验证模板是否已删除。

## 更新电子邮件模板
<a name="send-personalized-email-manage-templates-update"></a>

您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_UpdateEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_UpdateEmailTemplate.html) SES v2 API 操作来更新现有电子邮件模板。例如，如果您要更改电子邮件模板的主题行，或者如果您需要修改邮件本身的正文，那么此操作很有用。

**更新电子邮件模板**

1. 使用 `GetEmailTemplate` 命令，在命令行中输入以下命令来检索现有模板：

   ```
   aws sesv2 get-email-template --template-name MyTemplate
   ```

   在前面的命令中，*MyTemplate*替换为要更新的模板的名称。

   如果您提供的模板名称与 SES 账户中存在的模板匹配，那么此命令将返回类似于以下示例的响应：

   ```
   {
       "Template": {
           "TemplateName": "TestMessage",
           "SubjectPart": "Amazon SES Test Message",
           "TextPart": "Hello! This is the text part of the message.",
           "HtmlPart": "<html>\n<body>\n<h2>Hello!</h2>\n<p>This is the HTML part of the message.</p></body>\n</html>"
       }
   }
   ```

1. 在文本编辑器中，创建一个新文件。将上一个命令的输出粘贴到文件中。

1. 根据需要修改模板。您省略的任何行都将从模板中删除。例如，如果您只想更改模板的 `SubjectPart`，您仍然需要包含 `TextPart` 和 `HtmlPart` 属性。

   完成后，将文件另存为 `update_template.json`。

1. 在命令行输入以下命令：

   ```
   aws sesv2 update-email-template --cli-input-json file://path/to/update_template.json
   ```

   在前面的命令中，*path/to/update\$1template.json*替换为您在上一步中创建的`update_template.json`文件的路径。

   如果模板更新成功，则此命令不提供任何输出。您可以使用 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_GetEmailTemplate.html) 操作来验证模板是否已更新。

   如果您指定的模板不存在，则此命令会返回 `TemplateDoesNotExist` 错误。如果模板不包含 `TextPart` 和/或 `HtmlPart` 属性，则此命令会返回 `InvalidParameterValue` 错误。

# 使用软件开发工具包通过 Amazon AWS SES 发送电子邮件
<a name="send-an-email-using-sdk-programmatically"></a>

您可以使用 AWS 软件开发工具包通过 Amazon SES 发送电子邮件。 AWS SDKs 适用于多种编程语言。有关更多信息，请参阅[用于 Amazon Web Services 的工具](https://aws.amazon.com/tools/#sdk)。

## 先决条件
<a name="send-an-email-using-sdk-programmatically-prereqs"></a>

要完成下一节中的任何代码示例，必须完成以下先决条件：
+ 如果您尚未执行此操作，请完成[设置 Amazon Simple Email Service](setting-up.md)中的任务。
+ **使用 Amazon SES 验证您的电子邮件地址** – 您必须先验证您拥有发件人的电子邮件地址，然后才能使用 Amazon SES 发送电子邮件。如果您的账户仍在 Amazon SES 沙盒中，您还必须验证收件人的电子邮件地址。我们建议您使用 Amazon SES 控制台来验证电子邮件地址。有关更多信息，请参阅 [创建电子邮件地址身份](creating-identities.md#verify-email-addresses-procedure)。
+ **获取您的 AWS 证书**-您需要访问密钥 ID 和 AWS 私有 AWS 访问密钥才能使用软件开发工具包访问 Amazon SES。您可以使用 [中的](https://console.aws.amazon.com/iam/home?#security_credential)安全凭证 AWS 管理控制台页面来查找您的凭证。有关凭证的更多信息，请参阅[Amazon SES 凭证的类型](send-email-concepts-credentials.md)。
+ **创建共享凭证文件** – 为了使此部分中的示例代码正常运行，您必须创建一个共享凭证文件。有关更多信息，请参阅 [创建共享凭证文件，以便在使用软件开发工具包通过 Amazon AWS SES 发送电子邮件时使用](create-shared-credentials-file.md)。

## 代码示例
<a name="send-an-email-using-sdk-programmatically-examples"></a>

**重要**  
在以下教程中，您将向自己发送电子邮件，以便检查是否收到了该电子邮件。如需进一步试验或进行负载测试，请使用 Amazon SES 邮箱模拟器。您发送到邮箱模拟器的电子邮件不会计入您的发送配额或您的退信率和投诉率。有关更多信息，请参阅 [手动使用邮箱模拟器](send-an-email-from-console.md#send-email-simulator)。

**Topics**

------
#### [ .NET ]

以下过程介绍如何使用 [Visual Studio](https://www.visualstudio.com/) 和 适用于 .NET 的 AWS SDK通过 Amazon SES 发送电子邮件。

已使用以下组件测试此解决方案：
+ Microsoft Visual Studio Community 2017 版本 15.4.0。
+ Microsoft .NET Framework 版本 4.6.1。
+  AWSSDK.Core 软件包（版本 3.3.19），使用安装。 NuGet
+ 的 AWSSDK。 SimpleEmail 软件包（版本 3.3.6.1），使用安装。 NuGet

**在开始前，请执行以下任务：**
+ **安装 Visual Studio** —Visual Studio 可在 [https://www.visualstudio.com/](https://www.visualstudio.com/)上

**要使用发送电子邮件 适用于 .NET 的 AWS SDK**

1. 通过执行以下步骤创建新项目：

   1. 启动 Visual Studio。

   1. 在 **File** 菜单上，依次选择 **New** 和 **Project**。

   1. 在 **New Project** 窗口上的左侧面板中，展开 **Installed**，然后展开 **Visual C\$1**。

   1. 在右侧面板中，选择 **Console App（.NET Framework）**。

   1. 对于**名称**，键入 **AmazonSESSample**，然后选择 **确定**。

1. 通过完成以下步骤，使用 NuGet 将 Amazon SES 软件包包含在您的解决方案中：

   1. 在 “**解决方案资源管理器**” 窗格中，右键单击您的项目，然后选择 “**管理 NuGet 包**”。

   1. 在 **NuGet：Amazon SESSample** 选项卡上，选择**浏览**。

   1. 在搜索框中，键入 **AWSSDK.SimpleEmail**。

   1. 选择**AWSSDK。 SimpleEmail**软件包，然后选择 “**安装**”。

   1. 在 **Preview Changes** 窗口中，选择 **OK**。

1. 在 **Program.cs** 选项卡上，粘贴以下代码：

   ```
    1. using Amazon;
    2. using System;
    3. using System.Collections.Generic;
    4. using Amazon.SimpleEmail;
    5. using Amazon.SimpleEmail.Model;
    6. 
    7. namespace AmazonSESSample 
    8. {
    9.     class Program
   10.     {
   11.         // Replace sender@example.com with your "From" address.
   12.         // This address must be verified with Amazon SES.
   13.         static readonly string senderAddress = "sender@example.com";
   14. 
   15.         // Replace recipient@example.com with a "To" address. If your account
   16.         // is still in the sandbox, this address must be verified.
   17.         static readonly string receiverAddress = "recipient@example.com";
   18. 
   19.         // The configuration set to use for this email. If you do not want to use a
   20.         // configuration set, comment out the following property and the
   21.         // ConfigurationSetName = configSet argument below. 
   22.         static readonly string configSet = "ConfigSet";
   23. 
   24.         // The subject line for the email.
   25.         static readonly string subject = "Amazon SES test (适用于 .NET 的 AWS SDK)";
   26. 
   27.         // The email body for recipients with non-HTML email clients.
   28.         static readonly string textBody = "Amazon SES Test (.NET)\r\n" 
   29.                                         + "This email was sent through Amazon SES "
   30.                                         + "using the 适用于 .NET 的 AWS SDK.";
   31.         
   32.         // The HTML body of the email.
   33.         static readonly string htmlBody = @"<html>
   34. <head></head>
   35. <body>
   36.   <h1>Amazon SES Test (适用于 .NET 的 SDK)</h1>
   37.   <p>This email was sent with
   38.     <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
   39.     <a href='https://aws.amazon.com/sdk-for-net/'> 适用于 .NET 的 AWS SDK</a>.</p>
   40. </body>
   41. </html>";
   42. 
   43.         static void Main(string[] args)
   44.         {
   45.             // Replace USWest2 with the AWS Region you're using for Amazon SES.
   46.             // Acceptable values are EUWest1, USEast1, and USWest2.
   47.             using (var client = new AmazonSimpleEmailServiceClient(RegionEndpoint.USWest2))
   48.             {
   49.                 var sendRequest = new SendEmailRequest
   50.                 {
   51.                     Source = senderAddress,
   52.                     Destination = new Destination
   53.                     {
   54.                         ToAddresses =
   55.                         new List<string> { receiverAddress }
   56.                     },
   57.                     Message = new Message
   58.                     {
   59.                         Subject = new Content(subject),
   60.                         Body = new Body
   61.                         {
   62.                             Html = new Content
   63.                             {
   64.                                 Charset = "UTF-8",
   65.                                 Data = htmlBody
   66.                             },
   67.                             Text = new Content
   68.                             {
   69.                                 Charset = "UTF-8",
   70.                                 Data = textBody
   71.                             }
   72.                         }
   73.                     },
   74.                     // If you are not using a configuration set, comment
   75.                     // or remove the following line 
   76.                     ConfigurationSetName = configSet
   77.                 };
   78.                 try
   79.                 {
   80.                     Console.WriteLine("Sending email using Amazon SES...");
   81.                     var response = client.SendEmail(sendRequest);
   82.                     Console.WriteLine("The email was sent successfully.");
   83.                 }
   84.                 catch (Exception ex)
   85.                 {
   86.                     Console.WriteLine("The email was not sent.");
   87.                     Console.WriteLine("Error message: " + ex.Message);
   88. 
   89.                 }
   90.             }
   91. 
   92.             Console.Write("Press any key to continue...");
   93.             Console.ReadKey();
   94.         }
   95.     }
   96. }
   ```

1. 在代码编辑器中，执行下列操作：
   + *sender@example.com*替换为 “发件人:” 电子邮件地址。必须验证此地址。有关更多信息，请参阅 [Amazon SES 中已验证的身份](verify-addresses-and-domains.md)。
   + *recipient@example.com*替换为 “收件人：” 地址。如果您的账户仍处于沙盒中，则还必须验证此地址。
   + *ConfigSet*替换为发送此电子邮件时要使用的配置集的名称。
   + *USWest2*替换为您用于通过 Amazon SES 发送电子邮件的 AWS 区域 终端节点的名称。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

   完成后，保存 `Program.cs`。

1. 通过完成以下步骤来生成并运行应用程序：

   1. 在 **Build** 菜单上，选择 **Build Solution**。

   1. 在 **Debug** 菜单上，选择 **Start Debugging**。此时显示一个控制台窗口。

1. 检查控制台的输出。如果已成功发送电子邮件，则控制台会显示“`The email was sent successfully.`” 

1. 如果已成功发送电子邮件，请登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------
#### [ Java ]

以下过程向您展示了如何使用适用[于 Java EE 开发人员的 Eclipse IDE、[AWS Toolkit for Eclipse](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/welcome.html)如何创建软件开发](http://www.eclipse.org/) AWS 工具包项目和修改 Java 代码以通过 Amazon SES 发送电子邮件。

**在开始前，请执行以下任务：**
+ **安装 Eclipse**：访问 [https://www.eclipse.org/downloads](https://www.eclipse.org/downloads) 可获得 Eclipse。本教程中的代码使用 Eclipse Neon.3（版本 4.6.3） 和 Java 运行时环境的 1.8 版本进行了测试。
+ **安装 AWS Toolkit for Eclipse** [—有关向 Eclipse 安装中 AWS Toolkit for Eclipse 添加的说明，请访问 /eclipse。https://aws.amazon.com](https://aws.amazon.com/eclipse)本教程中的代码已使用 2.3.1 版本的 AWS Toolkit for Eclipse进行了测试。

**要使用发送电子邮件 适用于 Java 的 AWS SDK**

1. 通过执行以下步骤在 Eclipse 中创建 AWS Java 项目：

   1. 启动 Eclipse。

   1. 在 **File** 菜单上，选择 **New**，然后选择 **Other**。在 **New** 窗口中，展开 **AWS** 文件夹，然后选择 **AWS Java Project**。

   1. 在 “**新建 AWS Java 项目**” 对话框中，执行以下操作：

      1. 对于 **Project name**，键入项目的名称。

      1. 在 “**适用于 Java 的 AWS SDK 示例**” 下，选择 **Amazon 简单电子邮件服务 JavaMail 示例**。

      1. 选择**结束**。

1. 在 Eclipse 中的 **Package Explorer** 窗格中，展开您的项目。

1. 在您的项目下，展开 `src/main/java` 文件夹，展开 `com.amazon.aws.samples` 文件夹，然后双击 `AmazonSESSample.java`。

1. 将 `AmazonSESSample.java` 的整个内容替换为以下代码：

   ```
    1. package com.amazonaws.samples;
    2. 
    3. import java.io.IOException;
    4. 
    5. import com.amazonaws.regions.Regions;
    6. import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
    7. import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder;
    8. import com.amazonaws.services.simpleemail.model.Body;
    9. import com.amazonaws.services.simpleemail.model.Content;
   10. import com.amazonaws.services.simpleemail.model.Destination;
   11. import com.amazonaws.services.simpleemail.model.Message;
   12. import com.amazonaws.services.simpleemail.model.SendEmailRequest; 
   13. 
   14. public class AmazonSESSample {
   15. 
   16.   // Replace sender@example.com with your "From" address.
   17.   // This address must be verified with Amazon SES.
   18.   static final String FROM = "sender@example.com";
   19. 
   20.   // Replace recipient@example.com with a "To" address. If your account
   21.   // is still in the sandbox, this address must be verified.
   22.   static final String TO = "recipient@example.com";
   23. 
   24.   // The configuration set to use for this email. If you do not want to use a
   25.   // configuration set, comment the following variable and the 
   26.   // .withConfigurationSetName(CONFIGSET); argument below.
   27.   static final String CONFIGSET = "ConfigSet";
   28. 
   29.   // The subject line for the email.
   30.   static final String SUBJECT = "Amazon SES test (适用于 Java 的 AWS SDK)";
   31.   
   32.   // The HTML body for the email.
   33.   static final String HTMLBODY = "<h1>Amazon SES test (适用于 Java 的 AWS SDK)</h1>"
   34.       + "<p>This email was sent with <a href='https://aws.amazon.com/ses/'>"
   35.       + "Amazon SES</a> using the <a href='https://aws.amazon.com/sdk-for-java/'>" 
   36.       + "AWS SDK for Java</a>";
   37. 
   38.   // The email body for recipients with non-HTML email clients.
   39.   static final String TEXTBODY = "This email was sent through Amazon SES "
   40.       + "using the 适用于 Java 的 AWS SDK.";
   41. 
   42.   public static void main(String[] args) throws IOException {
   43. 
   44.     try {
   45.       AmazonSimpleEmailService client = 
   46.           AmazonSimpleEmailServiceClientBuilder.standard()
   47.           // Replace US_WEST_2 with the AWS Region you're using for
   48.           // Amazon SES.
   49.             .withRegion(Regions.US_WEST_2).build();
   50.       SendEmailRequest request = new SendEmailRequest()
   51.           .withDestination(
   52.               new Destination().withToAddresses(TO))
   53.           .withMessage(new Message()
   54.               .withBody(new Body()
   55.                   .withHtml(new Content()
   56.                       .withCharset("UTF-8").withData(HTMLBODY))
   57.                   .withText(new Content()
   58.                       .withCharset("UTF-8").withData(TEXTBODY)))
   59.               .withSubject(new Content()
   60.                   .withCharset("UTF-8").withData(SUBJECT)))
   61.           .withSource(FROM)
   62.           // Comment or remove the next line if you are not using a
   63.           // configuration set
   64.           .withConfigurationSetName(CONFIGSET);
   65.       client.sendEmail(request);
   66.       System.out.println("Email sent!");
   67.     } catch (Exception ex) {
   68.       System.out.println("The email was not sent. Error message: " 
   69.           + ex.getMessage());
   70.     }
   71.   }
   72. }
   ```

1. 在 `AmazonSESSample.java` 中，将以下内容替换为您自己的值：
**重要**  
电子邮件地址区分大小写。请确保此处的地址与经验证的地址完全相同。
   + `SENDER@EXAMPLE.COM`：替换为您的 From (发件人) 电子邮件地址。运行此程序之前，您必须验证该地址。有关更多信息，请参阅 [Amazon SES 中已验证的身份](verify-addresses-and-domains.md)。
   + `RECIPIENT@EXAMPLE.COM`：替换为您的 To (收件人) 电子邮件地址。如果您的账户仍处于沙盒中，您还必须验证此地址，然后才能使用它。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。
   + **（可选）`us-west-2`** - 如果您要在美国西部（俄勒冈州）以外的区域中使用 Amazon SES，请将它替换为您要使用的区域。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

1. 保存 `AmazonSESSample.java`。

1. 要构建项目，请选择 **Project**，然后选择 **Build Project**。
**注意**  
如果禁用此选项，则可能启用自动构建；如果是这样，请跳过此步骤。

1. 要开始程序和发送电子邮件，请选择 **Run**，然后再次选择 **Run**。

1. 在 Eclipse 中查看控制台窗格的输出。如果已成功发送电子邮件，则控制台会显示“`Email sent!`”，否则将显示一条错误消息。

1. 如果已成功发送电子邮件，请登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------
#### [ PHP ]

本主题说明如何使用 [适用于 PHP 的 AWS SDK](https://aws.amazon.com/sdk-for-php/) 通过 Amazon SES 发送电子邮件。

**在开始前，请执行以下任务：**
+ **安装 PHP**：访问 [http://php.net/downloads.php](http://php.net/downloads.php) 可获得 PHP。本教程需要 PHP 版本 5.5 或更高版本。安装 PHP 后，在环境变量中添加 PHP 的路径，这样就能通过任何命令提示符运行 PHP。本教程中的代码已使用 PHP 7.2.7 进行测试。
+ **安装 适用于 PHP 的 AWS SDK 版本 3**-有关下载和安装说明，请参阅[适用于 PHP 的 AWS SDK 文档](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/installation.html)。本教程中的代码已使用版本 3.64.13 的软件开发工具包进行测试。

**要通过 Amazon SES 发送电子邮件，请使用 适用于 PHP 的 AWS SDK**

1. 在文本编辑器中，创建一个名为 `amazon-ses-sample.php` 的文件。粘贴以下代码：

   ```
    1. <?php
    2. 
    3. // If necessary, modify the path in the require statement below to refer to the 
    4. // location of your Composer autoload.php file.
    5. require 'vendor/autoload.php';
    6. 
    7. use Aws\Ses\SesClient;
    8. use Aws\Exception\AwsException;
    9. 
   10. // Create an SesClient. Change the value of the region parameter if you're 
   11. // using an AWS Region other than US West (Oregon). Change the value of the
   12. // profile parameter if you want to use a profile in your credentials file
   13. // other than the default.
   14. $SesClient = new SesClient([
   15.     'profile' => 'default',
   16.     'version' => '2010-12-01',
   17.     'region'  => 'us-west-2'
   18. ]);
   19. 
   20. // Replace sender@example.com with your "From" address.
   21. // This address must be verified with Amazon SES.
   22. $sender_email = 'sender@example.com';
   23. 
   24. // Replace these sample addresses with the addresses of your recipients. If
   25. // your account is still in the sandbox, these addresses must be verified.
   26. $recipient_emails = ['recipient1@example.com','recipient2@example.com'];
   27. 
   28. // Specify a configuration set. If you do not want to use a configuration
   29. // set, comment the following variable, and the
   30. // 'ConfigurationSetName' => $configuration_set argument below.
   31. $configuration_set = 'ConfigSet';
   32. 
   33. $subject = 'Amazon SES test (适用于 PHP 的 AWS SDK)';
   34. $plaintext_body = 'This email was sent with Amazon SES using the AWS SDK for PHP.' ;
   35. $html_body =  '<h1>AWS Amazon Simple Email Service Test Email</h1>'.
   36.               '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'.
   37.               'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-php/">'.
   38.               '适用于 PHP 的 AWS SDK</a>.</p>';
   39. $char_set = 'UTF-8';
   40. 
   41. try {
   42.     $result = $SesClient->sendEmail([
   43.         'Destination' => [
   44.             'ToAddresses' => $recipient_emails,
   45.         ],
   46.         'ReplyToAddresses' => [$sender_email],
   47.         'Source' => $sender_email,
   48.         'Message' => [
   49.           'Body' => [
   50.               'Html' => [
   51.                   'Charset' => $char_set,
   52.                   'Data' => $html_body,
   53.               ],
   54.               'Text' => [
   55.                   'Charset' => $char_set,
   56.                   'Data' => $plaintext_body,
   57.               ],
   58.           ],
   59.           'Subject' => [
   60.               'Charset' => $char_set,
   61.               'Data' => $subject,
   62.           ],
   63.         ],
   64.         // If you aren't using a configuration set, comment or delete the
   65.         // following line
   66.         'ConfigurationSetName' => $configuration_set,
   67.     ]);
   68.     $messageId = $result['MessageId'];
   69.     echo("Email sent! Message ID: $messageId"."\n");
   70. } catch (AwsException $e) {
   71.     // output error message if fails
   72.     echo $e->getMessage();
   73.     echo("The email was not sent. Error message: ".$e->getAwsErrorMessage()."\n");
   74.     echo "\n";
   75. }
   ```

1. 在 `amazon-ses-sample.php` 中，将以下内容替换为您自己的值：
   + **`path_to_sdk_inclusion`**—替换为包含在程序 适用于 PHP 的 AWS SDK 中所需的路径。有关详情，请参阅 [适用于 PHP 的 AWS SDK 文档](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/basic-usage.html)。
   + **`sender@example.com`** – 替换为您已使用 Amazon SES 验证过的电子邮件地址。有关更多信息，请参阅 [已验证的身份](verify-addresses-and-domains.md)。Amazon SES 中的电子邮件地址区分大小写。请确保您输入的地址与经验证的地址完全相同。
   + **`recipient1@example.com`，`recipient2@example.com`**：替换为收件人的地址。如果您的账户仍处于沙盒中，则还必须验证收件人地址。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。请确保您输入的地址与经验证的地址完全相同。
   + **（可选）`ConfigSet`**：如果您要在发送此电子邮件时使用配置集，请将此值替换为配置集的名称。有关配置集的更多信息，请参阅[在 SES 中使用配置集](using-configuration-sets.md)。
   + **（可选）`us-west-2`** - 如果您要在美国西部（俄勒冈州）以外的区域中使用 Amazon SES，请将它替换为您要使用的区域。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

1. 保存 `amazon-ses-sample.php`。

1. 要运行程序，请在 `amazon-ses-sample.php` 所在的同一目录中打开命令提示符，然后键入以下命令：

   ```
   $ php amazon-ses-sample.php
   ```

1. 检查输出。如果已成功发送电子邮件，则控制台会显示“`Email sent!`”，否则将显示一条错误消息。
**注意**  
如果在运行程序时遇到“cURL error 60: SSL certificate problem”错误，请下载最新的 CA 服务包，如[适用于 PHP 的 AWS SDK](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/faq.html#what-do-i-do-about-a-curl-ssl-certificate-error)文档中所述。然后，在 `amazon-ses-sample.php` 中，将以下行添加到 `SesClient::factory` 数组，将 `path_of_certs` 替换为您下载的 CA 捆绑的路径，然后重新运行程序。  

   ```
   1. 'http' => [
   2.    'verify' => 'path_of_certs\ca-bundle.crt'
   3. ]
   ```

1. 登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------
#### [ Ruby ]

本主题说明如何使用 [适用于 Ruby 的 AWS SDK](https://aws.amazon.com/sdk-for-ruby/) 通过 Amazon SES 发送电子邮件。

**在开始前，请执行以下任务：**
+ **安装 Ruby** —Ruby 的[网址为 https://www.ruby-lang。 org/en/downloads](https://www.ruby-lang.org/en/downloads/)/。本教程中的代码已使用 Ruby 1.9.3 进行测试。安装 Ruby 后，在环境变量中添加 Ruby 的路径，这样就能通过任何命令提示符运行 Ruby。
+ **安装 适用于 Ruby 的 AWS SDK** —有关下载和安装说明，请参阅《*适用于 Ruby 的 AWS SDK 开发人员指南*[》 适用于 Ruby 的 AWS SDK中的安装](https://docs.aws.amazon.com/sdk-for-ruby/latest/developer-guide/setup-install.html)。本教程中的示例代码已使用 2.9.36 版本的 适用于 Ruby 的 AWS SDK进行了测试。
+ **创建共享凭证文件** – 为了使此部分中的示例代码正常运行，您必须创建一个共享凭证文件。有关更多信息，请参阅 [创建共享凭证文件，以便在使用软件开发工具包通过 Amazon AWS SES 发送电子邮件时使用](create-shared-credentials-file.md)。

**要通过 Amazon SES 发送电子邮件，请使用 适用于 Ruby 的 AWS SDK**

1. 在文本编辑器中，创建一个名为 `amazon-ses-sample.rb` 的文件。将以下代码粘贴到该文件中：

   ```
    1. require 'aws-sdk'
    2. 
    3. # Replace sender@example.com with your "From" address.
    4. # This address must be verified with Amazon SES.
    5. sender = "sender@example.com"
    6. 
    7. # Replace recipient@example.com with a "To" address. If your account 
    8. # is still in the sandbox, this address must be verified.
    9. recipient = "recipient@example.com"
   10. 
   11. # Specify a configuration set. If you do not want to use a configuration
   12. # set, comment the following variable and the 
   13. # configuration_set_name: configsetname argument below. 
   14. configsetname = "ConfigSet"
   15.   
   16. # Replace us-west-2 with the AWS Region you're using for Amazon SES.
   17. awsregion = "us-west-2"
   18. 
   19. # The subject line for the email.
   20. subject = "Amazon SES test (适用于 Ruby 的 AWS SDK)"
   21. 
   22. # The HTML body of the email.
   23. htmlbody =
   24.   '<h1>Amazon SES test (适用于 Ruby 的 AWS SDK)</h1>'\
   25.   '<p>This email was sent with <a href="https://aws.amazon.com/ses/">'\
   26.   'Amazon SES</a> using the <a href="https://aws.amazon.com/sdk-for-ruby/">'\
   27.   '适用于 Ruby 的 AWS SDK</a>.'
   28. 
   29. # The email body for recipients with non-HTML email clients.  
   30. textbody = "This email was sent with Amazon SES using the 适用于 Ruby 的 AWS SDK."
   31. 
   32. # Specify the text encoding scheme.
   33. encoding = "UTF-8"
   34. 
   35. # Create a new SES resource and specify a region
   36. ses = Aws::SES::Client.new(region: awsregion)
   37. 
   38. # Try to send the email.
   39. begin
   40. 
   41.   # Provide the contents of the email.
   42.   resp = ses.send_email({
   43.     destination: {
   44.       to_addresses: [
   45.         recipient,
   46.       ],
   47.     },
   48.     message: {
   49.       body: {
   50.         html: {
   51.           charset: encoding,
   52.           data: htmlbody,
   53.         },
   54.         text: {
   55.           charset: encoding,
   56.           data: textbody,
   57.         },
   58.       },
   59.       subject: {
   60.         charset: encoding,
   61.         data: subject,
   62.       },
   63.     },
   64.   source: sender,
   65.   # Comment or remove the following line if you are not using 
   66.   # a configuration set
   67.   configuration_set_name: configsetname,
   68.   })
   69.   puts "Email sent!"
   70. 
   71. # If something goes wrong, display an error message.
   72. rescue Aws::SES::Errors::ServiceError => error
   73.   puts "Email not sent. Error message: #{error}"
   74. 
   75. end
   ```

1. 在 `amazon-ses-sample.rb` 中，将以下内容替换为您自己的值：
   + **`sender@example.com`** – 替换为您已使用 Amazon SES 验证过的电子邮件地址。有关更多信息，请参阅 [已验证的身份](verify-addresses-and-domains.md)。Amazon SES 中的电子邮件地址区分大小写。请确保您输入的地址与经验证的地址完全相同。
   + **`recipient@example.com`** – 替换为收件人的地址。如果您的账户仍处于沙盒中，您还必须验证此地址，然后才能使用它。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。请确保您输入的地址与经验证的地址完全相同。
   + **（可选）`us-west-2`** - 如果您要在美国西部（俄勒冈州）以外的区域中使用 Amazon SES，请将它替换为您要使用的区域。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

1. 保存 `amazon-ses-sample.rb`。

1. 要运行程序，请在 `amazon-ses-sample.rb` 所在的目录中打开命令提示符，然后键入 **ruby amazon-ses-sample.rb**

1. 检查输出。如果已成功发送电子邮件，则控制台会显示“`Email sent!`”，否则将显示一条错误消息。

1. 登录收件人地址的电子邮件客户端。您将找到已发送的电子邮件。

------
#### [ Python ]

本主题说明如何使用 [AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python/) 通过 Amazon SES 发送电子邮件。

**在开始前，请执行以下任务：**
+ **使用 Amazon SES 验证您的电子邮件地址** – 您必须先验证您拥有发件人的电子邮件地址，然后才能使用 Amazon SES 发送电子邮件。如果您的账户仍在 Amazon SES 沙盒中，您还必须验证收件人的电子邮件地址。我们建议您使用 Amazon SES 控制台来验证电子邮件地址。有关更多信息，请参阅 [创建电子邮件地址身份](creating-identities.md#verify-email-addresses-procedure)。
+ **获取您的 AWS 证书**-您需要访问密钥 ID 和 AWS 私有 AWS 访问密钥才能使用软件开发工具包访问 Amazon SES。您可以通过 [的](https://console.aws.amazon.com/iam/home?#security_credential)安全凭证 AWS 管理控制台页面来查找您的凭证。有关凭证的更多信息，请参阅[Amazon SES 凭证的类型](send-email-concepts-credentials.md)。
+ **安装 Python —Python** 已在 thon.org/downloads/ 上[https://www.py线](https://www.python.org/downloads/)。本教程中的代码已使用 Python 2.7.6 和 Python 3.6.1 进行了测试。安装 Python 后，在环境变量中添加 Python 的路径，这样就能通过任何命令提示符运行 Python。
+ **安装 AWS SDK for Python (Boto)—有关**下载和安装说明，请参阅[AWS SDK for Python (Boto) 文档](https://boto3.readthedocs.io/en/latest/guide/quickstart.html#installation)。本教程中的示例代码已使用 1.4.4 版本的 SDK for Python 进行了测试。

**使用 SDK for Python 通过 Amazon SES 发送电子邮件**

1. 在文本编辑器中，创建一个名为 `amazon-ses-sample.py` 的文件。将以下代码粘贴到该文件中：

   ```
    1. import boto3
    2. from botocore.exceptions import ClientError
    3. 
    4. # Replace sender@example.com with your "From" address.
    5. # This address must be verified with Amazon SES.
    6. SENDER = "Sender Name <sender@example.com>"
    7. 
    8. # Replace recipient@example.com with a "To" address. If your account 
    9. # is still in the sandbox, this address must be verified.
   10. RECIPIENT = "recipient@example.com"
   11. 
   12. # Specify a configuration set. If you do not want to use a configuration
   13. # set, comment the following variable, and the 
   14. # ConfigurationSetName=CONFIGURATION_SET argument below.
   15. CONFIGURATION_SET = "ConfigSet"
   16. 
   17. # If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
   18. AWS_REGION = "us-west-2"
   19. 
   20. # The subject line for the email.
   21. SUBJECT = "Amazon SES Test (SDK for Python)"
   22. 
   23. # The email body for recipients with non-HTML email clients.
   24. BODY_TEXT = ("Amazon SES Test (Python)\r\n"
   25.              "This email was sent with Amazon SES using the "
   26.              "AWS SDK for Python (Boto)."
   27.             )
   28.             
   29. # The HTML body of the email.
   30. BODY_HTML = """<html>
   31. <head></head>
   32. <body>
   33.   <h1>Amazon SES Test (SDK for Python)</h1>
   34.   <p>This email was sent with
   35.     <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
   36.     <a href='https://aws.amazon.com/sdk-for-python/'> AWS SDK for Python (Boto)</a>.</p>
   37. </body>
   38. </html>
   39.             """            
   40. 
   41. # The character encoding for the email.
   42. CHARSET = "UTF-8"
   43. 
   44. # Create a new SES resource and specify a region.
   45. client = boto3.client('ses',region_name=AWS_REGION)
   46. 
   47. # Try to send the email.
   48. try:
   49.     #Provide the contents of the email.
   50.     response = client.send_email(
   51.         Destination={
   52.             'ToAddresses': [
   53.                 RECIPIENT,
   54.             ],
   55.         },
   56.         Message={
   57.             'Body': {
   58.                 'Html': {
   59.                     'Charset': CHARSET,
   60.                     'Data': BODY_HTML,
   61.                 },
   62.                 'Text': {
   63.                     'Charset': CHARSET,
   64.                     'Data': BODY_TEXT,
   65.                 },
   66.             },
   67.             'Subject': {
   68.                 'Charset': CHARSET,
   69.                 'Data': SUBJECT,
   70.             },
   71.         },
   72.         Source=SENDER,
   73.         # If you are not using a configuration set, comment or delete the
   74.         # following line
   75.         ConfigurationSetName=CONFIGURATION_SET,
   76.     )
   77. # Display an error if something goes wrong.	
   78. except ClientError as e:
   79.     print(e.response['Error']['Message'])
   80. else:
   81.     print("Email sent! Message ID:"),
   82.     print(response['MessageId'])
   ```

1. 在 `amazon-ses-sample.py` 中，将以下内容替换为您自己的值：
   + **`sender@example.com`** – 替换为您已使用 Amazon SES 验证过的电子邮件地址。有关更多信息，请参阅 [已验证的身份](verify-addresses-and-domains.md)。Amazon SES 中的电子邮件地址区分大小写。请确保您输入的地址与经验证的地址完全相同。
   + **`recipient@example.com`** – 替换为收件人的地址。如果您的账户仍处于沙盒中，您还必须验证此地址，然后才能使用它。有关更多信息，请参阅 [请求生产访问权限（从 Amazon SES 沙盒中移出）](request-production-access.md)。请确保您输入的地址与经验证的地址完全相同。
   + **（可选）`us-west-2`** - 如果您要在美国西部（俄勒冈州）以外的区域中使用 Amazon SES，请将它替换为您要使用的区域。有关已推出 Amazon SES 的区域的列表，请参阅《AWS 一般参考》**中的 [Amazon Simple Email Service（Amazon SES）](https://docs.aws.amazon.com/general/latest/gr/rande.html#ses_region)。

1. 保存 `amazon-ses-sample.py`。

1. 要运行程序，请在 `amazon-ses-sample.py` 所在的目录中打开命令提示符，然后键入 **python amazon-ses-sample.py**。

1. 检查输出。如果已成功发送电子邮件，则控制台会显示“`Email sent!`”，否则将显示一条错误消息。

1. 登录收件人地址的电子邮件客户端。您将看到已发送的电子邮件。

------

# 创建共享凭证文件，以便在使用软件开发工具包通过 Amazon AWS SES 发送电子邮件时使用
<a name="create-shared-credentials-file"></a>

以下过程演示如何在主目录中创建一个共享凭证文件。若要让软件开发工具包示例代码正常运行，您必须创建此文件。

1. 在文本编辑器中，创建一个新文件。在此文件中，粘贴以下代码：

   ```
   1. [default]
   2. aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
   3. aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
   ```

1. 在您刚刚创建的文本文件中，`YOUR_AWS_ACCESS_KEY`替换为您唯一的 AWS 访问密钥 ID，然后`YOUR_AWS_SECRET_ACCESS_KEY`替换为您唯一的私有访问 AWS 密钥。

1. 保存该文件。下表显示了您的操作系统的正确位置和文件名。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ses/latest/dg/create-shared-credentials-file.html)
**重要**  
请勿在保存凭证文件时包含文件扩展名。

# Amazon SES 支持的内容编码
<a name="content-encodings"></a>

提供以下内容供参考。

Amazon SES 支持以下内容编码：
+ `deflate`
+ `gzip`
+ `identity`

根据 [RFC 7231](https://tools.ietf.org/html/rfc7231#section-5.3.4) 规范，Amazon SES 还支持以下 Accept-Encoding 标头格式：
+ `Accept-Encoding:deflate,gzip`
+ `Accept-Encoding:`
+ `Accept-Encoding:*`
+ `Accept-Encoding:deflate;q=0.5,gzip;q=1.0`
+ `Accept-Encoding:gzip;q=1.0,identity;q=0.5,*;q=0`

# Amazon SES 和安全协议
<a name="security-protocols"></a>

本主题介绍当您连接到 Amazon SES 时以及当 SES 将电子邮件传递给接收方时，您可以使用的安全协议。

## 电子邮件发件人到 Amazon SES
<a name="security-client-to-ses"></a>

您用于连接到 Amazon SES 的安全协议取决于您使用的是 Amazon SES API 还是 Amazon SES SMTP 接口，如下所述。

### HTTPS
<a name="security-client-to-ses-api"></a>

如果您使用的是 Amazon SES API（直接使用或通过 AWS 软件开发工具包），则所有通信都将通过 Amazon SES HTTPS 终端节点通过 TLS 加密。Amazon SES HTTPS 端点支持 TLS 1.2 和 TLS 1.3。

### SMTP 接口
<a name="security-client-to-ses-smtp"></a>

如果通过 SMTP 接口访问 Amazon SES，那么您需要使用传输层安全性（TLS）来加密您的连接。请注意，提及 TLS 时通常使用其前身协议的名称：安全套接字层（SSL）。

Amazon SES 支持两种建立 TLS 加密连接的机制：STARTTLS 和 TLS Wrapper。
+ **STARTTLS**：STARTTLS 是一种将未加密的连接升级到加密连接的方式。提供了适用于各种协议的 STARTTLS 版本；SMTP 版本已在 [RFC 3207](https://www.ietf.org/rfc/rfc3207.txt) 中定义。对于 STARTTLS 连接，Amazon SES 支持 TLS 1.2 和 TLS 1.3。
+ **TLS Wrapper**：TLS Wrapper（也称为 SMTPS 或握手协议）是一种在无需先建立未加密连接的情况下启动加密连接的方式。利用 TLS Wrapper，Amazon SES SMTP 端点不执行 TLS 协商：客户端负责使用 TLS 连接到端点，然后继续对整个对话使用 TLS。虽然 TLS Wrapper 是一项旧协议，但许多客户端仍支持它。对于 TLS 包装器连接，Amazon SES 支持 TLS 1.2 和 TLS 1.3。

有关使用这些方法来连接到 Amazon SES SMTP 接口的信息，请参阅[连接到 Amazon SES SMTP 端点](smtp-connect.md)。

## Amazon SES 到接收方
<a name="security-ses-to-receiver"></a>

 虽然 TLS 1.3 是我们的默认传送方式，但 SES 可以使用早期版本的 TLS 将电子邮件传送到邮件服务器。

默认情况下，Amazon SES 使用*操作 TLS*。SES 中的机会主义 TLS 始终使用 STARTTLS 并且不包括 TLS 包装器。流程包括建立初始的明文连接，然后如果客户端和服务器都支持 STARTTLS，则升级到 TLS 加密会话。如果 SES 无法建立安全连接，那么它会发送未加密的邮件。

您可以使用配置集来更改此行为。使用 [PutConfigurationSetDeliveryOptions](https://docs.aws.amazon.com/ses/latest/APIReference/API_PutConfigurationSetDeliveryOptions.html)API 操作将配置的`TlsPolicy`属性设置为`Require`。您可以使用 [AWS CLI](https://aws.amazon.com/cli) 来实施此更改。

**配置 Amazon SES 以要求配置集的 TLS 连接**
+ 在命令行输入以下命令：

  ```
  aws sesv2 put-configuration-set-delivery-options --configuration-set-name MyConfigurationSet --tls-policy REQUIRE
  ```

  在前面的示例中，*MyConfigurationSet*替换为配置集的名称。

  如果您使用此配置集来发送电子邮件，那么只有当 Amazon SES 能够建立安全连接时，它才会将邮件发送到接收电子邮件服务器。如果 Amazon SES 无法与接收电子邮件服务器建立安全连接，那么它会丢弃该邮件。

## End-to-end 加密
<a name="security-end-to-end"></a>

您可以使用 Amazon SES 发送使用 S/MIME 或 PGP 加密的消息。使用这些协议的消息会被发送人加密。只有拥有解密消息所需私有密钥的收件人才能查看其内容。

Amazon SES 支持以下 MIME 类型，您可以使用这些类型来发送 S/MIME 加密的电子邮件：
+ `application/pkcs7-mime`
+ `application/pkcs7-signature`
+ `application/x-pkcs7-mime`
+ `application/x-pkcs7-signature`

Amazon SES 还支持以下 MIME 类型，您可以使用它们来发送通过 PGP 加密的电子邮件：
+ `application/pgp-encrypted`
+ `application/pgp-keys`
+ `application/pgp-signature`

# Amazon SES 标头字段
<a name="header-fields"></a>

Amazon SES 可接受采用 [RFC 822](https://www.rfc-editor.org/rfc/rfc822.html) 中所述格式的所有电子邮件标头。

以下字段不能在消息的标头部分中出现多次：
+ `Accept-Language`
+ `acceptLanguage`
+ `Archived-At`
+ `Auto-Submitted`
+ `Bounces-to`
+ `Comments`
+ `Content-Alternative`
+ `Content-Base`
+ `Content-Class`
+ `Content-Description`
+ `Content-Disposition`
+ `Content-Duration`
+ `Content-ID`
+ `Content-Language`
+ `Content-Length`
+ `Content-Location`
+ `Content-MD5`
+ `Content-Transfer-Encoding`
+ `Content-Type`
+ `Date`
+ `Delivered-To `
+ `Disposition-Notification-Options`
+ `Disposition-Notification-To`
+ `DKIM-Signature`
+ `DomainKey-Signature`
+ `Errors-To`
+ `From`
+ `Importance`
+ `In-Reply-To`
+ `Keywords`
+ `List-Archive`
+ `List-Help`
+ `List-Id`
+ `List-Owner`
+ `List-Post`
+ `List-Subscribe`
+ `List-Unsubscribe`
+ `List-Unsubscribe-Post`
+ `Message-Context`
+ `Message-ID`
+ `MIME-Version`
+ `Organization`
+ `Original-From`
+ `Original-Message-ID`
+ `Original-Recipient`
+ `Original-Subject`
+ `Precedence`
+ `Priority`
+ `References`
+ `Reply-To`
+ `Return-Path`
+ `Return-Receipt-To`
+ `Sender`
+ `Solicitation`
+ `Sensitivity`
+ `Subject`
+ `Thread-Index`
+ `Thread-Topic`
+ `User-Agent`
+ `VBR-Info`

**注意事项**
+ `acceptLanguage` 字段为非标准字段。如果可能，您应该使用 `Accept-Language` 标头。
+ 如果您指定 `Date` 标头，则 Amazon SES 会使用时间戳将其覆盖，该时间戳对应于 SES 接受消息时 UTC 时区中的日期和时间。
+ 如果您提供 `Message-ID` 标头，则 Amazon SES 会用自己的值来覆盖标头。
+ 如果您指定 `Return-Path` 标头，则 Amazon SES 会将退信和投诉通知发送到您指定的地址。但是，收件人收到的消息包含不同的 `Return-Path` 标头值。
+ 如果您使用 Amazon SES API v2 `SendEmail` 操作，并且指定了*简单*或*模板化*内容类型，或者使用 `SendBulkEmail` 操作，则无法为 SES 设置的标头设置自定义标题内容；因此，不允许将以下标头作为自定义标头：
  + `BCC`, `CC`, `Content-Disposition`, `Content-Type`, `Date`, `From`, `Message-ID`, `MIME-Version`, `Reply-To`, `Return-Path`, `Subject`, `To`

# 在 SES 中处理电子邮件附件
<a name="attachments"></a>

SES 中的电子邮件附件是您在使用 SES API v2 `SendEmail` 和 `SendBulkEmail` 操作时可以随电子邮件消息一起包含的文件。此功能使您能够通过添加符合 SES 支持的 MIME 类型的文档（例如 PDFs Word 文件、图像或其他文件类型）来丰富电子邮件内容。您还可以包含内联图像，这些图像直接在电子邮件内容中呈现，无需收件人单独下载。每封电子邮件可以包含多个附件，总消息大小限制为 40MB。

**注意**  
具有 `Raw` 内容类型的 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html) SES API v2、SMTP 接口和 SES API v1 继续通过[原始电子邮件 MIME 消息构建](send-email-raw.md#send-email-raw-mime)处理附件。

## 附件在 SES 中的工作原理
<a name="how-attachments-work"></a>

在发送带有附件的电子邮件时，在不同的阶段会发生两种不同的编码：

第 1 阶段：向 SES 发送数据：
+ 当您想要向 SES 发送附件时，二进制数据（如 PDF 或图像）需要转换为可以安全传输的格式。
+ 这就是 base64 编码的用武之地——它是必需的，因为您不能在 JSON 请求中发送原始二进制数据。
+ 如果你使用的是 AWS SDK，它会自动处理这种编码。
+ 如果您使用的是 AWS CLI，则需要在发送附件之前自己对其进行 base64 编码。

第 2 阶段：SES 创建电子邮件：
+ SES 收到您的数据后，需要创建一封带有附件的实际电子邮件。
+ 这就是[ContentTransferEncoding](#attachment-structure)设置的用武之地。
+ SES 将使用您指定的任何编码 ContentTransferEncoding 方法自动格式化最后一封电子邮件中的附件。

可以这样理解——这类似于通过邮件发送包裹。首先，你需要将包裹送到邮局（第 1 阶段——需要 Base64 编码），然后邮局会对其进行适当的包装以进行最终交付（第 2 阶段- ContentTransferEncoding）。

## 附件对象结构
<a name="attachment-structure"></a>

当您通过 SES 发送带附件的电子邮件时，该服务会自动处理复杂的 MIME 消息构建。您只需通过以下 SES API v2 [https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Attachment.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_Attachment.html) 对象结构提供附件内容和元数据：
+ `FileName`（必填）：向收件人显示的文件名（必须包含文件扩展名）。如果未提供，SES 将从 `ContentType` 的扩展名中派生一个 `FileName`。
+ `ContentType`（可选）：[符合 IANA 标准的媒体类型标识符](https://www.iana.org/assignments/media-types/media-types.xhtml)。
+ `ContentDisposition`（可选）：指定应如何呈现附件：`ATTACHMENT`*（默认）*或 `INLINE`。
+ `ContentDescription`（可选）：内容的简短描述。
+ `RawContent`（必填）：附件的实际内容。
+ `ContentTransferEncoding`（可选）：指定在将附件有效载荷组装到电子邮件的 mime 消息中时如何编码：`SEVEN_BIT`*（默认）*、`BASE64` 或 `QUOTED_PRINTABLE`。

所有附加内容在传输到 SES 端点进行发送之前必须编码为 base64。如果您使用 AWS SDK 客户端发出 API 调用，则会自动为您处理。如果你使用的是客户端 AWS CLI，或者已经实现了自己的客户端，则必须自己进行编码，例如：
+ 纯文本内容：`Text attachment sample content.`
+ Base64 编码：`VGV4dCBhdHRhY2htZW50IHNhbXBsZSBjb250ZW50Lg==`

以下示例说明了在使用 SES API v2 指定附件时如何使用附件对象结构，[https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html)以及如何使用 AWS CLI 引用包含附件对象元素的 JSON 文件进行[https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendBulkEmail.html)操作。

**Example — SendEmail 内容简单**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-simple.json
```
**request-send-email-simple.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Simple": {
            "Subject": {
                "Data": "Email with attachment"
            },
            "Body": {
                "Text": {
                    "Data": "Please see attached document."
                },
                "Html": {
                    "Data": "Please see attached <b>document</b>."
                }
            },
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example — SendEmail 带有简单内容和内联附件**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-simple-inline-attachment.json
```
**request-send-email-simple-inline-atchament.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Simple": {
            "Subject": {
                "Data": "Email with attachment"
            },
            "Body": {
                "Html": {
                    "Data": "<html><body>Our logo:<br><img src=\"cid:logo123\" alt=\"Company Logo\"></body></html>"
                }
            },
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "INLINE",
                    "FileName": "logo.png",
                    "ContentId": "logo123",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example — SendEmail 包含模板内容**  

```
aws sesv2 send-email --cli-input-json file://request-send-email-template.json
```
**request-send-email-template.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "Destination": {
        "ToAddresses": [
            "recipient@example.com"
        ]
    },
    "Content": {
        "Template": {
            "TemplateName": "MyTemplate",
            "TemplateData": "{\"name\":\"John\"}",
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    }
}
```

**Example — 附 SendBulkEmail 带附件内容**  

```
aws sesv2 send-bulk-email --cli-input-json file://request-send-bulk-email.json
```
**request-send-bulk-email.json**  

```
{
    "FromEmailAddress": "sender@example.com",
    "DefaultContent": {
        "Template": {
            "TemplateName": "MyTemplate",
            "TemplateData": "{}",
            "Attachments": [
                {
                    "RawContent": "<base64-encoded-content>",
                    "ContentDisposition": "ATTACHMENT",
                    "FileName": "document.pdf",
                    "ContentDescription": "PDF Document Attachment",
                    "ContentTransferEncoding": "BASE64"
                }
            ]
        }
    },
    "BulkEmailEntries": [
        {
            "Destination": {
                "ToAddresses": [
                    "recipient@example.com"
                ]
            },
            "ReplacementEmailContent": {
                "ReplacementTemplate": {
                    "ReplacementTemplateData": "{\"name\":\"John\"}"
                }
            }
        }
    ]
}
```

## 最佳实践
<a name="attachments-best-practices"></a>
+ 保持总消息大小（包括附件）在 40MB 以下。
+ 在可能的情况下，让 SES 根据文件扩展名自动检测内容类型。
+ 仅当内容类型超出[常见 MIME 类型](https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types)时才显式指定内容类型。
+ 考虑使用内联图像以获得更好的电子邮件渲染效果。
+ SES 支持广泛的附件 MIME 类型，除了 [不支持的附件类型](#mime-types) 中列出的那些。

## SES 不支持的附件类型
<a name="mime-types"></a>

您可以使用多用途 Internet 邮件扩展（MIME）标准，通过 Amazon SES 发送带附件的电子邮件。Amazon SES 接受所有文件附件类型，带有以下列表中的文件扩展名的附件*除外*。


|  |  |  |  |  | 
| --- |--- |--- |--- |--- |
| .ade .adp .app .asp .bas .bat .cer .chm .cmd .com .cpl .crt .csh .der .exe .fxp .gadget .hlp  | .hta .inf .ins .isp .its .js .jse .ksh .lib .lnk .mad .maf .mag .mam .maq .mar .mas .mat  | .mau .mav .maw .mda .mdb .mde .mdt .mdw .mdz .msc .msh .msh1 .msh2 .mshxml .msh1xml .msh2xml .msi .msp  | .mst .ops .pcd .pif .plg .prf .prg .reg .scf .scr .sct .shb .shs .sys .ps1 .ps1xml .ps2 .ps2xml  | .psc1 .psc2 .tmp .url .vb .vbe .vbs .vps .vsmacros .vss .vst .vsw .vxd .ws .wsc .wsf .wsh .xnk  | 

有些 ISPs 还有其他限制（例如对存档附件的限制），因此我们建议您在发送正式电子邮件 ISPs 之前测试通过主要方式发送的电子邮件。