File size: 5,881 Bytes
89419ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# External API 第三方对接速览

如果你是第三方调用方,只需要记住下面这套最小流程。

详细字段说明见:

- [Temp Mail 域名池与外部注册 API 说明](temp-mail-external-api.md)
- [External API 调用示例](external-api-examples.md)

---

## 1. 先查能力

调用:

```http
GET /api/external/capabilities
```

目的:

- 看当前支持哪些邮箱类型
- 看有哪些上传目标可用
- 看 `temp_mail` 是否有可用服务

你要重点关注返回中的:

- `email_types[].type`
- `email_types[].services[].id`
- `email_types[].services[].name`
- `upload_providers[].provider`
- `upload_providers[].services[].id`
- `upload_providers[].services[].name`

示例:

```json
{
  "email_types": [
    {
      "type": "temp_mail",
      "available": true,
      "services": [
        {"id": 3, "name": "Worker temp mail A", "priority": 0},
        {"id": 7, "name": "Worker temp mail B", "priority": 0}
      ]
    }
  ],
  "upload_providers": [
    {
      "provider": "sub2api",
      "available": true,
      "services": [
        {"id": 1, "name": "sub2-main", "priority": 0},
        {"id": 4, "name": "sub2-backup", "priority": 10}
      ]
    }
  ]
}
```

这时:

- `email.service_id=3` 表示选 `Worker temp mail A`
- `email.service_id=7` 表示选 `Worker temp mail B`
- `upload.service_id=1` 表示选 `sub2-main`
- `upload.service_id=4` 表示选 `sub2-backup`

> 不是 0/1 猜出来的,而是以 `capabilities` 当前返回的 `id + name` 为准。

---

## 2. 再创建批次

调用:

```http
POST /api/external/registration/batches
```

你只需要决定 4 件事:

1. 要注册多少个:`count`
2. 用哪种邮箱:`email.type`
3. 是否上传:`upload.enabled`
4. 怎么执行:`execution.mode`

最小示例:

```json
{
  "count": 10,
  "email": {
    "type": "temp_mail"
  },
  "upload": {
    "enabled": false
  },
  "execution": {
    "mode": "pipeline",
    "concurrency": 1,
    "interval_min": 0,
    "interval_max": 0
  }
}
```

如果你不传:

- `email.service_id`
- `upload.service_id`

则系统会自动选择当前可用服务。

如果你想固定某一个邮箱服务或上传目标,就必须先通过 `capabilities` 拿到对应 `id`。

---

## 3. 保存 `batch_uuid`

创建成功后,响应里会返回:

```json
{
  "batch_uuid": "..."
}
```

后续所有查询和取消都依赖这个值。

---

## 4. 轮询状态

调用:

```http
GET /api/external/registration/batches/{batch_uuid}
```

你只需要关注:

- `status`
- `requested_count`
- `completed_count`
- `success_count`
- `failed_count`
- `upload_success_count`
- `upload_failed_count`
- `recent_errors`

终态只有这几个:

- `completed`
- `completed_partial`
- `failed`
- `cancelled`

---

## 5. 如需终止就取消

调用:

```http
POST /api/external/registration/batches/{batch_uuid}/cancel
```

仅 `pending` / `running` 批次可以取消。

---

## 6. 推荐调用策略

### 推荐 1:始终传 `idempotency_key`

这样你的上游系统在重试创建请求时,不会重复创建同一批任务。

### 推荐 2:先看 `capabilities`,再决定参数

不要写死:

- 邮箱类型
- 上传 provider
- service_id

否则后台一改配置,你的调用方就会直接打空。

尤其不要假设:

- `1` 永远是某个邮箱
- `1` 永远是某个上传渠道

`service_id` 的意义完全取决于当前环境里的实际配置。

### 推荐 3:把“成功标准”定义成批次维度

不要要求“必须全部成功”。

更合理的是读取:

- `success_count`
- `failed_count`

再由你的系统决定是否接受这次结果。

---

## 7. 常见错误处理

| 状态码 | 含义 | 建议处理 |
| --- | --- | --- |
| `401` | API Key 错误 | 检查请求头 |
| `403` | 外部 API 未启用 | 联系后台启用 |
| `404` | 批次不存在 | 检查 `batch_uuid` |
| `422` | 请求体格式不合法 | 修正参数结构 |
| `400` | 业务参数非法 | 修正业务参数 |
| `503` | 服务暂时不可用 | 稍后重试 |

---

## 8. 第三方最小接入步骤

建议接入顺序:

1. 接入 `GET /capabilities`
2. 接入 `POST /batches`
3. 接入 `GET /batches/{batch_uuid}`
4. 最后再接 `POST /cancel`

这样最快能形成闭环。

---

## 9. 一句话理解

外部调用方只负责:

- 下发批次
- 轮询状态
- 读取成功/失败统计

系统内部负责:

- 选邮箱
- 真正执行注册
- 上传账号
- 失败回收与重启恢复

---

## 10. API Key 从哪里拿

外部调用方使用的:

```http
X-API-Key: 你的APIKey
```

这个值不是通过接口获取的,而是由系统管理员在本项目配置里设置后,直接发给对接方。

---

## 11. `failure_category` 字段

批次响应现在会额外返回:

```json
"failure_category": null
```

或:

```json
"failure_category": "config"
```

允许值只有四种:

- `config`
- `business`
- `transient`
- `null`

推荐按下面方式消费:

- `transient`:可按你的策略做退避重试
- `config`:不要自动重试,先人工检查配置
- `business`:不要自动重试,先人工检查业务约束
- `null`:当前批次还没有失败分类,通常表示批次未失败

说明:

- `failure_reason` 继续保留,主要给人看
- `failure_category` 主要给程序判断
- `POST /api/external/registration/batches/{batch_uuid}/cancel` 的响应也可能带上该字段;这是为了和其他批次响应保持一致,不需要时可直接忽略

### 返回规则

- `pending` / `running` / `completed` / `completed_partial` / `cancelled`
  - `failure_category = null`
- `failed`
  - `failure_category` 一定是 `config | business | transient` 之一

也就是说:

- 对接方自己拿不到
- 必须由项目维护者提供
- 如果项目维护者修改了 Key,对接方也要同步更新请求头