feat: add /webhook/push-broadcast POST route for Pipeline C feishu broadcast
- Add push-broadcast handler in backend/routes/feishu-bot.js with token validation, request parsing, and Feishu IM API message delivery - Wire /webhook/push-broadcast in backend/server.js via route forwarding - Add nginx /webhook/ proxy_pass config in nginx-api-proxy.conf - Update health check to report push_broadcast feature status Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
c1677400de
commit
fec940188e
|
|
@ -22,6 +22,16 @@ location /api/ps/ {
|
|||
proxy_read_timeout 90s;
|
||||
}
|
||||
|
||||
# Webhook 路由 → 后端服务端口 3000(飞书事件回调、广播推送等)
|
||||
location /webhook/ {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Content-Type $content_type;
|
||||
}
|
||||
|
||||
# API 代理转发(通用 AI 聊天)
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:3721;
|
||||
|
|
|
|||
|
|
@ -410,6 +410,71 @@ router.post('/alert', async (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// 广播推送(Pipeline C 调用)
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* 接收 Pipeline C 的广播推送请求,转发到飞书聊天窗口
|
||||
* POST /push-broadcast (通过 server.js 映射到 /webhook/push-broadcast)
|
||||
*/
|
||||
router.post('/push-broadcast', async (req, res) => {
|
||||
// 1. 验证 token
|
||||
const token = req.headers['x-push-token'];
|
||||
if (!process.env.PUSH_BROADCAST_TOKEN || token !== process.env.PUSH_BROADCAST_TOKEN) {
|
||||
return res.status(401).json({ error: true, message: 'Invalid push token' });
|
||||
}
|
||||
|
||||
// 2. 解析请求体
|
||||
const { chat_id, sender_open_id, broadcast_title, broadcast_content, broadcast_url } = req.body;
|
||||
|
||||
if (!broadcast_content && !broadcast_title) {
|
||||
return res.status(400).json({ error: true, message: 'Missing broadcast_title or broadcast_content' });
|
||||
}
|
||||
|
||||
const receive_id = chat_id || sender_open_id;
|
||||
if (!receive_id) {
|
||||
return res.status(400).json({ error: true, message: 'Missing chat_id or sender_open_id' });
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. 获取飞书 token
|
||||
const feishuToken = await getFeishuToken();
|
||||
|
||||
// 4. 构造消息文本
|
||||
const urlLine = broadcast_url ? '\n🔗 ' + broadcast_url : '';
|
||||
const text = '📡 新广播 ' + (broadcast_title || '') + '\n\n' + (broadcast_content || '') + urlLine;
|
||||
|
||||
// 5. 发送飞书消息(优先 chat_id,备选 open_id)
|
||||
const receive_id_type = chat_id ? 'chat_id' : 'open_id';
|
||||
const msgResult = await httpsRequest({
|
||||
hostname: 'open.feishu.cn',
|
||||
port: 443,
|
||||
path: '/open-apis/im/v1/messages?receive_id_type=' + receive_id_type,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + feishuToken,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}, {
|
||||
receive_id: receive_id,
|
||||
msg_type: 'text',
|
||||
content: JSON.stringify({ text }),
|
||||
});
|
||||
|
||||
if (msgResult.data && msgResult.data.code === 0) {
|
||||
console.log('✅ 广播推送成功: ' + broadcast_title + ' → ' + receive_id);
|
||||
res.json({ success: true, message_id: msgResult.data.data && msgResult.data.data.message_id });
|
||||
} else {
|
||||
console.error('❌ 飞书发送失败:', JSON.stringify(msgResult.data));
|
||||
res.status(500).json({ error: true, message: (msgResult.data && msgResult.data.msg) || 'Feishu API error', code: msgResult.data && msgResult.data.code });
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('❌ push-broadcast error:', err.message);
|
||||
res.status(500).json({ error: true, message: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// ══════════════════════════════════════════════════════════
|
||||
// 健康检查 + 统计
|
||||
// ══════════════════════════════════════════════════════════
|
||||
|
|
@ -424,6 +489,7 @@ router.get('/health', (req, res) => {
|
|||
ai_chat: !!process.env.MODEL_API_KEY,
|
||||
collaboration_logging: true,
|
||||
failure_alerting: !!ALERT_CHAT_ID,
|
||||
push_broadcast: !!process.env.PUSH_BROADCAST_TOKEN,
|
||||
},
|
||||
github_token_configured: !!GITHUB_TOKEN,
|
||||
feishu_app_configured: !!(FEISHU_APP_ID && FEISHU_APP_SECRET),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ app.get('/', (req, res) => {
|
|||
});
|
||||
});
|
||||
|
||||
// Pipeline C 广播推送 webhook → 转发到 feishu-bot 路由
|
||||
app.post('/webhook/push-broadcast', (req, res, next) => {
|
||||
req.url = '/push-broadcast';
|
||||
feishuBotRoutes(req, res, next);
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
// 飞书 Webhook 处理(旧版兼容入口,新事件请使用 /feishu-bot/event)
|
||||
app.post('/webhook/feishu', (req, res) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue