175 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 };