hughcube / laravel-lark
Lark (Feishu) custom robot/webhook notifications for Laravel & Lumen.
Requires
- php: 8.*
- ext-json: *
- ext-mbstring: *
- guzzlehttp/guzzle: *
- hughcube/laravel-service-support: ^1.0
- monolog/monolog: *
Requires (Dev)
This package is auto-updated.
Last update: 2026-05-19 05:06:17 UTC
README
在 Laravel / Lumen 中向飞书(Lark)自定义机器人 webhook
发送消息。支持签名校验,并覆盖自定义机器人全部消息类型:text、post、
image、interactive、share_chat。
安装
$ composer require hughcube/laravel-lark -vvv
ServiceProvider 与 Lark 门面会被自动发现。如需自定义配置,发布配置文件:
$ php artisan vendor:publish --tag=lark-config
配置
return [ 'defaults' => [ 'http' => [ 'timeout' => 10.0, 'connect_timeout' => 10.0, ], ], 'robots' => [ 'default' => [ 'enabled' => env('LARK_ROBOT_ENABLED', true), // 完整的 webhook 地址,或仅 hook token(二选一即可)。 'webhook' => env('LARK_ROBOT_WEBHOOK', ''), 'token' => env('LARK_ROBOT_TOKEN', ''), // 机器人安全设置里的签名密钥(可选)。 'secret' => env('LARK_ROBOT_SECRET', ''), ], ], ];
在 .env 中设置:
LARK_ROBOT_WEBHOOK=https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx LARK_ROBOT_SECRET=your-signing-secret
用法
use HughCube\Laravel\Lark\Lark; use HughCube\Laravel\Lark\Robot\Messages\Text; use HughCube\Laravel\Lark\Robot\Messages\Post; use HughCube\Laravel\Lark\Robot\Messages\Image; use HughCube\Laravel\Lark\Robot\Messages\Interactive; use HughCube\Laravel\Lark\Robot\Messages\ShareChat; // 纯文本(便捷方法) Lark::robot()->text('hello from laravel-lark'); // 带 @ 提及、多行的文本 Lark::robot()->send( Text::make() ->line('Deploy finished ✅') ->atAll() ->at('ou_xxxxxxxx', 'Tom') ->atEmail('dev@example.com') ); // 富文本(post) Lark::robot()->send( Post::make('Release v1.0.0') ->line('All checks passed.') ->link('changelog', 'https://example.com/changelog') ); // 消息卡片 Lark::robot()->send( Interactive::card('Build report', [])->markdown('**status:** success') ); // 图片 / 分享群名片(image_key 与 chat_id 通过飞书开放接口获取) Lark::robot()->send(new Image('img_xxxxxxxx')); Lark::robot()->send(new ShareChat('oc_xxxxxxxx')); // 使用 `robots` 配置里的某个具名机器人 Lark::robot('alerts')->text('disk almost full');
签名
配置了 secret 时,客户端会按飞书自定义机器人的要求对每个请求签名:
sign = base64( HMAC-SHA256( key = "{timestamp}\n{secret}", data = "" ) )
timestamp 为当前 Unix 时间戳(单位:秒);timestamp 与 sign 都放在
请求体中发送。
日志通道
用 HughCube\Laravel\Lark\Log\Handler 把 Monolog 日志推送给机器人:
// config/logging.php 'channels' => [ 'lark' => [ 'driver' => 'monolog', 'handler' => HughCube\Laravel\Lark\Log\Handler::class, // 'card' => true(默认)发送按级别上色的卡片; // 设为 false 则始终发送纯文本。 'with' => ['robot' => 'default', 'enabled' => true, 'card' => true], 'level' => 'warning', ], ],
消息体积上限
飞书的报错文案写的是 “30KB”,但自定义机器人实际能接受大得多的内容——
而且 text 与 interactive 卡片的上限完全一致。tests/MaxLengthTest.php
对真实 webhook 二分查找出 text 的真实边界;卡片边界用同样方式探测。实测:
| 消息类型 | 最后接受 | 首次拒绝 | 有效上限 |
|---|---|---|---|
| text | 153,323 字节 | 153,518 字节 | ≈ 150 KiB |
| interactive 卡片 | 152,968 字节 | 153,241 字节 | ≈ 150 KiB |
超过边界后接口返回 error 19036 — The message exceeds the size limit of 30KB
(文案里的 “30KB” 是虚的;真实上限约 ~150 KiB,≈ 153,600 = 150 × 1024)。
随包提供的 Log\Handler 默认发送按级别上色的交互卡片(正文用
plain_text,日志内容绝不会被当作 markdown 再次解析),并以 UTF-8 安全方式
截断到 120000 字节——在边界之下留足余量,JSON 外壳绝不会把它顶超,且中文
绝不会被从半个字符处切断。飞书会自动折叠超长内容,所以长卡片依然好读;万一
飞书拒绝了该卡片,会自动回退为纯 Text 消息。在通道 with 中传
['card' => false] 可始终发送纯文本。
自定义机器人还有频控(约 5 次/秒,约 100 次/分钟,按机器人计)。
测试
单元测试在任何环境都能跑。实时用例(@group live)仅在配置了 webhook 时运行,
否则自动跳过:
export LARK_ROBOT_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/xxxx" export LARK_ROBOT_SECRET="xxxx" composer test # 全部 vendor/bin/phpunit --exclude-group live # 仅单元测试
CI 中 webhook 通过 LARK_WEBHOOK / LARK_SECRET 两个 GitHub Actions secret
提供,且实时用例被限定在矩阵的单个单元格上运行,以遵守机器人频控。
许可
MIT