PHP项目怎么实现企业微信告警?

wen java案例 2

本文目录导读:

PHP项目怎么实现企业微信告警?

  1. 方式一:群机器人 Webhook(推荐,最简单)
  2. 方式二:应用消息推送(企业级,更专业)
  3. 注意事项(重要)
  4. 进阶建议

在PHP项目中实现企业微信告警,最常用的方式是通过企业微信的“群机器人”发送Webhook消息(最简单、无需开发)或通过“应用消息”主动推送(更灵活、可定向)。

以下是两种主流实现方式的详细步骤和代码示例:

群机器人 Webhook(推荐,最简单)

这种方式适合将告警消息发送到指定的企业微信群聊中,运维告警群”。

步骤:

  1. 创建群机器人

    • 在企业微信中,进入目标群聊 -> 点击右上角“...” -> “群机器人” -> “添加” -> 创建一个机器人。
    • 复制机器人的 Webhook 地址(形如 https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx)。
  2. PHP 代码实现

    <?php
    /**
     * 发送企业微信群机器人告警
     *
     * @param string $webhookUrl 群机器人的 webhook 地址
     * @param string $content    告警内容(支持 Markdown 语法)
     * @return bool|string       成功返回 true,失败返回错误信息
     */
    function sendWechatGroupRobotAlert($webhookUrl, $content) {
        // 构建消息体(支持 text 或 markdown 类型)
        $data = [
            'msgtype' => 'markdown', // 推荐使用 markdown,更美观
            'markdown' => [
                'content' => $content
            ]
        ];
        // 也可以使用纯文本 (替换 msgtype 和 text):
        // 'msgtype' => 'text',
        // 'text' => ['content' => $content]
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $webhookUrl);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 生产环境建议开启
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        if ($error) {
            return "CURL Error: " . $error;
        }
        $result = json_decode($response, true);
        if ($httpCode == 200 && isset($result['errcode']) && $result['errcode'] == 0) {
            return true; // 发送成功
        } else {
            return "发送失败: " . $response;
        }
    }
    // --- 使用示例 ---
    $webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key";
    // 构建告警内容(Markdown格式,带颜色和醒目提示)
    $alertContent = "## ⚠️ 线上告警通知\n" .
                    "> **项目**: 用户中心\n" .
                    "> **环境**: 生产\n" .
                    "> **时间**: " . date('Y-m-d H:i:s') . "\n" .
                    "> **级别**: <font color=\"warning\">严重</font>\n" .
                    "> **详情**: 数据库连接超时\n" .
                    "> **操作**: 请相关人员立即排查";
    $result = sendWechatGroupRobotAlert($webhookUrl, $alertContent);
    if ($result === true) {
        echo "告警发送成功";
    } else {
        echo "告警发送失败: " . $result;
    }

特点:

  • 优点:零成本(无需注册应用),配置简单,消息直接到群。
  • 缺点:只能发到固定的群,无法单独@具体人(除非在消息文本中手动写@all 或 @手机号,但需要机器人开启“@所有人”权限)。

应用消息推送(企业级,更专业)

这种方式使用企业微信的自建应用,可以向指定成员、部门或标签发送告警消息,且支持“应用内点击跳转”等交互。

