# SMTP 网关

SMTP 网关接受标准邮件提交，并将每条消息作为事务性邮件转发到 [Messaging API v2 `Notify`](/zh/developer/api-reference/messaging-api-v2/notify/)。当现有的邮件工具（如 MTA、框架邮件程序、SDK）比向 API 发送 JSON 请求更容易集成时，可以使用它。

<Aside type="note">
该网关仅用于事务性邮件。对于受众细分、计划发送或 A/B 测试活动，请直接调用 `Notify`。
</Aside>

## 工作原理

```
   any SMTP client          smtp gateway              Messaging API v2
   ──────────────── ──────> ──────────────── ──────> ─────────────────
       submission            STARTTLS                gRPC Notify
       AUTH PLAIN            + AUTH PLAIN            Authorization: Token
```

1. 客户端连接到 `smtp.pushwoosh.com` 的 `587` 端口，使用 `STARTTLS` 将连接升级到 TLS，然后使用 `AUTH PLAIN` 进行身份验证。
2. 网关解析 MIME 消息并构建一个包含 `platforms: ["EMAIL"]` 和 `message_type: TRANSACTIONAL` 的 `Notify` 请求。
3. 来自 `AUTH PLAIN` 的 API 令牌作为 `Authorization` 标头转发到 Messaging API。令牌验证、应用程序匹配、发送身份和退信处理都在 API 端进行。

## 端点

| 设置 <div style="width:140px"></div> | 值 <div style="width:340px"></div> |
|---------|-------|
| 主机 | `smtp.pushwoosh.com` |
| 端口 | `587` (SMTP 提交) |
| TLS | `STARTTLS` — `AUTH` 前强制执行 |
| 身份验证 | `AUTH PLAIN` |

## 身份验证

`AUTH PLAIN` 使用两个 Pushwoosh 凭据。

| AUTH 字段 <div style="width:120px"></div> | Pushwoosh 值 |
|------------|-----------------|
| `username` | [应用程序代码](/zh/developer/api-reference/api-identifiers/#application-code)，例如 `XXXXX-XXXXX` |
| `password` | [服务器 API 令牌](/zh/developer/api-reference/api-access-token/#server-api-token) |

在 TLS 之外，`AUTH` 会被拒绝。令牌永远不会出现在消息中——它仅用于授权上游的 `Notify` 调用。

## 消息如何映射到 Notify

| MIME 或 SMTP 字段 <div style="width:200px"></div> | Notify 字段 |
|--------------------|--------------|
| `RCPT TO` | `target.users.list` — Pushwoosh 将这些地址解析为订阅者 |
| AUTH `username` | `application` |
| `Subject:` 标头 | `email_payload.subject["default"]` (RFC 2047 解码) |
| `From:` 标头 | `email_payload.from` — `name` 和 `email` |
| HTML 部分 | `email_payload.body` (当两个部分都存在时首选) |
| 纯文本部分 | `email_payload.body` (当 HTML 不存在时使用) |
| `MAIL FROM` | 忽略 — Pushwoosh 会替换为自己的发送身份并自行处理退信 |

每条消息都以 `schedule.send_date: now` 发送。

## 限制

| 限制 <div style="width:280px"></div> | 值 |
|-------|-------|
| 最大消息大小 | 25 MiB |
| 每个信封的最大收件人数 (`RCPT TO`) | 50 |

## 错误映射

由 Messaging API 返回的 gRPC 状态码会转换为标准的 SMTP 回复码，以便任何 SMTP 客户端都能显示有意义的错误。

| 上游 gRPC 状态 <div style="width:280px"></div> | SMTP 回复 <div style="width:120px"></div> | 含义 |
|----------------------|------------|---------|
| `Unauthenticated` | `535 5.7.8` | 应用程序代码或 API 令牌错误。 |
| `PermissionDenied` | `550 5.7.1` | 该令牌对此应用程序没有权限。 |
| `InvalidArgument` / `FailedPrecondition` / `OutOfRange` | `550 5.6.0` | MIME 内容错误（例如缺少主题或正文）。 |
| `NotFound` | `550 5.1.1` | 未找到应用程序或收件人。 |
| `ResourceExhausted` | `452 4.5.3` | 已达到速率限制 — 请稍后重试。 |
| `DeadlineExceeded` / `Unavailable` | `451 4.4.1` | 上游暂时性错误 — 请稍后重试。 |
| 任何其他失败 | `451 4.5.0` | 内部暂时性错误 — 请稍后重试。 |

`4xx` 范围内的代码是临时的，客户端应重试；`5xx` 范围内的代码是永久性的，需要客户端修复。

## 示例：使用 swaks 发送

```bash
swaks --server smtp.pushwoosh.com:587 \
      --auth-user "XXXXX-XXXXX" \
      --auth-password "YOUR_API_TOKEN" \
      --tls \
      --from from@example.com \
      --to user@example.com \
      --header "Subject: Hello from SMTP gateway" \
      --body "Plain-text body"
```

MIME 正文中的 `From:` 标头是到达 Pushwoosh 的内容 — `--from` 信封 (`MAIL FROM`) 会被丢弃。

## 注意事项

- 网关是无状态的，不存储消息。一旦转发，交付就由 Messaging API 负责。
- 退信、投诉和取消订阅链接由 Pushwoosh 处理，与任何其他事务性邮件相同。
- 对于营销活动发送（细分、计划、A/B 测试），请直接使用 `Notify` — SMTP 网关仅用于提交。

## 另请参阅

<CardGrid>
  <LinkCard title="Messaging API v2 概述" href="/developer/api-reference/messaging-api-v2/" />
  <LinkCard title="Notify" href="/developer/api-reference/messaging-api-v2/notify/" />
  <LinkCard title="电子邮件有效负载参考" href="/developer/api-reference/messaging-api-v2/email-payload-reference/" />
  <LinkCard title="营销邮件与事务性邮件" href="/product/messaging-channels/marketing-vs-transactional/" />
</CardGrid>