diff --git a/skill/ai-news-collector/feishu-card.js b/skill/ai-news-collector/feishu-card.js new file mode 100644 index 0000000..19473a3 --- /dev/null +++ b/skill/ai-news-collector/feishu-card.js @@ -0,0 +1,174 @@ +#!/usr/bin/env node + +/** + * 飞书卡片消息格式化 + * 生成可点击链接的富文本卡片 + */ + +const fs = require('fs'); +const path = require('path'); + +const DAILY_DIR = path.join(__dirname, '../../daily'); + +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 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 createFeishuCard(data) { + const { currentTime, totalItems, items } = data; + + const elements = [ + { + tag: "div", + text: { + tag: "lark_md", + content: `**⏰ 采集时间**: ${currentTime}\n**📊 总条目**: ${totalItems}条` + } + }, + { + tag: "hr" + } + ]; + + // 添加新闻条目 + items.forEach((item, index) => { + const num = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟'][index] || `${index + 1}.`; + + elements.push({ + tag: "div", + text: { + tag: "lark_md", + content: `${num} **${item.title}**\n\`${item.source}\`\n> ${item.description}\n[🔗 点击查看详情](${item.url})` + } + }); + + // 每条之间加分隔线(除了最后一条) + if (index < items.length - 1) { + elements.push({ + tag: "hr" + }); + } + }); + + // 添加底部提示 + elements.push({ + tag: "hr" + }); + elements.push({ + tag: "note", + elements: [ + { + tag: "plain_text", + content: "💡 点击链接跳转到GitHub查看详情\n*Generated by AINewsCollector*" + } + ] + }); + + return { + msg_type: "interactive", + card: { + header: { + title: { + tag: "plain_text", + content: `📰 AI Daily Brief - ${getYesterdayDate()}` + }, + template: "blue" + }, + elements: elements + } + }; +} + +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 card = createFeishuCard(data); + + console.log(JSON.stringify(card, null, 2)); + + return { + success: true, + date: yesterday, + card: card + }; +} + +if (require.main === module) { + main().catch(console.error); +} + +module.exports = { main, createFeishuCard, parseMarkdown };