飞书webhook发消息无需access_token,直接用含uuid的webhook url即可;需严格遵循json格式、content-type头及msg_type/content结构,优先用curl验证链路,并确认机器人已入群且权限正常。

直接用 Webhook 最快,但别硬塞 access_token
飞书机器人发消息,最简单的方式就是 Webhook,根本不需要调用 auth/v3/tenant_access_token/internal 拿 access_token。你看到的那些带 Authorization: Bearer xxx 的示例,其实是误用了「自建应用」的调用方式——Webhook 机器人压根不走鉴权头,它靠的是 URL 里的密钥。
- Webhook 地址形如
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,后半段 UUID 就是凭证,泄露等于机器人失控 - 如果在代码里写死
Authorization头并填了错误的 token,会返回400 Bad Request或401 Unauthorized,但错误信息里不会明说“你用错鉴权方式了” - PHP 用
curl或GuzzleHttp\Client都行,关键要确保Content-Type: application/json,且请求体是合法 JSON(注意中文编码、引号转义)
msg_type 和 content 结构必须严格匹配文档
飞书对消息格式非常敏感,msg_type 写成 "text" 却把内容塞进 text 字段外的键里,或者漏掉 content 这层包装,都会导致 400 并返回模糊提示 "invalid parameter"。
- 纯文本:必须是
{"msg_type":"text","content":{"text":"hello"}},不是{"text":"hello"} - 富文本(如加粗、链接)要用
post类型,结构完全不同:{"msg_type":"post","content":{"post":{"zh_cn":{"title":"告警","content":[[{"tag":"text","text":"CPU > 95%"}]]}}}} - PHP 中用
json_encode()时务必加JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,否则中文变 \uXXXX,飞书可能渲染为空或报错
本地调试 curl 成功率比 PHP 脚本高,先验证再集成
很多问题其实和 PHP 无关,而是网络、URL、JSON 格式导致的。别急着改代码,先用命令行确认基础链路通不通。
- 终端执行:
curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/你的webhook-id" -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"test from curl"}}' - 如果返回
{"status_code":0,"status_msg":"success"},说明 URL 和格式没问题;如果返回空、超时或 HTML 页面,大概率是 URL 错、被防火墙拦截、或本地没开代理(企业内网常见) - PHP 里用
curl_error($ch)或 Guzzle 的$response->getBody()->getContents()打印原始响应,比只看状态码更有用
别忽略机器人权限和群组状态
Webhook 发送成功 ≠ 消息一定出现在群里。飞书后台有两处静默关卡:
- 机器人必须已被手动添加到目标群聊中——仅配置 Webhook 地址不生效,这步无法 API 完成
- 群聊若被设置为“仅允许指定成员@机器人”,而消息里没带
@_user_id,则消息会被丢弃且无任何错误反馈 - 企业管理员可能关闭了“允许机器人发送消息”策略,此时所有 Webhook 请求都返回
403 Forbidden,但响应体为空,容易误判为网络问题
真正麻烦的从来不是怎么写那几行 PHP,而是飞书后台那个没点进去看的「群管理设置」和「安全策略中心」。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











