反馈体系漫谈(四):即时通讯通知——Webhook 连接一切

在 DevOps 实际工作中,即时通讯工具(IM)是最常用的通知通道。构建成功没、部署完没、Pipeline 跑到哪一步了——这些日常信息,最适合在群里说一声。相比邮件的正式和短信的重度,IM 是“刚刚好”的那个。

IM 通知背后的核心技术是 Webhook——一个简单的 HTTP 回调机制,理解了这个,飞书、企业微信、钉钉、Slack 的通法都是一样的。

一、Webhook 是什么

Webhook 本质上就是一个 URL,你往它 POST 数据,它帮你把消息发到指定位置

你的系统 → HTTP POST → Webhook URL → IM 平台 → 群聊消息

没有复杂的协议、不需要长连接、不用装 SDK。你只需要发一个 HTTP 请求:

curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx \
  -H "Content-Type: application/json" \
  -d '{
    "msg_type": "text",
    "content": {
      "text": "构建失败: myapp/master Build#42"
    }
  }'

就是这么简单。剩下的事情——消息怎么渲染、怎么推送到客户端——IM 平台帮你搞定。

二、飞书机器人

创建机器人

  1. 飞书群 → 设置 → 群机器人 → 添加机器人 → 自定义机器人
  2. 设置名称(如“CI 通知助手”)、安全设置(建议添加签名校验)
  3. 复制 Webhook 地址

消息格式

飞书机器人支持多种消息类型:

// 文本消息
{
  "msg_type": "text",
  "content": {
    "text": "【构建通知】myapp/master 构建成功,耗时 3m"
  }
}

// 富文本(推荐,信息密度高)
{
  "msg_type": "interactive",
  "card": {
    "header": {
      "title": {"tag": "plain_text", "content": "构建失败"},
      "template": "red"
    },
    "elements": [
      {"tag": "div", "text": {"tag": "lark_md", "content": "**项目**: myapp\n**分支**: master\n**失败阶段**: 测试"}},
      {"tag": "action", "actions": [
        {"tag": "button", "text": {"tag": "plain_text", "content": "查看日志"}, "url": "https://jenkins/123"}
      ]}
    ]
  }
}

卡片消息比纯文本好得多——颜色能区分成功/失败、按钮能跳到日志页、信息分区清晰。

安全设置

飞书支持三种安全校验:

方式 说明 推荐
签名校验 请求带 timestamp + sign,服务端验证 ✅ 推荐
IP 白名单 只允许指定 IP 请求 辅助使用
无校验 知道 Webhook 地址就能调用 ❌ 不推荐

签名校验的计算方式:

import hashlib, hmac, time

def generate_sign(secret, timestamp):
    string_to_sign = f"{timestamp}\n{secret}"
    hmac_code = hmac.new(
        string_to_sign.encode(), digestmod=hashlib.sha256
    ).digest()
    return hmac_code.hex()

三、企业微信机器人

企业微信的 Webhook 机制几乎相同:

  1. 群聊 → 群机器人 → 添加
  2. 获取 Webhook URL: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx

消息发送:

{
  "msgtype": "markdown",
  "markdown": {
    "content": "## 构建失败 <font color=\"warning\">myapp/master</font>\n> 失败阶段: 单元测试\n> [查看详情](https://jenkins/123)"
  }
}

企业微信的 markdown 类型支持颜色标签,很适合做直观的构建状态通知。

飞书 vs 企业微信 对比

  飞书 企业微信
消息格式 文本 + 卡片(interactive) 文本 + Markdown + 图文
富文本能力 强(卡片布局) 一般(Markdown)
按钮/交互 支持 不支持
签名校验 支持 不支持(key 即认证)
适用场景 复杂通知(有按钮和分区) 简洁通知

四、集成到 Jenkins Pipeline

// Jenkinsfile - 飞书通知示例
pipeline {
    agent any
    environment {
        FEISHU_WEBHOOK = credentials('feishu-webhook-url')
    }
    stages {
        stage('Build') { steps { sh 'mvn package' } }
        stage('Test')  { steps { sh 'mvn test' } }
    }
    post {
        failure {
            script {
                def msg = [
                    msg_type: "interactive",
                    card: [
                        header: [
                            title: [tag: "plain_text", content: "构建失败"],
                            template: "red"
                        ],
                        elements: [[
                            tag: "div",
                            text: [tag: "lark_md", 
                                   content: "**项目**: ${env.JOB_NAME}\n**构建号**: #${env.BUILD_NUMBER}\n**阶段**: ${env.STAGE_NAME}\n**日志**: [查看](${env.BUILD_URL})"]
                        ]]
                    ]
                ]
                sh "curl -X POST ${FEISHU_WEBHOOK} -H 'Content-Type: application/json' -d '${groovy.json.JsonOutput.toJson(msg)}'"
            }
        }
        success {
            script {
                sh "curl -X POST ${FEISHU_WEBHOOK} -H 'Content-Type: application/json' -d '{\"msg_type\":\"text\",\"content\":{\"text\":\"✅ ${env.JOB_NAME} #${env.BUILD_NUMBER} 构建成功\"}}'"
            }
        }
    }
}

几个实践建议:

  • Webhook URL 存为 Jenkins Credential,不要硬编码在 Jenkinsfile 里
  • 成功用简洁消息,失败用详细卡片——失败时需要更多信息来定位
  • 不同环境发不同群:开发环境通知开发群,生产环境通知运维群
  • @ 人 功能:飞书卡片支持 at 指定人,失败时可以 @ 触发者
  • 实际使用时,在Jenkins共享库中实现,Jenkinsfile只需要调用共享库方法

小结

Webhook 是即时通讯通知的核心机制。不管是飞书、企业微信还是其他 IM 工具,原理都是“往一个 URL POST JSON 数据”。掌握了这个,剩下的就是选好消息格式、做好安全设置、分环境分场景发到正确的群。

即时通讯通知处在“日常”这个使用级别——高频、轻量、实时。下一篇也就是最后一篇,我们聊怎么把邮件、短信、IM 串起来,设计一套完整的通知策略。

每天前进一小步,就是一个新的高度!

作者:唐明

出处:/post/feedback-04-im

版权:本站使用"CC BY 4.0"创作共享协议,转载请在文章明显位置注明作者及出处。