notify:一次 Send 把通知发到所有消息平台——Go 多渠道通知库的用法与取舍
项目地址:github.com/nikoksr/notify
Go 文档:pkg.go.dev/github.com/nikoksr/notify
服务出故障要发告警时,运维团队在钉钉,开发团队在 Slack,老板只收邮件,值班同事用 Telegram。要把一条告警同时送达这些平台,原来得接多套 SDK,每个平台一套 API,配置散落各处。之后再加一个新的通知渠道,又得从头集成一遍。
notify 解决的就是这种多平台重复集成。
notify 是什么
notify 是一个 Go 通知库,目标很集中:用统一的 API 向各种消息平台发送通知。
核心模型很简单:创建 Notifier 实例,往里注册多个 Service(每个 Service 对应一个消息平台),然后一次 Send 调用把消息扇出到所有已注册平台。
API 面就五个函数:
New():创建 Notifier 实例UseServices():注册通知服务到 NotifierSend():发送消息,扇出到所有已注册服务Enable()/Disable():启用/禁用通知WithOptions():配置选项
没有复杂配置体系、消息模板引擎或通知路由规则,只做一件事:把一条消息发到多个平台。
快速上手
一个完整的 Telegram 通知示例:
package main
import (
"context"
"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/telegram"
)
func main() {
// 创建 Telegram 服务
telegramService, _ := telegram.New("your_telegram_api_token")
// 添加接收者(聊天 ID)
telegramService.AddReceivers(-1234567890)
// 注册到全局 Notifier
notify.UseServices(telegramService)
// 发送消息
_ = notify.Send(
context.Background(),
"Subject/Title",
"The actual message — Hello, you awesome gophers! :)",
)
}
这是使用全局函数的写法。notify 也支持创建独立实例:
n := notify.New()
n.UseServices(telegramService, slackService, emailService)
err := n.Send(ctx, "Alert", "Database is down!")
用实例而不是全局函数的好处是:不同场景可以用不同的 Notifier 实例,各自注册不同的服务组合,互不干扰。
多平台同时发送
最核心的价值在这里——一次 Send,多平台送达:
// Telegram
telegramService, _ := telegram.New("bot_token")
telegramService.AddReceivers(-1009876543210)
// Slack
slackService := slack.New("webhook_url")
slackService.AddReceivers("#alerts")
// Email
emailService := mail.New("smtp.gmail.com:587")
emailService.AddReceivers("oncall@example.com")
emailService.AuthenticateSMTP("sender@gmail.com", "password")
// 钉钉
dingTalkService := dingding.New("webhook_url", "secret")
// 注册所有服务
n := notify.New()
n.UseServices(telegramService, slackService, emailService, dingTalkService)
// 一次调用,四个平台同时收到
err := n.Send(ctx, "Critical Alert", "Production database is down!")
执行这行 Send,Telegram、Slack 的 #alerts 频道、值班邮箱、钉钉群都会收到消息。
支持的平台
按类型划分如下。
即时通讯
- Telegram:Bot API,支持多个聊天 ID
- Discord:webhook 或 Bot,支持频道
- Slack:Incoming Webhook,支持频道
- RocketChat:webhook 或 SDK
- Matrix:mautrix SDK
- Viber:Viber Bot API
企业通讯
- 钉钉(DingTalk):群机器人 webhook
- 飞书(Lark):webhook
- Microsoft Teams:Incoming Webhook
- Google Chat:webhook
- 微信(WeChat):企业微信 API
邮件
- SMTP:标准 SMTP 协议,任意邮件服务商
- Amazon SES
- Mailgun
- SendGrid
- Mailtrap:测试邮件服务
短信 / 电话
- Twilio
- Plivo
- TextMagic
推送通知
- Firebase Cloud Messaging(FCM):Android / iOS
- Pushover
- Pushbullet:多设备同步
- Webpush:浏览器 Web Push,基于 VAPID
- Bark:iOS 专用推送
社交媒体
- Twitter:发推
- Reddit:发帖
- WhatsApp:API 可用性需按当前版本确认
告警平台
- PagerDuty:触发事件
- Amazon SNS:多协议扇出
其他
- HTTP:通用 webhook 对接
- Syslog:写入系统日志
总共 30 多个平台,覆盖常见通知渠道。
每个 Service 的使用模式
虽然底层平台差别很大,但 Service 的使用模式统一:
- 创建 Service 实例,传入认证信息(token、webhook、API key 等)
- 调用
AddReceivers指定接收方(聊天 ID、频道名、邮箱、手机号等) - 调用
UseServices注册到 Notifier
Slack:
slackService := slack.New("https://hooks.slack.com/services/xxx/yyy/zzz")
slackService.AddReceivers("#alerts", "#engineering")
n.UseServices(slackService)
邮件:
emailService := mail.New("smtp.gmail.com:587")
emailService.AuthenticateSMTP("sender@gmail.com", "app_password")
emailService.AddReceivers("oncall@example.com", "dev-team@example.com")
n.UseServices(emailService)
Discord:
discordService, _ := discord.New("bot_token")
discordService.AddReceivers("channel_id_1", "channel_id_2")
n.UseServices(discordService)
模式一致,熟悉一个 Service 后其他平台基本可以照着写。
启用 / 禁用控制
notify 支持运行时启用和禁用,适合做静默时段或功能开关:
n := notify.NewWithOptions(notify.Disable)
// 维护期间通知被禁用,Send 不会实际发送
n.Send(ctx, "test", "this won't be sent")
// 维护结束后启用
n.WithOptions(notify.Enable)
n.Send(ctx, "test", "now it will be sent")
这比在业务代码里到处写 if 判断要干净。
设计理念
notify 遵循「简单优先」:
- 不引入消息队列:同步发送,不依赖 Redis、RabbitMQ 等中间件
- 不做消息模板:调用方传什么字符串就发什么,格式化是调用方的责任
- 不做通知路由:所有已注册服务都会收到消息;条件路由(比如按严重级别决定是否发短信)由调用方实现
- 不去重、不限流:这些属于业务逻辑
如果需求复杂到需要消息队列、模板渲染、通知降级策略,那更适合引入完整的告警平台(如 AlertManager)。仅做同步直发多渠道通知,notify 这种轻量方案是够用的。
总结
notify 解决的是多平台通知里反复出现的集成问题:30 多个渠道,一套 API,一次 Send 全部送达。
它不是企业级告警平台的替代品,但处理大多数中小型项目里的多渠道告警需求足够直接。通知部分的复杂度从「N 个平台 × M 套 SDK」降到一个库一次调用,这是 notify 的核心价值。