Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
6.0 KiB
6.0 KiB
belongs_to
| belongs_to | |
|---|---|
|
🔧 铸渊+舒舒指令|修复 Pipeline C 飞书广播推送 · 新增 /push-broadcast 路由(2026-03-15·霜砚签发)
一、错误日志(原文)
📢 推送广播到飞书...
标题: BC-M23-003-AW
目标: ou_3bd223b67374fd102edd4223244a7542
HTTP 响应: 405
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>
❌ 推送失败 (HTTP 405)
二、问题分析
Pipeline C 的 push-broadcast-feishu.sh(或类似脚本)向服务器发送 POST 请求推送广播,但:
- nginx 没有配置该路由的 proxy_pass,直接返回 405
- 舒舒(gateway-server.js) 没有
/push-broadcast路由来接收和处理广播推送 - 即使有路由,还需要舒舒调用飞书发消息 API 把广播内容发给目标用户
三、修复指令
3.1 舒舒:新增 /push-broadcast POST 路由
文件位置:feishu-bot/index.js(或 gateway-server.js,取决于实际结构)
// ============ 广播推送路由 ============
// Pipeline C 调用此路由,将广播推送到飞书
app.post('/push-broadcast', async (req, res) => {
try {
// 1. 验证 token
const token = req.headers['x-push-token'] || req.body.token;
if (token !== process.env.PUSH_BROADCAST_TOKEN) {
return res.status(401).json({ error: 'Invalid token' });
}
// 2. 解析请求体
const { title, content, target_open_id, chat_id } = req.body;
if (!content) {
return res.status(400).json({ error: 'Missing content' });
}
// 3. 获取飞书 tenant_access_token
const tokenRes = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
app_id: process.env.FEISHU_APP_ID,
app_secret: process.env.FEISHU_APP_SECRET
})
});
const tokenData = await tokenRes.json();
const accessToken = tokenData.tenant_access_token;
// 4. 发送飞书消息
// 优先发到群聊(chat_id),否则发给个人(target_open_id)
const receive_id_type = chat_id ? 'chat_id' : 'open_id';
const receive_id = chat_id || target_open_id;
const msgRes = await fetch(`https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=${receive_id_type}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify({
receive_id: receive_id,
msg_type: 'text',
content: JSON.stringify({ text: `📡 新广播 ${title || ''}\n\n${content}` })
})
});
const msgData = await msgRes.json();
if (msgData.code === 0) {
console.log(`✅ 广播推送成功: ${title} → ${receive_id}`);
res.json({ success: true, message_id: msgData.data?.message_id });
} else {
console.error(`❌ 飞书发送失败:`, msgData);
res.status(500).json({ error: msgData.msg, code: msgData.code });
}
} catch (err) {
console.error('❌ push-broadcast error:', err.message);
res.status(500).json({ error: err.message });
}
});
3.2 nginx:添加 proxy_pass(如果 /push-broadcast 没有被代理)
文件位置:/etc/nginx/conf.d/guanghulab.conf(或对应的 nginx 配置文件)
在 server block 中确认有如下配置:
location /push-broadcast {
proxy_pass http://127.0.0.1:3080; # 舒舒端口,按实际修改
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Content-Type $content_type;
}
如果舒舒已经有一个通配 location 代理所有 API 请求(如 location /api/),则需要确认 /push-broadcast 路径在代理范围内,或者单独加一条。
3.3 Pipeline C 脚本:确认请求格式
Pipeline C 的推送脚本应该发送如下格式的 POST 请求:
curl -X POST https://guanghulab.com/push-broadcast \
-H "Content-Type: application/json" \
-H "X-Push-Token: ${PUSH_BROADCAST_TOKEN}" \
-d '{
"title": "BC-M23-003-AW",
"content": "广播正文内容...",
"target_open_id": "ou_3bd223b67374fd102edd4223244a7542",
"chat_id": "(可选,群聊 ID)"
}'
四、环境变量确认
舒舒服务器上需要以下环境变量(.env 文件或 PM2 ecosystem):
| 变量名 | 用途 | 来源 |
|---|---|---|
FEISHU_APP_ID |
飞书应用 App ID | 飞书开放平台 → 应用凭证 |
FEISHU_APP_SECRET |
飞书应用 App Secret | 飞书开放平台 → 应用凭证 |
PUSH_BROADCAST_TOKEN |
推送鉴权 token | 与 GitHub Secret 中的 PUSH_BROADCAST_TOKEN 一致:guanghu-push-2026 |
注意:FEISHU_APP_ID 和 FEISHU_APP_SECRET 舒舒发消息时就应该已经有了(舒舒接收飞书回调时用的同一个应用)。确认这两个变量在 .env 里存在即可。
五、验收标准
- 服务器上
curl -X POST https://guanghulab.com/push-broadcast不再返回 405 - 带正确 token 和 content 的 POST 请求返回
{"success": true} - 飞书端收到广播消息
- 完整链路测试:飞书发 SYSLOG → Pipeline A/B/C 全绿 → 飞书收到新广播
六、执行确认
铸渊完成后,在本页下方追加一行:
✅ push-broadcast 路由已部署 · [日期时间] · commit SHA