一个协议兼容 ntfy 的发布/订阅通知服务,整个后端跑在 Cloudflare Workers 免费套餐上: 每个主题一个 SQLite 型 Durable Object,订阅者通过休眠 WebSocket 挂在全球边缘上,空闲时不消耗运行时长。
curl -X POST \
-H "Authorization: Bearer <publish-key>" \
-H "Title: 磁盘告警" \
-H "Priority: high" \
-H "Tags: warning" \
https://push.luoml.kdns.fr/disk-alerts \
-d "/dev/sda1 用了 92%"
# WebSocket(推荐:空闲订阅几乎不消耗配额)
websocat wss://push.luoml.kdns.fr/disk-alerts/ws
# 一次性拉取缓存(最省配额)
curl -s "https://push.luoml.kdns.fr/disk-alerts/json?poll=1&since=all"
# 官方 App:添加自建服务器 push.luoml.kdns.fr,订阅同名主题
GET /v1/config | 服务器能力声明(官方 Web App 会探测) |
GET /<topic>/auth | 可读性探测(官方 Android App 会调用) |
GET /<topic>/json|/sse|/ws|/raw | 四种订阅传输 |
POST /<topic> | 发布(需要 publish key) |
免费套餐有硬顶,所以这些数字是公开的,超限时一律返回 HTTP 429 并附 Retry-After。
| 范围 | 上限 |
|---|---|
| 正文 / 标题 / 标签 | 4096 B / 128 B / 64 B,动作按钮 ≤3 |
| 主题名 | [A-Za-z0-9][A-Za-z0-9_-]{0,63},保留词除外 |
| 同一来源 IP 对同一主题 | 20 条 / 分钟 |
| 单个主题 | 300 条 / 小时 |
| 同一来源 IP 新建主题 | 60 个 / 天 |
| 全服务消息量 | 30,000 条 / 天,到 80% 即软着陆 |
| 消息缓存 | 每主题最近 200 条或 24 小时,先到为准 |
| 一次订阅请求的主题数 | 150(长连流式 ≤8) |
| 长连 HTTP 流并发 | 20 条,消息延迟 ≤45 秒;要秒级请用 WebSocket |
轮询(?poll=1) | 建议 ≥300 秒一次,频繁轮询最先撞配额 |
本服务对订阅匿名开放,发布需要密钥。禁止用于垃圾消息、钓鱼、欺诈或任何违法内容; 正文与主题名的上限见上表,命中关键词黑名单的发布直接返回 403。 滥用请联系 lucasluo520@gmail.com。 因运行在免费配额上,服务不承诺投递延迟或可用性:请优先使用 WebSocket 或轮询, 并把重连交给 ntfy 官方的退避策略,不要自建重试风暴。