const fs = require('fs'); const path = require('path'); const matter = require('gray-matter'); const axios = require('axios'); require('dotenv').config(); // Configuration const CONTENT_DIR = path.join(__dirname, '../content/post'); const PROVIDER = process.env.AI_PROVIDER || 'siliconflow'; // 'siliconflow' or 'zhipu' const SILICONFLOW_API_KEY = process.env.SILICONFLOW_API_KEY; const ZHIPU_API_KEY = process.env.ZHIPU_API_KEY; // SiliconFlow Config const SILICONFLOW_URL = 'https://api.siliconflow.cn/v1/chat/completions'; const SILICONFLOW_MODEL = 'deepseek-ai/DeepSeek-V3'; // Zhipu Config const ZHIPU_URL = 'https://open.bigmodel.cn/api/paas/v4/chat/completions'; const ZHIPU_MODEL = 'glm-4'; async function generateComment(content) { const prompt = `你是一个热情的博客读者。请阅读以下文章内容,并写一段简短的评论(100字以内)。 要求: 1. 语气自然、轻松,像真人的评论。 2. 可以带一点幽默或感慨。 3. 不要只是总结文章,要发表看法或共鸣。 4. 不要带引号。 文章内容: ${content.substring(0, 2000)}...`; // Truncate to avoid token limits try { if (PROVIDER === 'siliconflow') { if (!SILICONFLOW_API_KEY) throw new Error('SILICONFLOW_API_KEY is missing'); const response = await axios.post(SILICONFLOW_URL, { model: SILICONFLOW_MODEL, messages: [{ role: 'user', content: prompt }], temperature: 0.7, max_tokens: 200 }, { headers: { 'Authorization': `Bearer ${SILICONFLOW_API_KEY}`, 'Content-Type': 'application/json' } }); return response.data.choices[0].message.content.trim(); } else if (PROVIDER === 'zhipu') { if (!ZHIPU_API_KEY) throw new Error('ZHIPU_API_KEY is missing'); const response = await axios.post(ZHIPU_URL, { model: ZHIPU_MODEL, messages: [{ role: 'user', content: prompt }], temperature: 0.7 }, { headers: { 'Authorization': `Bearer ${ZHIPU_API_KEY}`, 'Content-Type': 'application/json' } }); return response.data.choices[0].message.content.trim(); } } catch (error) { console.error('API Error:', error.response ? error.response.data : error.message); return null; } } async function processFiles(dir) { const files = await fs.promises.readdir(dir); for (const file of files) { const filePath = path.join(dir, file); const stats = await fs.promises.stat(filePath); if (stats.isDirectory()) { await processFiles(filePath); continue; } if (!file.endsWith('.md')) continue; const content = await fs.promises.readFile(filePath, 'utf8'); const parsed = matter(content); if (parsed.data.ai_comment && !process.argv.includes('--force')) { console.log(`[Skip] ${file} already has ai_comment`); continue; } console.log(`[Generating] Comment for ${file}...`); // Remove front matter and HTML tags for prompt const cleanContent = parsed.content.replace(/<[^>]*>?/gm, ''); const comment = await generateComment(cleanContent); if (comment) { parsed.data.ai_comment = comment; const newContent = matter.stringify(parsed.content, parsed.data); await fs.promises.writeFile(filePath, newContent); console.log(`[Success] Updated ${file}`); } else { console.log(`[Failed] Could not generate comment for ${file}`); } } } // Check arguments const args = process.argv.slice(2); if (args.includes('--help')) { console.log(` Usage: node scripts/ai_comment.js Environment Variables (.env): AI_PROVIDER - 'siliconflow' (default) or 'zhipu' SILICONFLOW_API_KEY - Key for SiliconFlow ZHIPU_API_KEY - Key for Zhipu AI `); process.exit(0); } console.log(`Starting AI Comment Generator using ${PROVIDER}...`); processFiles(CONTENT_DIR).catch(console.error);