refactor: extract shared feishu alert script + fix error messages + code review fixes
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
d0cc67953b
commit
9fb8197042
|
|
@ -52,32 +52,7 @@ jobs:
|
|||
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
|
||||
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}
|
||||
ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }}
|
||||
run: |
|
||||
if [ -z "$ALERT_CHAT_ID" ]; then
|
||||
echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过群通知"
|
||||
exit 0
|
||||
fi
|
||||
node -e "
|
||||
const https = require('https');
|
||||
function post(url, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payload = JSON.stringify(body);
|
||||
const u = new URL(url);
|
||||
const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }
|
||||
}, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); });
|
||||
req.on('error', reject); req.write(payload); req.end();
|
||||
});
|
||||
}
|
||||
(async () => {
|
||||
const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
|
||||
{ app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET }));
|
||||
const token = tokenRes.tenant_access_token;
|
||||
const payload = JSON.stringify({ text: '📡 新广播已推送到飞书文档B\n\n时间: ' + new Date().toISOString() + '\n请查看飞书广播收件箱。' });
|
||||
await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
|
||||
JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload }));
|
||||
})().catch(e => console.error(e.message));
|
||||
"
|
||||
run: node scripts/send-feishu-alert.js "push-broadcast" "📡 新广播已推送到飞书文档B,请查看飞书广播收件箱。" || true
|
||||
|
||||
- name: 🔴 失败告警 → 飞书通知
|
||||
if: failure()
|
||||
|
|
@ -85,29 +60,4 @@ jobs:
|
|||
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
|
||||
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}
|
||||
ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }}
|
||||
run: |
|
||||
if [ -z "$ALERT_CHAT_ID" ]; then
|
||||
echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过告警"
|
||||
exit 0
|
||||
fi
|
||||
node -e "
|
||||
const https = require('https');
|
||||
function post(url, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payload = JSON.stringify(body);
|
||||
const u = new URL(url);
|
||||
const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }
|
||||
}, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); });
|
||||
req.on('error', reject); req.write(payload); req.end();
|
||||
});
|
||||
}
|
||||
(async () => {
|
||||
const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
|
||||
{ app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET }));
|
||||
const token = tokenRes.tenant_access_token;
|
||||
const payload = JSON.stringify({ text: '🔴 GitHub Action 失败告警\n\n工作流: push-broadcast\n时间: ' + new Date().toISOString() + '\n请检查 GitHub Actions 日志。' });
|
||||
await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
|
||||
JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload }));
|
||||
})().catch(e => console.error(e.message));
|
||||
"
|
||||
run: node scripts/send-feishu-alert.js "push-broadcast"
|
||||
|
|
|
|||
|
|
@ -58,29 +58,4 @@ jobs:
|
|||
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
|
||||
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}
|
||||
ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }}
|
||||
run: |
|
||||
if [ -z "$ALERT_CHAT_ID" ]; then
|
||||
echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过告警"
|
||||
exit 0
|
||||
fi
|
||||
node -e "
|
||||
const https = require('https');
|
||||
function post(url, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payload = JSON.stringify(body);
|
||||
const u = new URL(url);
|
||||
const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }
|
||||
}, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); });
|
||||
req.on('error', reject); req.write(payload); req.end();
|
||||
});
|
||||
}
|
||||
(async () => {
|
||||
const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
|
||||
{ app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET }));
|
||||
const token = tokenRes.tenant_access_token;
|
||||
const payload = JSON.stringify({ text: '🔴 GitHub Action 失败告警\n\n工作流: receive-syslog\n时间: ' + new Date().toISOString() + '\n请检查 GitHub Actions 日志。' });
|
||||
await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
|
||||
JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload }));
|
||||
})().catch(e => console.error(e.message));
|
||||
"
|
||||
run: node scripts/send-feishu-alert.js "receive-syslog"
|
||||
|
|
|
|||
|
|
@ -46,29 +46,4 @@ jobs:
|
|||
FEISHU_APP_ID: ${{ secrets.FEISHU_APP_ID }}
|
||||
FEISHU_APP_SECRET: ${{ secrets.FEISHU_APP_SECRET }}
|
||||
ALERT_CHAT_ID: ${{ secrets.FEISHU_ALERT_CHAT_ID }}
|
||||
run: |
|
||||
if [ -z "$ALERT_CHAT_ID" ]; then
|
||||
echo "⚠️ 未配置 FEISHU_ALERT_CHAT_ID,跳过告警"
|
||||
exit 0
|
||||
fi
|
||||
node -e "
|
||||
const https = require('https');
|
||||
function post(url, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payload = JSON.stringify(body);
|
||||
const u = new URL(url);
|
||||
const req = https.request({ hostname: u.hostname, port: 443, path: u.pathname, method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) }
|
||||
}, res => { let d=''; res.on('data', c => d+=c); res.on('end', () => resolve(d)); });
|
||||
req.on('error', reject); req.write(payload); req.end();
|
||||
});
|
||||
}
|
||||
(async () => {
|
||||
const tokenRes = JSON.parse(await post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
|
||||
{ app_id: process.env.FEISHU_APP_ID, app_secret: process.env.FEISHU_APP_SECRET }));
|
||||
const token = tokenRes.tenant_access_token;
|
||||
const payload = JSON.stringify({ text: '🔴 GitHub Action 失败告警\n\n工作流: sync-login-entry\n时间: ' + new Date().toISOString() + '\n请检查 GitHub Actions 日志。' });
|
||||
await post('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
|
||||
JSON.stringify({ receive_id: process.env.ALERT_CHAT_ID, msg_type: 'text', content: payload }));
|
||||
})().catch(e => console.error(e.message));
|
||||
"
|
||||
run: node scripts/send-feishu-alert.js "sync-login-entry"
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ async function callModel(messages, options = {}) {
|
|||
const model = options.model || process.env.MODEL_NAME || DEFAULT_MODEL;
|
||||
|
||||
if (!apiKey) {
|
||||
return '⚠️ AI 模型未配置(缺少 MODEL_API_KEY),请联系管理员。';
|
||||
return '⚠️ AI 服务暂时不可用,请联系管理员。';
|
||||
}
|
||||
|
||||
const url = new URL(apiBase + '/chat/completions');
|
||||
|
|
@ -163,10 +163,10 @@ async function callModel(messages, options = {}) {
|
|||
|
||||
// 尝试降级模型
|
||||
if (result.statusCode === 429 || result.statusCode >= 500) {
|
||||
return '⚠️ AI 模型暂时不可用(HTTP ' + result.statusCode + '),请稍后重试。';
|
||||
return '⚠️ AI 模型暂时不可用,请稍后重试。';
|
||||
}
|
||||
|
||||
return '⚠️ AI 模型调用异常: ' + (result.data.error?.message || JSON.stringify(result.data));
|
||||
return '⚠️ AI 模型调用异常,请稍后重试或联系管理员。';
|
||||
} catch (e) {
|
||||
return '⚠️ AI 模型调用失败: ' + e.message;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,9 @@ function main() {
|
|||
d.total_interactions++;
|
||||
if (r.type === 'syslog_collaboration') d.syslog_count++;
|
||||
if (r.type === 'collaboration') d.chat_count++;
|
||||
d.last_active_at = r.timestamp;
|
||||
if (!d.last_active_at || r.timestamp > d.last_active_at) {
|
||||
d.last_active_at = r.timestamp;
|
||||
}
|
||||
if (r.channel) d.channels_used.add(r.channel);
|
||||
if (r.broadcast_id && r.broadcast_id !== 'UNKNOWN') d.broadcasts_referenced.add(r.broadcast_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
// scripts/send-feishu-alert.js
|
||||
// 铸渊 · 飞书告警通知脚本(供 GitHub Actions 工作流调用)
|
||||
//
|
||||
// 用法: node scripts/send-feishu-alert.js "工作流名称" "告警内容"
|
||||
//
|
||||
// 环境变量:
|
||||
// FEISHU_APP_ID 飞书应用 App ID
|
||||
// FEISHU_APP_SECRET 飞书应用 App Secret
|
||||
// ALERT_CHAT_ID 飞书群 chat_id
|
||||
|
||||
'use strict';
|
||||
|
||||
const https = require('https');
|
||||
|
||||
function httpsPost(url, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const payload = JSON.stringify(body);
|
||||
const u = new URL(url);
|
||||
const req = https.request({
|
||||
hostname: u.hostname,
|
||||
port: 443,
|
||||
path: u.pathname + u.search,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(payload),
|
||||
},
|
||||
}, res => {
|
||||
let d = '';
|
||||
res.on('data', c => d += c);
|
||||
res.on('end', () => resolve(d));
|
||||
});
|
||||
req.on('error', reject);
|
||||
req.write(payload);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const appId = process.env.FEISHU_APP_ID;
|
||||
const appSecret = process.env.FEISHU_APP_SECRET;
|
||||
const chatId = process.env.ALERT_CHAT_ID;
|
||||
const workflow = process.argv[2] || 'unknown';
|
||||
const detail = process.argv[3] || '';
|
||||
|
||||
if (!chatId) {
|
||||
console.log('⚠️ 未配置 ALERT_CHAT_ID,跳过告警');
|
||||
process.exit(0);
|
||||
}
|
||||
if (!appId || !appSecret) {
|
||||
console.log('⚠️ 未配置飞书 App 凭据,跳过告警');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// 获取飞书 token
|
||||
const tokenRes = JSON.parse(await httpsPost(
|
||||
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
|
||||
{ app_id: appId, app_secret: appSecret }
|
||||
));
|
||||
const token = tokenRes.tenant_access_token;
|
||||
if (!token) {
|
||||
console.error('❌ 获取飞书 token 失败');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
const text = '🔴 GitHub Action 失败告警\n\n' +
|
||||
'工作流: ' + workflow + '\n' +
|
||||
'时间: ' + new Date().toISOString() + '\n' +
|
||||
(detail ? '详情: ' + detail + '\n' : '') +
|
||||
'请检查 GitHub Actions 日志。';
|
||||
|
||||
await httpsPost(
|
||||
'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id',
|
||||
{
|
||||
receive_id: chatId,
|
||||
msg_type: 'text',
|
||||
content: JSON.stringify({ text }),
|
||||
}
|
||||
);
|
||||
|
||||
console.log('✅ 告警已发送到飞书群');
|
||||
}
|
||||
|
||||
main().catch(e => {
|
||||
console.error('❌ 告警发送失败:', e.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Reference in New Issue