#!/usr/bin/env node /** * 格式化AI新闻简报 - 飞书友好版本(含中文翻译) * 生成易读、链接可点击的消息格式 */ const fs = require('fs'); const path = require('path'); const DAILY_DIR = path.join(__dirname, '../../daily'); // 简单的翻译映射(常见术语) const termMap = { 'web browser': '网页浏览器', 'browser': '浏览器', 'independent': '独立的', 'framework': '框架', 'methodology': '方法论', 'agentic': '代理式', 'adaptive': '自适应', 'web scraping': '网页爬取', 'framework': '框架', 'high performance': '高性能', 'vector graph': '向量图', 'real time': '实时', 'analytics': '分析', 'portrait': '肖像', 'animation': '动画', 'live streaming': '直播', 'health records': '健康记录', 'medical practice': '医疗实践', 'management': '管理', 'solution': '解决方案', 'open source': '开源', 'tool': '工具', 'location': '位置', 'mobile number': '手机号码', 'track': '追踪', 'system': '系统', 'built in': '构建于', 'focused on': '专注于' }; function translateToChinese(text) { let translated = text; // 替换常见术语 for (const [eng, chi] of Object.entries(termMap)) { const regex = new RegExp(eng, 'gi'); translated = translated.replace(regex, chi); } return translated; } function getYesterdayDate() { const d = new Date(); d.setDate(d.getDate() - 1); return d.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: 'Asia/Shanghai' }).replace(/\//g, '-'); } function parseMarkdown(markdown) { const lines = markdown.split('\n'); const items = []; let currentDate = ''; let currentTime = ''; let totalItems = 0; // 解析元数据 for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line.startsWith('> 采集时间:')) { currentTime = line.replace('> 采集时间:', '').trim(); } if (line.startsWith('> 总条目:')) { totalItems = parseInt(line.replace('> 总条目:', '').trim()); } } // 解析新闻条目 const itemRegex = /^(\d+)\.\s+\[([^\]]+)\]\(([^)]+)\)\s+-\s+\*\*([^*]+)\*\*/; let currentItem = null; for (let i = 0; i < lines.length; i++) { const line = lines[i]; const match = line.match(itemRegex); if (match) { if (currentItem) { items.push(currentItem); } // 清理URL,移除登录页面 let url = match[3]; let title = match[2]; // 如果是登录页面,提取真实路径 if (url.includes('login?return_to=')) { const realPath = decodeURIComponent(url.split('return_to=')[1]); url = `https://github.com${realPath}`; title = realPath.replace('/', ''); // 使用真实仓库名 } currentItem = { number: match[1], title: title, url: url, source: match[4], description: '' }; } else if (currentItem && line.trim().startsWith('>') && !line.includes('采集时间') && !line.includes('总条目')) { // 移除所有 > 符号和前导空格 currentItem.description = line.replace(/^\s*>\s*/, '').trim(); } } if (currentItem) { items.push(currentItem); } return { currentTime, totalItems, items }; } function formatForFeishu(data) { const { currentTime, totalItems, items } = data; let message = `📰 AI Daily Brief - ${getYesterdayDate()}\n\n`; message += `⏰ 采集时间: ${currentTime}\n`; message += `📊 总条目: ${totalItems}条\n\n`; message += `━━━━━━━━━━━━━━━━━━━━\n\n`; message += `🔥 今日热点\n\n`; items.forEach((item, index) => { const num = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'][index] || `${index + 1}.`; message += `${num} ${item.title}\n`; message += `${item.source}\n`; if (item.description) { // 添加中文翻译 const translated = translateToChinese(item.description); message += `${translated}\n`; // 如果翻译后不同,显示原文 if (translated !== item.description) { message += `(原文:${item.description})\n`; } } message += `🔗 ${item.url}\n\n`; }); message += `━━━━━━━━━━━━━━━━━━━━\n`; message += `💡 点击链接跳转到GitHub查看详情\n`; return message; } async function main() { const yesterday = getYesterdayDate(); const reportPath = path.join(DAILY_DIR, `${yesterday}.md`); if (!fs.existsSync(reportPath)) { console.log(`❌ 未找到昨日简报: ${reportPath}`); return { success: false, error: 'Report not found' }; } const markdown = fs.readFileSync(reportPath, 'utf8'); const data = parseMarkdown(markdown); const formattedMessage = formatForFeishu(data); console.log('格式化后的消息:'); console.log(formattedMessage); return { success: true, date: yesterday, message: formattedMessage }; } if (require.main === module) { main().catch(console.error); } module.exports = { main, formatForFeishu, parseMarkdown };