通知中转服务 · 密钥只在服务端 · Cloudflare Access 鉴权
其他应用通过本服务发送通知,底层的钉钉 / Bark 密钥保存在 Cloudflare Secrets Store, 调用方永远拿不到。鉴权由 Cloudflare Access(service token)在边缘完成。
每个请求需带 service token 两个头:
CF-Access-Client-Id: <your-client-id> CF-Access-Client-Secret: <your-client-secret>
token 由 Cloudflare Zero Trust 签发,每个调用方一个,可单独吊销。
| 方法 | 路径 | 请求体 | 响应 |
|---|---|---|---|
| GET | /health | — | {"ok":true} |
| POST | /dingtalk | {title?, body} | {"ok":true} |
| POST | /bark | {title?, body, sound?, group?, url?, level?} | {"ok":true} |
body 必填;title 可选。失败返回 {"ok":false} +
对应 4xx/5xx 状态码,不回显任何配置细节。
钉钉:
curl -X POST https://notify.example.com/dingtalk \
-H "CF-Access-Client-Id: $CF_ID" \
-H "CF-Access-Client-Secret: $CF_SECRET" \
-H "Content-Type: application/json" \
-d '{"title":"部署完成","body":"web-app 已上线"}'
Bark:
curl -X POST https://notify.example.com/bark \
-H "CF-Access-Client-Id: $CF_ID" \
-H "CF-Access-Client-Secret: $CF_SECRET" \
-H "Content-Type: application/json" \
-d '{"title":"提醒","body":"该喝水了","sound":"glass","group":"daily"}'
Node.js(其他 Worker / 本地脚本):
await fetch("https://notify.example.com/bark", {
method: "POST",
headers: {
"CF-Access-Client-Id": process.env.CF_ID,
"CF-Access-Client-Secret": process.env.CF_SECRET,
"Content-Type": "application/json",
},
body: JSON.stringify({ title: "hi", body: "hello from script" }),
});
仓库:git@github.com:danny-plus/notify-relay.git