Providers
Herald 支持多种通知渠道,包括即时通讯、邮件、短信、推送和 Webhook。
按任务找渠道
| 你想做什么 | 用哪个 | 申请难度 |
|---|---|---|
| 消息发进飞书/企微/钉钉群 | feishu / wecom / dingtalk | 群里加机器人即得,零审批 |
| 推送到自己手机 | telegram 或 wechat(Server酱等) | Telegram 零审批;微信第三方扫码即用 |
| 发验证码 / 事务短信 | aliyunsms / tencentsms / neteasesms | 需签名+模板审核 |
| 发邮件 | email | 有 SMTP 账号即可(授权码) |
| 推到 Discord / Slack 频道 | discord / slack | 创建 Webhook 即得,零审批 |
| 对接自建系统 / 本地调试 | webhook / log | 零凭据 |
| 公众号模板消息 | wechatmp | 需认证服务号 |
| App 推送(Android/Web) | fcm | 需 Firebase 项目,控制台生成服务账号即用 |
| App 推送(iOS/macOS) | apns | 需 Apple Developer 账号,Keys 页生成 .p8 |
| App 推送(国内,Android/iOS/鸿蒙) | jpush / getui | 需极光/个推账号,控制台建应用即得 AppKey/Master Secret |
每个渠道页都含:申请凭据 → 配置 → 发第一条消息(可跟跑的命令)→ 常见错误。
Provider 分类
即时通讯
| Provider | 说明 | 状态 |
|---|---|---|
telegram | Telegram Bot | ✅ |
feishu | 飞书机器人 | ✅ |
wecom | 企业微信机器人 | ✅ |
wechat | 微信个人推送 (ServerChan/PushPlus/WxPusher) | ✅ |
wechatmp | 微信公众号模板消息 | ✅ |
dingtalk | 钉钉机器人 | ✅ |
slack | Slack | ✅ |
discord | Discord | ✅ |
邮件
| Provider | 说明 | 状态 |
|---|---|---|
email | SMTP 邮件 | ✅ |
短信
| Provider | 说明 | 状态 |
|---|---|---|
aliyunsms | 阿里云短信 | ✅ |
tencentsms | 腾讯云短信 | ✅ |
neteasesms | 网易云信短信 | ✅ |
推送
| Provider | 说明 | 状态 |
|---|---|---|
fcm | Firebase Cloud Messaging (Android/Web) | ✅ |
apns | Apple Push Notification service (iOS/macOS) | ✅ |
jpush | 极光推送 JPush (Android/iOS/鸿蒙) | ✅ |
getui | 个推 Getui (Android/iOS/鸿蒙) | ✅ |
其他
| Provider | 说明 | 状态 |
|---|---|---|
webhook | 通用 Webhook | ✅ |
log | 日志输出 | ✅ |
Builtin vs Worker
Builtin Providers
Builtin Providers 直接在 Herald 核心进程中运行,配置块长这样:
yaml
providers:
telegram:
type: telegram
enabled: true
config:
token: "your_token"
chat_id: "your_chat_id"Worker Providers
Worker Providers 在独立的进程中运行,通过 WebSocket 连接到 Herald:
yaml
providers:
custom-provider:
type: worker
config:
target: "custom-worker-01" # 等价 name 键启用/禁用 Provider
通过配置文件
yaml
providers:
telegram:
type: telegram
enabled: true # 启用
config:
token: "your_token"
slack:
type: slack
enabled: false # 禁用
config:
webhook_url: "your_url"通过 API
bash
# 启用
curl -X POST http://localhost:8080/api/v1/providers/telegram/enable
# 禁用
curl -X POST http://localhost:8080/api/v1/providers/telegram/disable通过 Dashboard
在 Dashboard 的 Providers 页面中,点击每个 Provider 卡片的启用/禁用按钮。
配置优先级
- API 调用(运行时修改)
- 配置文件(启动时加载)
- 默认配置
配置文件中的 enabled 字段指定 Provider 的初始状态,之后可以通过 API 或 Dashboard 动态修改。
错误分类与重试
投递失败是否重试由错误分类决定(六类词汇,见 受众领域模型总纲):
| 分类 | 触发 | 是否重试 |
|---|---|---|
temporary | 上游 5xx、一般网络错误 | ✅ 按 retry 配置退避重投 |
rate_limited | 上游 429 | ✅ 带 Retry-After 时按其等待(封顶 retry.max_delay),否则同上 |
timeout | 请求超时(408 或传输超时) | ✅ 同上 |
permanent | 上游明确拒绝且重试无意义 | ❌ 立即 failed |
authentication | 凭据无效 | ❌ 立即 failed |
invalid_request | 请求本身不合法 | ❌ 立即 failed |
- 走内置 HTTP 客户端(
core/httpclient)的 Provider 自动获得分类:408 归timeout、429 归rate_limited、5xx 与传输错误归temporary(三类可重试),其余 4xx 不分类也重试不了(classifyStatus注释原话:retrying them cannot succeed) - 「HTTP 200 但业务码失败」不在自动分类范围内,由 Provider 自己决定:腾讯云/网易云信给业务错误整体套
httpclient.WithRetry(业务码失败也重试),阿里云业务码只返回裸错误(不重试)——各渠道差异见对应 Provider 页 - 重试等待发生在队列侧:可重试失败的任务带
next_retry_at重新入队,到点再投,期间 worker 去投别的任务;Retry-After的等待同样在队列侧消化(封顶retry.max_delay)。日志(/api/v1/logs)里该任务只有一行,重试期间停在pending - 可重试类耗尽
retry.max后任务进入 dead,终态错误留在任务的last_error;日志(/api/v1/logs)的status始终是success/failed二值 wire 词汇
最佳实践
- 凭据走环境变量,配置文件里写
$VAR占位 - 同类型配多个实例(如两个 webhook 指向不同接收端),故障时切路由不换业务代码
enabled: false只是关掉投递,Provider 仍会按配置创建、凭据照常校验;临时下线走 API 或 Dashboard 的动态开关- 排查投递问题先查
/api/v1/logs,失败原因带渠道原始报错
注册机制与 worker 占位
- 所有 Builtin Provider 的工厂统一在
providers/builtin/registry注册(RegisterBuiltinProviders),上表即注册全集,无需手工注册 worker类型的 provider 是远程 Worker 的本地占位:本地 Deliver 为空操作,任务由调度器按target路由到对应 Worker 节点执行(name默认worker,target默认取name)。适用场景与开发方式见 Worker Runtime 与 Worker SDK