155 lines
4.5 KiB
JavaScript
155 lines
4.5 KiB
JavaScript
// scripts/skyeye/sync-to-notion.js
|
|
// 天眼·报告同步到 Notion
|
|
//
|
|
// 将天眼全局健康报告同步到 Notion 数据库
|
|
// 如果 NOTION_TOKEN 未设置则优雅跳过
|
|
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const https = require('https');
|
|
|
|
const SKYEYE_DIR = '/tmp/skyeye';
|
|
const NOTION_TOKEN = process.env.NOTION_TOKEN;
|
|
const SYSLOG_DB_ID = process.env.NOTION_SYSLOG_DB_ID;
|
|
|
|
const NOTION_TITLE_MAX = 100;
|
|
const NOTION_CONTENT_MAX = 2000;
|
|
|
|
// ━━━ 安全读取 JSON ━━━
|
|
function readJSON(filePath) {
|
|
try {
|
|
if (!fs.existsSync(filePath)) return null;
|
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// ━━━ Notion API 调用 ━━━
|
|
function notionRequest(apiPath, body) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!NOTION_TOKEN) {
|
|
return reject(new Error('NOTION_TOKEN 未设置'));
|
|
}
|
|
|
|
const postData = JSON.stringify(body);
|
|
const options = {
|
|
hostname: 'api.notion.com',
|
|
path: apiPath,
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': 'Bearer ' + NOTION_TOKEN,
|
|
'Notion-Version': '2022-06-28',
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(postData)
|
|
},
|
|
timeout: 15000
|
|
};
|
|
|
|
const req = https.request(options, (res) => {
|
|
let data = '';
|
|
res.on('data', chunk => data += chunk);
|
|
res.on('end', () => {
|
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
resolve({ statusCode: res.statusCode, body: data });
|
|
} else {
|
|
reject(new Error(`Notion API ${res.statusCode}: ${data.length > 200 ? data.substring(0, 200) + '...' : data}`));
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on('error', reject);
|
|
req.on('timeout', () => { req.destroy(); reject(new Error('Notion API timeout')); });
|
|
req.write(postData);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
// ━━━ 格式化报告为文本 ━━━
|
|
function formatReportText(report) {
|
|
if (!report) return '天眼报告数据缺失';
|
|
|
|
const lines = [
|
|
`🦅 天眼报告 ${report.report_id}`,
|
|
`整体健康: ${report.overall_health}`,
|
|
`时间: ${report.timestamp}`,
|
|
'',
|
|
`🧠 核心大脑: ${report.brain_status.integrity}`,
|
|
`📋 Workflow: ${report.workflow_health.healthy}/${report.workflow_health.total} 健康`,
|
|
`📂 仓库结构: ${report.structure_health.core_dirs_ok ? '✅' : '❌'}`,
|
|
`🌉 外部桥接: Notion=${report.bridge_health.notion_api} GitHub=${report.bridge_health.github_api}`,
|
|
'',
|
|
`🔬 诊断: ${report.diagnosis.total_issues} 个问题`,
|
|
` 自动修复: ${report.diagnosis.auto_fixed}`,
|
|
` 需人工: ${report.diagnosis.needs_human}`,
|
|
` 观察中: ${report.diagnosis.watching}`
|
|
];
|
|
|
|
if (report.repairs_applied.length > 0) {
|
|
lines.push('', '🔧 已执行修复:');
|
|
for (const r of report.repairs_applied) {
|
|
lines.push(` • ${r}`);
|
|
}
|
|
}
|
|
|
|
if (report.tickets_created.length > 0) {
|
|
lines.push('', '📨 生成工单:');
|
|
for (const t of report.tickets_created) {
|
|
lines.push(` • ${t}`);
|
|
}
|
|
}
|
|
|
|
return lines.join('\n').substring(0, NOTION_CONTENT_MAX);
|
|
}
|
|
|
|
// ━━━ 主同步流程 ━━━
|
|
async function syncToNotion() {
|
|
console.log('📡 天眼·Notion 同步启动');
|
|
|
|
if (!NOTION_TOKEN) {
|
|
console.log('⚠️ NOTION_TOKEN 未设置,跳过 Notion 同步');
|
|
return;
|
|
}
|
|
|
|
if (!SYSLOG_DB_ID) {
|
|
console.log('⚠️ NOTION_SYSLOG_DB_ID 未设置,跳过 Notion 同步');
|
|
return;
|
|
}
|
|
|
|
const report = readJSON(path.join(SKYEYE_DIR, 'full-report.json'));
|
|
if (!report) {
|
|
console.log('⚠️ 天眼报告不存在,跳过 Notion 同步');
|
|
return;
|
|
}
|
|
|
|
const title = `🦅 天眼报告 ${report.report_id} · ${report.overall_health}`;
|
|
const content = formatReportText(report);
|
|
|
|
try {
|
|
await notionRequest('/v1/pages', {
|
|
parent: { database_id: SYSLOG_DB_ID },
|
|
properties: {
|
|
'标题': {
|
|
title: [{ type: 'text', text: { content: title.substring(0, NOTION_TITLE_MAX) } }]
|
|
},
|
|
'接收时间': { date: { start: new Date().toISOString() } },
|
|
'推送方': {
|
|
rich_text: [{ type: 'text', text: { content: '天眼系统' } }]
|
|
},
|
|
'文件内容': {
|
|
rich_text: [{ type: 'text', text: { content } }]
|
|
}
|
|
}
|
|
});
|
|
|
|
console.log('✅ 天眼报告已同步到 Notion');
|
|
} catch (e) {
|
|
console.error('⚠️ Notion 同步失败:', e.message);
|
|
// 不阻断流程
|
|
}
|
|
}
|
|
|
|
syncToNotion();
|