步骤:

  1. 创建自建应用

    • 登录 企业微信管理后台 -> 应用管理 -> 自建 -> 创建应用。
    • 设置应用名称、头像,并配置“可见范围”(哪些人能收到消息)。
    • 记录下应用的 AgentIdSecret
  2. 获取企业微信全局 Access Token

    • 企业微信的 API 依赖 access_token,需通过 corpid(企业ID) 和 secret 获取。
  3. PHP 代码实现

    <?php
    class WeWorkAlert {
        private $corpId;
        private $agentSecret;
        private $agentId;
        public function __construct($corpId, $agentSecret, $agentId) {
            $this->corpId = $corpId;
            $this->agentSecret = $agentSecret;
            $this->agentId = $agentId;
        }
        /**
         * 获取 access_token
         */
        private function getAccessToken() {
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$this->corpId}&corpsecret={$this->agentSecret}";
            $result = $this->httpGet($url);
            $data = json_decode($result, true);
            if ($data['errcode'] === 0) {
                return $data['access_token'];
            }
            throw new \Exception("获取 access_token 失败: " . $result);
        }
        /**
         * 发送应用消息
         *
         * @param string $content 消息内容(支持 Markdown)
         * @param string $toUser 接收成员,多个用 | 分隔,如:"user1|user2",默认 @all(需要应用有@all权限)
         * @param string $toParty 接收部门
         * @return bool
         */
        public function sendMessage($content, $toUser = "@all", $toParty = "") {
            $token = $this->getAccessToken();
            $url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={$token}";
            $data = [
                "touser" => $toUser,
                "toparty" => $toParty,
                "msgtype" => "markdown",
                "agentid" => $this->agentId,
                "markdown" => [
                    "content" => $content
                ],
                "safe" => 0
            ];
            $result = $this->httpPost($url, json_encode($data));
            $response = json_decode($result, true);
            if ($response['errcode'] === 0) {
                return true;
            }
            throw new \Exception("发送失败: " . $result);
        }
        private function httpGet($url) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 5);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $output = curl_exec($ch);
            curl_close($ch);
            return $output;
        }
        private function httpPost($url, $postData) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $output = curl_exec($ch);
            curl_close($ch);
            return $output;
        }
    }
    // --- 使用示例 ---
    $corpId = "你的企业ID (在后台“我的企业”->“企业信息”底部可找到)";
    $agentSecret = "你的应用Secret";
    $agentId = "你的应用AgentId";
    $alert = new WeWorkAlert($corpId, $agentSecret, $agentId);
    $alertContent = "## ❌ 关键服务宕机\n" .
                    "> **服务**: API Gateway\n" .
                    "> **时间**: " . date('Y-m-d H:i:s') . "\n" .
                    "> **影响**: 可能影响所有下游服务\n" .
                    "> **处理人**: 值班同学";
    try {
        // 发送给整个可见范围 (@all),也可以指定具体人 如 "张三|李四"
        $result = $alert->sendMessage($alertContent, "@all");
        if ($result) {
            echo "企业微信应用告警发送成功!";
        }
    } catch (\Exception $e) {
        echo "发送失败: " . $e->getMessage();
    }

特点:

  • 优点:可定向发送给特定人/部门,支持跳转链接,可集成到统一告警平台。
  • 缺点:需要自建应用,配置稍繁琐,且应用需要设置“网页授权”才能获取访问 token。

注意事项(重要)

  1. 消息频率限制:企业微信 API 有频率限制(例如每分钟最多20条消息),频繁发送可能会被限流。
  2. 内容格式:推荐使用 markdown 格式,但不能包含一些特殊字符(如表格),且内容最长 4096字节
  3. 错误处理:实际生产环境中,建议记录告警发送的日志,方便排查。
  4. 安全不要将 Webhook URL 或 Secret 硬编码在代码中,建议放在环境变量或配置中心。
  5. 消息类型
    • 群机器人:支持 textmarkdownnews(图文)、file 等类型。
    • 应用消息:支持 textmarkdownnewstextcard 等类型,textcard 支持点击跳转到指定链接,非常适合告警工单处理。

进阶建议

  1. 集成到框架:如果你的 PHP 项目使用了 Laravel、ThinkPHP 等框架,可以将上述代码封装成 Service 类或 Job 队列,实现异步发送,避免阻塞主流程。
    • Laravel 示例:可以使用 Queue 将告警任务推送到队列,使用 Http Facade 发送请求。
  2. 消息模板:定义一个统一的告警模板函数,传入“级别、项目、详情、时间”等参数,自动生成格式化的 Markdown 字符串。
  3. 结合监控系统:如果你的项目使用 Prometheus + Grafana,或自建监控,可以在告警触发器(Hook)中调用此 PHP 接口。

抱歉,评论功能暂时关闭!