PHP 怎么飞书通知

wen PHP项目 2

本文目录导读:

PHP 怎么飞书通知

  1. 方式一:自定义机器人 Webhook(最简单)
  2. 方式二:带签名的安全增强版(推荐)
  3. 方式三:使用应用机器人(适合复杂场景)
  4. 方式四:使用官方 SDK(推荐生产环境)
  5. 完整封装类(推荐直接使用)
  6. 常见问题解决
  7. 推荐使用场景

在 PHP 中实现飞书通知,主要有以下几种方式,我会按照从简单到复杂的顺序给你介绍:

自定义机器人 Webhook(最简单)

这是最常用的方式,不需要审核,5分钟就能搞定。

创建机器人

  • 在飞书群中,点击 设置 -> 群机器人 -> 添加机器人 -> 自定义机器人
  • 复制生成的 Webhook 地址(格式类似 https://open.feishu.cn/open-apis/bot/v2/hook/xxxx

PHP 代码实现

<?php
class FeishuNotifier {
    private $webhookUrl;
    public function __construct($webhookUrl) {
        $this->webhookUrl = $webhookUrl;
    }
    /**
     * 发送文本消息
     */
    public function sendText($content) {
        $data = [
            'msg_type' => 'text',
            'content' => [
                'text' => $content
            ]
        ];
        return $this->send($data);
    }
    /**
     * 发送富文本/卡片消息
     */
    public function sendCard($title, $content) {
        $data = [
            'msg_type' => 'interactive',
            'card' => [
                'header' => [
                    'title' => [
                        'tag' => 'plain_text',
                        'content' => $title
                    ],
                    'template' => 'blue'  // 颜色:blue/green/red/orange
                ],
                'elements' => [
                    [
                        'tag' => 'div',
                        'text' => [
                            'tag' => 'lark_md',
                            'content' => $content
                        ]
                    ]
                ]
            ]
        ];
        return $this->send($data);
    }
    /**
     * 发送消息(带签名验证)
     */
    private function send($data) {
        $payload = json_encode($data, JSON_UNESCAPED_UNICODE);
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->webhookUrl,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json; charset=utf-8'
            ],
            CURLOPT_TIMEOUT => 10
        ]);
        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if ($error) {
            return ['success' => false, 'error' => $error];
        }
        return json_decode($response, true);
    }
}
// 使用示例
$webhookUrl = 'https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_WEBHOOK_URL';
$notifier = new FeishuNotifier($webhookUrl);
// 发送普通文本
$result = $notifier->sendText('Hello PHP! 这是一条测试消息');
// 发送富文本卡片
$result = $notifier->sendCard(
    '系统通知 📢',
    '**重要更新**:\n服务器将于今晚 22:00 进行维护'
);
var_dump($result);

带签名的安全增强版(推荐)

如果你的机器人开启了签名验证,需要加上签名逻辑:

<?php
class FeishuSecureNotifier {
    private $webhookUrl;
    private $secret;  // 机器人的签名密钥
    public function __construct($webhookUrl, $secret) {
        $this->webhookUrl = $webhookUrl;
        $this->secret = $secret;
    }
    /**
     * 生成时间戳和签名
     */
    private function generateSign() {
        $timestamp = time();
        // 拼接签名字符串
        $stringToSign = $timestamp . "\n" . $this->secret;
        // 计算签名(注意:需要与飞书文档一致)
        $sign = base64_encode(hash_hmac('sha256', $stringToSign, '', true));
        return [
            'timestamp' => $timestamp,
            'sign' => $sign
        ];
    }
    public function sendText($content) {
        $sign = $this->generateSign();
        $data = [
            'timestamp' => $sign['timestamp'],  // 签名必须放这里
            'sign' => $sign['sign'],           // 签名必须放这里
            'msg_type' => 'text',
            'content' => [
                'text' => $content
            ]
        ];
        // 发送逻辑同上...
    }
}

使用应用机器人(适合复杂场景)

如果需要更丰富的功能(发送文件、@指定人、获取用户信息等),需要创建应用:

