流水线跑完(成功或失败),团队怎么第一时间知道?——机器人发消息到群里。这篇讲 CI/CD 流水线怎么接飞书/钉钉机器人(国内主流;Slack 类同原理)。
一、原理:webhook 一条 curl
机器人通知的原理极简:调用 webhook URL 发一条 HTTP POST(JSON 内容),机器人就把消息推到群里:
流水线跑完 → curl POST → webhook URL → 群里出现消息不需要 SDK、不需要鉴权(webhook 本身就是密钥)——一个 curl 就能集成。
二、飞书自定义机器人
1. 创建机器人
群设置 → 群机器人 → 添加机器人 → 自定义机器人 → 取名(如"发布助手")→ 生成 Webhook 地址:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxx-xxxx-xxxx2. 发消息(curl)
bash
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/xxxx-xxxx-xxxx" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "text",
"content": { "text": "🚀 发布成功:myapp v1.0 已部署" }
}'3. 富文本(消息卡片,更醒目)
bash
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/xxxx-xxxx-xxxx" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": { "title": { "tag": "plain_text", "content": "CI 构建结果" }, "template": "red" },
"elements": [
{ "tag": "div", "text": { "tag": "lark_md", "content": "**myapp** 构建失败\n- 分支: main\n- 提交: 9fcde35" } }
]
}
}'template 控制颜色:red(失败)/ green(成功)/ blue(进行中)——一眼看出状态。
三、钉钉自定义机器人
1. 创建机器人
群设置 → 智能群助手 → 添加机器人 → 自定义 → 安全设置选加签(推荐)→ 生成 Webhook + 密钥:
https://oapi.dingtalk.com/robot/send?access_token=xxxx2. 加签(Secret 生成签名)
bash
# 时间戳 + 密钥 → HMAC-SHA256 → Base64 编码
TIMESTAMP=$(date +%s%3N)
SECRET="你的加签密钥"
SIGN=$(printf '%s\n%s' "$TIMESTAMP" "$SECRET" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64 | tr -d '\n')
# 注意:上一条是错误写法,正确加签公式为:
# sign = base64(hmac_sha256(secret, timestamp + "\n" + secret))
SIGN=$(printf "%s\n%s" "$TIMESTAMP" "$SECRET" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)3. 发消息(curl)
bash
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=xxxx×tamp=$TIMESTAMP&sign=$SIGN" \
-H "Content-Type: application/json" \
-d '{
"msgtype": "text",
"text": { "content": "❌ 构建失败:myapp" }
}'钉钉加签:把
timestamp + "\n" + secret做 HMAC-SHA256 再 Base64。安全设置不选加签就不用 sign 参数(但不安全,URL 泄露就能发消息)。
四、集成到 GitHub Actions workflow
yaml
name: CI/CD
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- run: npm test
# 成功通知:只有前面的步骤都成功才跑
- name: 通知成功
if: success()
run: |
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/${{ secrets.FEISHU_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"✅ 发布成功:myapp 已上线"}}'
# 失败通知:任何步骤失败都跑(if: failure())
- name: 通知失败
if: failure()
run: |
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/${{ secrets.FEISHU_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d '{"msg_type":"text","content":{"text":"❌ 构建失败:查看 https://github.com/xxx/yyy/actions"}}'关键:
if: success():前面全成功才发(成功通知)if: failure():任何一步失败都发(失败通知)- webhook URL 存 Secrets(
${{ secrets.FEISHU_WEBHOOK }}),不写死在 workflow(见《GitHub Actions 部署到自己服务器》的密钥安全)
五、其他通知渠道
| 渠道 | 方式 | 适用 |
|---|---|---|
| 飞书 | 自定义机器人 webhook | 国内公司主流(本文) |
| 钉钉 | 自定义机器人 webhook + 加签 | 国内公司主流(本文) |
| 企业微信 | 群机器人 webhook | 企微用户 |
| Slack | Incoming Webhook | 海外团队 |
| 邮件 | SMTP 发邮件 | 正式报告、审计 |
原理完全一样(webhook + curl),只是 URL 和 JSON 格式不同。
六、最佳实践
- 成功/失败分开处理:
success()/failure()独立 step - 消息带上下文:分支、提交号、Actions 链接(方便点进去看)
- webhook 存 Secrets:不写死在 yml
- 别刷屏:只通知关键节点(部署成功/失败),别每次 push 都发
- 加签/签名:钉钉选加签;飞书 webhook 别泄露
小结
- 通知原理:webhook + curl POST,一条命令搞定
- 飞书:
/open-apis/bot/v2/hook/xxx+ text/interactive 消息 - 钉钉:
robot/send?access_token=xxx+ 加签(timestamp + secret 的 HMAC) - GitHub Actions:
if: success()/if: failure()独立 step + Secrets 存 webhook - 消息带分支/提交/Actions 链接,别刷屏
完整部署链路见《CI/CD 快速入门》和《GitHub Actions 部署到自己服务器》。
