基本概念
Webhook 是一种「反向 API」机制:由服务端主动监听来自客户端 (或第三方系统)的 HTTP 请求并做出响应。在本系统中,Webhook 用于接收用户自定义的 HTTP POST 请求, 自动将其转换为邮件发送给指定收件人。
简单易用
无需复杂 SDK,一个 HTTP POST 即可触发邮件
Markdown 渲染
邮件正文支持 Markdown 语法,富文本展示
独立配置
每条路径独立配置收件人、主题、发件人
快速开始
无需任何配置,使用 cURL 即可发送一封邮件通知:
bash
curl -X POST https://your-domain.com/webhook/W2E_your_user_key/server-alert \
-H "Content-Type: application/json" \
-d '{
"content": "## 服务器告警\n\n- **时间**:2026-07-21 10:30:00\n- **状态**:CPU 使用率 95%\n- **操作**:请立即处理"
}'
注意:必须在控制台先创建名为
server-alert 的 WebHook 路径并配置收件人,否则接口返回 404。
推荐流程
- 登录控制台:访问
/dashboard - 创建路径:点击「新建路径」,填写名称、描述、收件人
- 获取 user_key:在控制台个人资料页查看
- 集成调用:在你的业务系统中发起 HTTP POST 请求
路由说明
Webhook2Email 使用「用户 key + 路径 key」的双层路由设计:
https://your-domain.com/webhook/{user_key}/{path_key}
│
服务地址
│ │
用户 key
│ │
路径 key
- user_key:用户注册时自动生成,64 位随机字符串,全局唯一
- path_key:用户在控制台为不同业务场景创建的路径标识(如
server-alert、deploy-notify)
请求格式
请求头
| 头部名称 | 是否必填 | 说明 |
|---|---|---|
Content-Type | 必填 | 必须为 application/json |
请求体(JSON)
json
{
"content": "Markdown 格式的邮件正文",
"subject": "邮件主题(可选)",
"recipients": ["a@example.com", "b@example.com"]
}
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
content | string | 必填* | Markdown 格式的邮件正文 |
subject | string | 可选 | 邮件主题,覆盖路径默认主题 |
recipients | string[] | 可选 | 本次请求的收件人,覆盖路径默认收件人 |
* 当路径的 notify_email=false 时,content 可省略。
响应格式
成功响应(HTTP 200)
json
{
"success": true,
"message": "邮件已加入发送队列",
"data": {
"log_id": 12345,
"path_key": "server-alert",
"recipients": ["ops@example.com"],
"quota_remaining": 18
}
}
失败响应(HTTP 4xx/5xx)
json
{
"success": false,
"message": "请求体解析失败: expected value at line 1 column 1",
"data": null
}
代码示例
python
import requests
response = requests.post(
"https://your-domain.com/webhook/W2E_abc/server-alert",
json={
"content": "## 服务器告警\n\n- **时间**:2026-07-21 10:30:00\n- **状态**:CPU 使用率 95%"
}
)
print(response.json())
javascript
// 直接发送 JSON 请求即可
const body = JSON.stringify({
content: '## 服务器告警\n\n- **状态**:CPU 95%'
});
await fetch('https://your-domain.com/webhook/W2E_abc/server-alert', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: body
});
go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]string{
"content": "## 服务器告警\n\n- **状态**:CPU 95%",
}
body, _ := json.Marshal(payload)
resp, err := http.Post(
"https://your-domain.com/webhook/W2E_abc/server-alert",
"application/json",
bytes.NewReader(body),
)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}
错误处理
| HTTP 状态码 | 含义 | 排查方法 |
|---|---|---|
| 200 | 成功 | - |
| 400 | 请求参数错误 | 检查 JSON 格式、字段类型 |
| 403 | 额度不足 | 购买套餐或等待下月额度刷新 |
| 404 | 路径不存在 | 检查 user_key、path_key 是否正确 |
| 500 | 服务器内部错误 | 查看服务端日志或联系管理员 |
重试建议
- 5xx 错误:建议指数退避重试(1s, 2s, 4s, 8s...),最多 3 次
- 4xx 错误:通常不需要重试,检查请求参数
- 网络超时:默认 10 秒超时,可调整
DISPATCH_TIMEOUT_SECS
常见问题
邮件没收到但接口返回 200?
可能原因:
- 邮件在发送队列中(异步模式),稍等片刻
- 收件人被 SMTP 服务器拒收(检查垃圾邮件箱)
- 控制台「邮件日志」页面查看发送状态和错误信息
能不能发送 HTML 邮件?
不支持。系统强制使用 Markdown 渲染邮件正文。如需 HTML,请自行实现邮件客户端。
免费额度每月什么时候刷新?
每月 1 日 00:00 UTC 刷新。可在控制台查看具体剩余额度。