diff --git a/README.md b/README.md
index 0dc5976..f4dc5c5 100644
--- a/README.md
+++ b/README.md
@@ -64,8 +64,11 @@
**内容成果展示:**
-* 🎙️ **小宇宙**:[来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e)
-* 📹 **抖音**:[来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)
+| 🎙️ **小宇宙** | 📹 **抖音** |
+| --- | --- |
+| [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
+|  |  |
+
**项目截图:**
diff --git a/src/foot.js b/src/foot.js
new file mode 100644
index 0000000..9426e3c
--- /dev/null
+++ b/src/foot.js
@@ -0,0 +1,15 @@
+export function insertFoot() {
+ return `
+
+ ---
+
+ **收听语音版**
+
+ | 🎙️ **小宇宙** | 📹 **抖音** |
+ | --- | --- |
+ | [来生小酒馆](https://www.xiaoyuzhoufm.com/podcast/683c62b7c1ca9cf575a5030e) | [来生情报站](https://www.douyin.com/user/MS4wLjABAAAAwpwqPQlu38sO38VyWgw9ZjDEnN4bMR5j8x111UxpseHR9DpB6-CveI5KRXOWuFwG)|
+ |  |  |
+
+
+ `;
+}
diff --git a/src/github.js b/src/github.js
index e181cbb..c0ad1b5 100644
--- a/src/github.js
+++ b/src/github.js
@@ -87,4 +87,35 @@ export async function createOrUpdateGitHubFile(env, filePath, content, commitMes
payload.sha = existingSha;
}
return callGitHubApi(env, `/contents/${filePath}`, 'PUT', payload);
-}
\ No newline at end of file
+}
+
+/**
+ * Gets the content of a file from GitHub.
+ */
+export async function getDailyReportContent(env, filePath) {
+ const GITHUB_BRANCH = env.GITHUB_BRANCH || 'main';
+ const GITHUB_REPO_OWNER = env.GITHUB_REPO_OWNER;
+ const GITHUB_REPO_NAME = env.GITHUB_REPO_NAME;
+
+ if (!GITHUB_REPO_OWNER || !GITHUB_REPO_NAME) {
+ console.error("GitHub environment variables (GITHUB_REPO_OWNER, GITHUB_REPO_NAME) are not configured.");
+ throw new Error("GitHub API configuration is missing in environment variables.");
+ }
+
+ const rawUrl = `https://raw.githubusercontent.com/${GITHUB_REPO_OWNER}/${GITHUB_REPO_NAME}/${GITHUB_BRANCH}/${filePath}`;
+ console.log(rawUrl)
+ try {
+ const response = await fetch(rawUrl);
+ if (!response.ok) {
+ if (response.status === 404) {
+ console.log(`File not found: ${filePath} on branch ${GITHUB_BRANCH}`);
+ return null;
+ }
+ throw new Error(`Failed to fetch file from GitHub: ${response.status} ${response.statusText}`);
+ }
+ return await response.text();
+ } catch (error) {
+ console.error(`Error fetching daily report content from ${rawUrl}:`, error);
+ throw error;
+ }
+}
diff --git a/src/handlers/commitToGitHub.js b/src/handlers/commitToGitHub.js
index 0109948..e10297b 100644
--- a/src/handlers/commitToGitHub.js
+++ b/src/handlers/commitToGitHub.js
@@ -1,6 +1,9 @@
// src/handlers/commitToGitHub.js
-import { getISODate, formatMarkdownText } from '../helpers.js';
+import { getISODate, formatMarkdownText, replaceImageProxy,formatDateToChineseWithTime } from '../helpers.js';
import { getGitHubFileSha, createOrUpdateGitHubFile } from '../github.js';
+import { storeInKV } from '../kv.js';
+import { marked } from '../marked.esm.js';
+
export async function handleCommitToGitHub(request, env) {
if (request.method !== 'POST') {
return new Response(JSON.stringify({ status: 'error', message: 'Method Not Allowed' }), { status: 405, headers: { 'Content-Type': 'application/json' } });
@@ -10,11 +13,21 @@ export async function handleCommitToGitHub(request, env) {
const dateStr = formData.get('date') || getISODate();
const dailyMd = formData.get('daily_summary_markdown');
const podcastMd = formData.get('podcast_script_markdown');
+ const report = {
+ report_date: dateStr,
+ title: dateStr+'日刊',
+ link: '/daily/'+dateStr+'.html',
+ content_html: null,
+ // 可以添加其他相關欄位,例如作者、來源等
+ published_date: formatDateToChineseWithTime(new Date()) // 記錄保存時間
+ }
const filesToCommit = [];
if (dailyMd) {
filesToCommit.push({ path: `daily/${dateStr}.md`, content: formatMarkdownText(dailyMd), description: "Daily Summary File" });
+ report.content_html = marked.parse(formatMarkdownText(replaceImageProxy(env.IMG_PROXY, dailyMd)));
+ storeInKV(env.DATA_KV, `${dateStr}-report`, report);
}
if (podcastMd) {
filesToCommit.push({ path: `podcast/${dateStr}.md`, content: podcastMd, description: "Podcast Script File" });
diff --git a/src/handlers/genAIContent.js b/src/handlers/genAIContent.js
index a6a7e5a..d408550 100644
--- a/src/handlers/genAIContent.js
+++ b/src/handlers/genAIContent.js
@@ -8,6 +8,7 @@ import { getSystemPromptSummarizationStepOne } from '../prompt/summarizationProm
import { getSystemPromptSummarizationStepTwo } from '../prompt/summarizationPromptStepTwo.js';
import { getSystemPromptPodcastFormatting } from '../prompt/podcastFormattingPrompt.js';
import { getSystemPromptDailyAnalysis } from '../prompt/dailyAnalysisPrompt.js'; // Import new prompt
+import { insertFoot } from '../foot.js';
export async function handleGenAIPodcastScript(request, env) {
let dateStr;
@@ -228,6 +229,7 @@ export async function handleGenAIContent(request, env) {
if (fullPromptForCall2_User) promptsMarkdownContent += `### User Input (Output of Call 1)\n\`\`\`\n${fullPromptForCall2_User}\n\`\`\`\n\n`;
let dailySummaryMarkdownContent = `# ${env.DAILY_TITLE} ${formatDateToChinese(dateStr)}\n\n${removeMarkdownCodeBlock(outputOfCall2)}`;
+ if (env.INSERT_FOOT) dailySummaryMarkdownContent += insertFoot() +`\n\n`;
const successHtml = generateGenAiPageHtml(
env,
diff --git a/src/handlers/getRss.js b/src/handlers/getRss.js
new file mode 100644
index 0000000..6e4c94d
--- /dev/null
+++ b/src/handlers/getRss.js
@@ -0,0 +1,99 @@
+import { stripHtml, getShanghaiTime, formatRssDate } from '../helpers.js';
+import { getFromKV } from '../kv.js';
+
+function minifyHTML(htmlString) {
+ if (typeof htmlString !== 'string') {
+ return '';
+ }
+
+ return htmlString
+ .replace(/>\s+<') // 移除标签之间的空白
+ .trim(); // 移除字符串两端的空白
+}
+
+/**
+ * 處理 Supabase RSS 請求
+ * @param {Request} request - 傳入的請求物件
+ * @param {object} env - Cloudflare Workers 環境變數
+ * @returns {Response} RSS Feed 的回應
+ */
+export async function handleRss(request, env) {
+ const url = new URL(request.url);
+ const days = parseInt(url.searchParams.get('days')) || 7; // 預設查詢 7 天內的資料
+
+ const allData = [];
+ const today = getShanghaiTime(); // 加上東八時區的偏移量
+ console.log(today);
+
+ for (let i = 0; i < days; i++) {
+ const date = new Date(today);
+ date.setDate(today.getDate() - i);
+ const dateStr = date.toISOString().split('T')[0]; // YYYY-MM-DD
+ const key = `${dateStr}-report`;
+ const data = await getFromKV(env.DATA_KV, key);
+ if (data) {
+ allData.push(data);
+ }
+ }
+
+ // 扁平化數據,因為每個 report 可能包含多個項目
+ const data = allData.flat();
+
+ if (!data || data.length === 0) {
+ return new Response('沒有找到相關資料', { status: 200 });
+ }
+
+ // 建立 RSS Feed
+ let rssItems = '';
+ if (data && data.length > 0) {
+ const filteredData = {};
+ data.forEach(item => {
+ const reportDate = item.report_date;
+ const publishedDate = new Date(item.published_date);
+
+ if (!filteredData[reportDate] || publishedDate > new Date(filteredData[reportDate].published_date)) {
+ filteredData[reportDate] = item;
+ }
+ });
+ const finalData = Object.values(filteredData);
+
+ finalData.forEach(item => {
+ const pubDate = item.published_date ? formatRssDate(new Date(item.published_date)) : formatRssDate(new Date());
+ const content = minifyHTML(item.content_html);
+ const title = item.title || '无标题';
+ const link = env.BOOK_LINK+item.link || '#';
+ const description = stripHtml(item.content_html).substring(0, 200); // 移除 HTML 標籤並截取 200 字元
+
+ rssItems += `
+
所选内容日期: ${formatDateToChinese(escapeHtml(pageDate))}