refactor:删除未使用的文件,添加文章总结功能及相关处理逻辑

This commit is contained in:
李东云
2025-02-12 16:58:02 +08:00
parent 5900791890
commit 72512ac993
8 changed files with 183 additions and 146 deletions

View File

@@ -0,0 +1,54 @@
import type { Context } from "elysia";
import { JSDOM } from "jsdom";
import callGeminiAPI from "../llm/gemini";
import fs from 'fs';
import path from 'path';
export async function summarizeHandler({ body }: Context) {
try {
const { articleUrl } = body as { articleUrl: string };
const urls = articleUrl.split('\n').filter(url => url.trim() !== '');
async function fetchArticle(url: string): Promise<string> {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch article: Status Code ${response.status}`);
}
return await response.text();
}
let articleTexts = [];
for (const url of urls) {
try {
const articleHTML = await fetchArticle(url);
const dom = new JSDOM(articleHTML);
const jsContent = dom.window.document.querySelector("#js_content");
const content = jsContent ? jsContent.textContent : "";
articleTexts.push(content);
} catch (error) {
console.error(`Failed to process article from ${url}:`, error);
// Optionally, you might want to handle the error more gracefully,
// such as skipping the article or returning a default value.
}
}
const geminiResponse = await callGeminiAPI(articleTexts);
const today = new Date();
const fileName = `history/${today.getFullYear()}/${today.getMonth() + 1}/${today.getDate()}.md`;
const dir = path.dirname(fileName);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(fileName, geminiResponse);
return new Response(geminiResponse, {
headers: {
"Content-Type": "text/markdown; charset=utf-8",
},
});
} catch (error: any) {
console.error("Error:", error);
return { error: error.message };
}
}

20
src/index.ts Normal file
View File

@@ -0,0 +1,20 @@
import { Elysia } from "elysia";
import { html } from '@elysiajs/html'
import fs from 'fs';
import path from 'path';
import { summarizeHandler } from "./controller/summarizeHandler";
const app = new Elysia()
.use(html())
.get("/", () => {
// 读取 HTML 文件
const filePath = path.join(process.cwd(), 'index.html');
const htmlContent = fs.readFileSync(filePath, 'utf8');
return htmlContent;
})
.post("/summarize", summarizeHandler)
.listen({ port: 3000 });
console.log(
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
);

50
src/llm/gemini.ts Normal file
View File

@@ -0,0 +1,50 @@
async function callGeminiAPI(articleContent: string[]): Promise<any> {
// articleContent = `You are a helpful assistant that summarizes WeChat articles.use Chinese: ${articleContent}`;
// const response = (await model.generateContent(articleContent)).response;
// return response.text();
const {
GoogleGenerativeAI,
HarmCategory,
HarmBlockThreshold,
} = require("@google/generative-ai");
const genAI = new GoogleGenerativeAI(process.env.API_KEY || "");
console.log(process.env.API_KEY);
const model = genAI.getGenerativeModel({
model: "gemini-2.0-flash-lite-preview-02-05"
});
const generationConfig = {
temperature: 1,
topP: 0.95,
topK: 40,
maxOutputTokens: 8192,
responseMimeType: "text/plain",
};
async function run(articleContent: string[]) {
const chatSession = model.startChat({
generationConfig,
history: [
{
role: "user",
parts: [
{ text: "这里有几篇文章,用 --- 分割,帮我简要汇总一下,控制在 300 字以内。" },
{ text: "如果你认为是投资主题,我希望你能额外帮我总结和设计出一个短中长线的投资策略,要求详略得当,短线权重大一些,长线一笔带过就好" }
],
},
],
});
const result = await chatSession.sendMessage(articleContent.join("\n---\n"));
console.log(result.response.text());
return result.response.text();
}
return run(articleContent);
}
export default callGeminiAPI;

17
src/view/form.html Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>文章总结</title>
</head>
<body>
<h1>输入微信文章链接</h1>
<form action="/summarize" method="post">
<label for="articleUrl">文章链接:</label><br>
<textarea id="articleUrl" name="articleUrl" rows="4" cols="50"></textarea><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>