go-workwx推送企业微信需正确配置corpid、agent_id和secret三参数,sdk自动缓存并刷新access_token,避免裸写http导致签名或认证错误。

直接用 moltybob/dingtalk 发钉钉消息,别自己拼 JSON
第三方 SDK 不是“可选”,而是必须——裸写 HTTP 请求极易出错。比如钉钉机器人要求签名(timestamp + sign),漏掉毫秒级时间戳或 HMAC-SHA256 算错,返回 {"errcode":310000,"errmsg":"invalid signature"} 你得花半小时查文档比对参数顺序。
用 moltybob/dingtalk 的典型流程就三步:
- 初始化 client:
dingtalk.NewClient("https://oapi.dingtalk.com/robot/send?access_token=xxx") - 构造消息体:
dingtalk.NewTextMessage("服务异常:CPU 使用率 > 90%")或dingtalk.NewMarkdownMessage("## 告警", "### 详情\n- 实例:svc-01\n- 时间:2026-08-03T12:45:00Z") - 发送:
client.Send(ctx, msg),自动处理签名、重试、超时(默认 5s)
注意:Webhook 地址里 access_token 是敏感信息,别硬编码。建议从环境变量读取:os.Getenv("DINGTALK_TOKEN"),配合 go-secrets 或 K8s Secret 挂载。
go-workwx 推送企业微信要填对 agent_id 和 secret
企业微信和钉钉不同,它不靠 Webhook,而是走 OAuth2 认证换取 access_token 后再发消息。很多开发者卡在第一步:用错凭证。
go-workwx 要求你提供三个核心参数:
-
corpid:企业 ID(URL 里https://work.weixin.qq.com/cgi-bin/loginpage?appid=xxx中的xxx不是它,得进「我的企业」页面底部找) -
agent_id:应用 ID(不是 corpsecret!是创建应用后分配的数字 ID,例如1000002) -
secret:应用 secret(在应用详情页「启用 API」下复制,每换一次就失效)
初始化后调用 SendText() 即可,SDK 内部会缓存 access_token 并自动刷新。但要注意:access_token 有效期 2 小时,如果进程常驻且长时间无调用,首次发消息可能因 token 过期失败——SDK 默认会重试一次,但若网络不通,错误日志只打印 "failed to get access token",容易误判为配置问题。
PagerDuty v2 告警必须禁用 pagerduty-go,手写 http.Client
官方 pagerduty-go SDK 已归档,还在用 v1 API(已停用),强行用会返回 404 Not Found 或 415 Unsupported Media Type。唯一可靠方式是直调 v2 Events API。
关键字段不能错:
-
Content-Type必须是application/json(不是application/vnd.pagerduty+json) -
Authorization头格式为Token token=xxx(不是Bearer xxx) -
routing_key是 Integration Key(在 PagerDuty UI 创建「Events API v2」集成时生成),不是 API Key -
event_action填trigger/resolve/acknowledge,别拼错
示例 payload:
{
"routing_key": "a1b2c3d4...",
"event_action": "trigger",
"payload": {
"summary": "Go service panic detected",
"severity": "critical",
"source": "svc-auth"
}
}
别忘了设 http.Client.Timeout = 10 * time.Second,PagerDuty 对超时请求不保证幂等性,重复发可能触发多次告警。
所有 SDK 都要处理 ctx 超时和错误重试边界
报警模块不是“发出去就行”,它必须可控、可观察、可降级。常见疏漏:
- 没传
context.WithTimeout(ctx, 3*time.Second),网络卡住时整个告警逻辑阻塞 goroutine - 把
client.Send()放在关键路径(如 HTTP handler 主流程),一旦钉钉/企微接口抖动,用户请求直接超时 - 忽略临时错误(如 DNS 解析失败、连接拒绝),直接 panic 或静默丢弃,导致告警完全失联
推荐做法:
- 告警调用一律异步:
go func() { _ = client.Send(context.Background(), msg) }(),或用带缓冲的 channel 控制并发 - 对
net/http错误分类处理:连接类错误(url.Error、net.OpError)可重试 2 次;4xx 错误(如400 Bad Request)立即失败,记录日志并告警自身异常 - 加个降级开关:当连续 5 次发送失败,自动切到备用通道(如本地文件落盘 + 定时扫)或关闭告警
最易被忽略的是:SDK 初始化时没设 http.Transport 的 MaxIdleConnsPerHost。默认 2,高并发场景下大量新建连接,触发钉钉限流(429 Too Many Requests)——这问题不会立刻暴露,压测时才突然崩。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











