feat: expand traffic alerts to discord/telegram
Some checks failed
Deploy to 110 WOOO Server / deploy (push) Failing after 7s

This commit is contained in:
OG T
2026-06-07 16:23:22 +08:00
parent 309b5aa1ec
commit 54608a3376
2 changed files with 86 additions and 14 deletions

View File

@@ -25,6 +25,11 @@ API_KEY="your-secure-mcp-key"
GITHUB_TOKEN="github_pat_..."
# 監控告警:外部導流/外部操作事件 webhook可留空
VIBEWORK_TRAFFIC_WEBHOOK_URL="https://your-webhook"
# 直接推送到 Discord可留空
DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/xxx"
# Telegram 告警(可留空)
TELEGRAM_BOT_TOKEN="123456:abcdef"
TELEGRAM_CHAT_ID="-1001234567890"
# optional只允許有 token 的 /api/traffic 查詢
TRAFFIC_MONITOR_TOKEN="your-monitor-token"
# optionalScout 掃描參數

View File

@@ -13,6 +13,29 @@ export type TrafficAlertEvent = {
};
const TRAFFIC_WEBHOOK_URL = process.env.VIBEWORK_TRAFFIC_WEBHOOK_URL?.trim();
const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN?.trim();
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID?.trim();
const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL?.trim();
function escapeMarkdown(value: unknown) {
if (value === null || value === undefined) return "";
return String(value)
.replace(/([_*[\]()~`>#+=|{}.!-])/g, "\\$1")
.replace(/\n/g, "\\n");
}
function buildTelegramMessage(event: TrafficAlertEvent) {
return (
`*VibeWork 流量告警*` +
`\n- 平台: \`agent-bounty-protocol\`` +
`\n- 等級: \`${event.level}\`` +
`\n- 行為: \`${event.action}\`` +
`\n- 通道: \`${event.surface}\`` +
`\n- Actor: \`${event.actorType}/${event.actorId}\`` +
`\n- 任務: \`${event.taskId || "n/a"}\`` +
`\n- 訊息: ${escapeMarkdown(event.message)}`
);
}
function resolveEntityFromTrafficEvent(event: TrafficAlertEvent) {
if (event.taskId) {
@@ -55,25 +78,69 @@ async function writeTrafficAuditEvent(event: TrafficAlertEvent) {
export async function sendTrafficAlert(event: TrafficAlertEvent): Promise<void> {
void writeTrafficAuditEvent(event);
if (!TRAFFIC_WEBHOOK_URL) return;
const payload = {
platform: "agent-bounty-protocol",
created_at: new Date().toISOString(),
...event,
};
try {
await fetch(TRAFFIC_WEBHOOK_URL, {
method: "POST",
headers: {
"content-type": "application/json",
"x-trace-source": "agent-bounty-protocol",
const notifyTargets = [
TRAFFIC_WEBHOOK_URL && {
kind: "generic",
url: TRAFFIC_WEBHOOK_URL,
init: {
method: "POST",
headers: {
"content-type": "application/json",
"x-trace-source": "agent-bounty-protocol",
},
body: JSON.stringify(payload),
},
body: JSON.stringify(payload),
signal: AbortSignal.timeout(3000),
});
} catch {
// Avoid affecting request flow if webhook fails.
}
},
DISCORD_WEBHOOK_URL && {
kind: "discord",
url: DISCORD_WEBHOOK_URL,
init: {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
content: `\`\`\`\n${JSON.stringify(payload, null, 2)}\n\`\`\``,
}),
},
},
TELEGRAM_BOT_TOKEN && TELEGRAM_CHAT_ID && {
kind: "telegram",
url: `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`,
init: {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: buildTelegramMessage(event),
parse_mode: "MarkdownV2",
}),
},
},
].filter(Boolean) as Array<{ kind: string; url: string; init: RequestInit }>;
if (notifyTargets.length === 0) return;
await Promise.allSettled(
notifyTargets.map(async (target) => {
try {
const response = await fetch(target.url, { ...target.init, signal: AbortSignal.timeout(3000) });
if (!response.ok) {
console.warn(
`[Traffic alert notify failed] ${target.kind} ${response.status} ${await response.text()}`
);
}
} catch (error) {
console.warn(`[Traffic alert notify failed] ${target.kind}`, error);
}
})
);
}