<?php
class FeishuAppNotifier {
    private $appId;
    private $appSecret;
    private $tenantAccessToken;
    public function __construct($appId, $appSecret) {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
        $this->getToken();
    }
    /**
     * 获取 tenant_access_token
     */
    private function getToken() {
        $url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal';
        $data = [
            'app_id' => $this->appId,
            'app_secret' => $this->appSecret
        ];
        $response = $this->request($url, $data);
        if (isset($response['tenant_access_token'])) {
            $this->tenantAccessToken = $response['tenant_access_token'];
        }
    }
    /**
     * 发送消息给用户
     */
    public function sendMessageToUser($openId, $content) {
        $url = 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id';
        $data = [
            'receive_id' => $openId,
            'msg_type' => 'text',
            'content' => json_encode([
                'text' => $content
            ])
        ];
        return $this->request($url, $data, true);
    }
    /**
     * 发送消息到群组
     */
    public function sendMessageToChat($chatId, $content) {
        $url = 'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id';
        $data = [
            'receive_id' => $chatId,
            'msg_type' => 'text',
            'content' => json_encode([
                'text' => $content
            ])
        ];
        return $this->request($url, $data, true);
    }
    /**
     * HTTP 请求封装
     */
    private function request($url, $data, $needToken = false) {
        $headers = ['Content-Type: application/json'];
        if ($needToken && $this->tenantAccessToken) {
            $headers[] = 'Authorization: Bearer ' . $this->tenantAccessToken;
        }
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_TIMEOUT => 15
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}
// 使用示例
$notifier = new FeishuAppNotifier('your_app_id', 'your_app_secret');
// 发送给用户(需要用户 open_id)
$notifier->sendMessageToUser('ou_123456', '你好,这是一条通知!');
// 发送到群组(需要群组 chat_id)
$notifier->sendMessageToChat('oc_123456', '群组通知:系统更新完成');

使用官方 SDK(推荐生产环境)

<?php
// 使用 Composer 安装官方 SDK:composer require larksuite/oapi-sdk
use Lark\Client;
use Lark\Api\Im\V1;
$client = (new Client('your_app_id', 'your_app_secret'))
    ->setHttpClient(new \GuzzleHttp\Client());
// 发送文本消息
$response = $client->im()->v1()->message()
    ->send([
        'receive_id_type' => 'open_id',
        'receive_id' => 'ou_123456',
        'msg_type' => 'text',
        'content' => json_encode(['text' => 'Hello from PHP!'])
    ]);
// 处理响应
if ($response->isOk()) {
    echo "发送成功";
}

完整封装类(推荐直接使用)

这里给你一个可直接使用的基础封装:

<?php
/**
 * 飞书通知工具类
 */
class FeishuNotifier {
    private static $instance = null;
    private $webhookUrl;
    private $secret = null;
    private function __construct($webhookUrl, $secret = null) {
        $this->webhookUrl = $webhookUrl;
        $this->secret = $secret;
    }
    /**
     * 获取单例实例
     */
    public static function getInstance($webhookUrl, $secret = null) {
        if (self::$instance === null) {
            self::$instance = new self($webhookUrl, $secret);
        }
        return self::$instance;
    }
    /**
     * 发送文本消息
     */
    public function sendText($content) {
        $msg = [
            'msg_type' => 'text',
            'content' => ['text' => $content]
        ];
        return $this->execute($msg);
    }
    /**
     * 发送 Markdown 消息
     */
    public function sendMarkdown($title, $markdownContent) {
        $msg = [
            'msg_type' => 'interactive',
            'card' => [
                'header' => [
                    'title' => [
                        'tag' => 'plain_text',
                        'content' => $title
                    ],
                    'template' => 'blue'
                ],
                'elements' => [
                    [
                        'tag' => 'div',
                        'text' => [
                            'tag' => 'lark_md',
                            'content' => $markdownContent
                        ]
                    ]
                ]
            ]
        ];
        return $this->execute($msg);
    }
    /**
     * 发送图片消息
     */
    public function sendImage($imageKey) {
        $msg = [
            'msg_type' => 'image',
            'content' => ['image_key' => $imageKey]
        ];
        return $this->execute($msg);
    }
    /**
     * 执行发送
     */
    private function execute($data) {
        // 签名处理
        if ($this->secret) {
            $timestamp = time();
            $sign = base64_encode(hash_hmac(
                'sha256', 
                $timestamp . "\n" . $this->secret, 
                '', 
                true
            ));
            $data['timestamp'] = $timestamp;
            $data['sign'] = $sign;
        }
        $result = $this->postJson($this->webhookUrl, $data);
        if ($result['code'] === 0) {
            return ['success' => true, 'data' => $result];
        }
        return ['success' => false, 'error' => $result['msg'] ?? 'unknown error'];
    }
    /**
     * POST JSON 请求
     */
    private function postJson($url, $data) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json; charset=utf-8'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        $response = curl_exec($ch);
        curl_close($ch);
        return json_decode($response, true);
    }
}
// 使用方式(简洁版)
$webhook = 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxx';
$secret = 'your_secret_if_enabled';
$notifier = FeishuNotifier::getInstance($webhook, $secret);
// 发送普通文本
$notifier->sendText('服务器部署完成 ✅');
// 发送 Markdown 格式
$notifier->sendMarkdown(
    '🎉 发布通知', 
    "**版本:** v1.2.3\n**状态:** 发布成功\n**环境:** 生产环境"
);

常见问题解决

报错 "invalid sign"

  • 检查签名算法是否与飞书官方文档一致
  • 确认时间戳是否为服务器当前时间

消息发送成功但没收到

  • 检查机器人是否被群主禁言
  • 确认消息格式是否正确(尤其是 JSON 编码)

中文乱码

  • 确保使用 json_encode($data, JSON_UNESCAPED_UNICODE)
  • 确认 Content-Type 包含 charset=utf-8

超时问题

  • 增加 CURLOPT_TIMEOUT
  • 使用异步方式发送(如队列)

推荐使用场景

  • 系统监控通知:服务器宕机、CPU 过高时推送
  • 业务告警:订单异常、支付失败等
  • CI/CD 通知:构建成功/失败推送
  • 定时任务提醒:定时执行的业务需要关注时

选择建议:

  • 简单通知 → 用自定义机器人 Webhook
  • 需要安全性 → 用签名版
  • 复杂功能 → 用飞书应用 + 官方 SDK

有问题随时问我!

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