From 791be8bd4f8e66869efab70112af007aabbdf697 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Tue, 2 Jun 2026 11:43:58 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E8=8B=A5=E5=B9=B2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96slug=E7=94=9F=E6=88=90?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 6 ++++ .../1780330451237-AgACAgQA.jpg | Bin .../1780330453301-AgACAgQA.jpg | Bin .../1780330454866-AgACAgQA.jpg | Bin .../1780330606155-AgACAgQA.jpg | Bin .../index.md | 6 ++-- hugo.toml | 2 +- scripts/fetch_greetings.js | 4 +-- themes/Ying/assets/js/modules/search.js | 22 +++++++------ write/src/lib/bot/handlers.ts | 4 ++- write/src/lib/bot/helpers.ts | 22 +++++-------- write/src/lib/bot/poll.ts | 9 ++++-- write/src/lib/bot/sessions.ts | 30 ++++++++++++++++-- write/src/lib/posts.ts | 8 +++-- write/src/types/marked.d.ts | 4 +-- 15 files changed, 76 insertions(+), 41 deletions(-) rename content/post/2026/{2026-06-01-尝试接入-telegram-机器人 => 2026-06-02-尝试接入-telegram-机器人}/1780330451237-AgACAgQA.jpg (100%) rename content/post/2026/{2026-06-01-尝试接入-telegram-机器人 => 2026-06-02-尝试接入-telegram-机器人}/1780330453301-AgACAgQA.jpg (100%) rename content/post/2026/{2026-06-01-尝试接入-telegram-机器人 => 2026-06-02-尝试接入-telegram-机器人}/1780330454866-AgACAgQA.jpg (100%) rename content/post/2026/{2026-06-01-尝试接入-telegram-机器人 => 2026-06-02-尝试接入-telegram-机器人}/1780330606155-AgACAgQA.jpg (100%) rename content/post/2026/{2026-06-01-尝试接入-telegram-机器人 => 2026-06-02-尝试接入-telegram-机器人}/index.md (93%) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c131f41e..ca6ed309 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,6 +49,12 @@ jobs: continue-on-error: true run: node scripts/optimize_images.js + - name: Fetch AI Greetings + continue-on-error: true + env: + RSS_API_TOKEN: ${{ secrets.RSS_API_TOKEN }} + run: node scripts/fetch_greetings.js + - name: Commit Optimized Images continue-on-error: true run: | diff --git a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330451237-AgACAgQA.jpg b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330451237-AgACAgQA.jpg similarity index 100% rename from content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330451237-AgACAgQA.jpg rename to content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330451237-AgACAgQA.jpg diff --git a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330453301-AgACAgQA.jpg b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330453301-AgACAgQA.jpg similarity index 100% rename from content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330453301-AgACAgQA.jpg rename to content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330453301-AgACAgQA.jpg diff --git a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330454866-AgACAgQA.jpg b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330454866-AgACAgQA.jpg similarity index 100% rename from content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330454866-AgACAgQA.jpg rename to content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330454866-AgACAgQA.jpg diff --git a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330606155-AgACAgQA.jpg b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330606155-AgACAgQA.jpg similarity index 100% rename from content/post/2026/2026-06-01-尝试接入-telegram-机器人/1780330606155-AgACAgQA.jpg rename to content/post/2026/2026-06-02-尝试接入-telegram-机器人/1780330606155-AgACAgQA.jpg diff --git a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/index.md b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/index.md similarity index 93% rename from content/post/2026/2026-06-01-尝试接入-telegram-机器人/index.md rename to content/post/2026/2026-06-02-尝试接入-telegram-机器人/index.md index 148741d7..fd9ec6a8 100644 --- a/content/post/2026/2026-06-01-尝试接入-telegram-机器人/index.md +++ b/content/post/2026/2026-06-02-尝试接入-telegram-机器人/index.md @@ -1,7 +1,7 @@ --- -title: 尝试接入telegram机器人 -date: '2026-06-01T00:00:00.000Z' -slug: 2026-06-01-尝试接入-telegram-机器人 +title: 尝试接入 telegram 机器人 +date: '2026-06-02T00:00:00.000Z' +slug: '202606021139' draft: false categories: - 生活 diff --git a/hugo.toml b/hugo.toml index e44a0956..9b2afda1 100644 --- a/hugo.toml +++ b/hugo.toml @@ -219,7 +219,7 @@ hasCJKLanguage = true # 打赏配置 (Reward Configuration) # ---------------------------------------------------------------------------- [params.reward] - enable = true + enable = false wechat = "/image/reward/new.png" # alipay = "/image/reward/alipay.jpg" # qq = "/image/reward/reward.png" diff --git a/scripts/fetch_greetings.js b/scripts/fetch_greetings.js index b16b90ad..286c6e99 100644 --- a/scripts/fetch_greetings.js +++ b/scripts/fetch_greetings.js @@ -58,13 +58,13 @@ async function main() { } }); - // Pick one random greeting per time slot, fall back to generic pool + // Keep all greetings per time slot (frontend picks randomly) var timeGreetings = {}; timeKeys.forEach(function(key) { var list = byTime[key]; if (list.length === 0) list = generic; if (list.length > 0) { - timeGreetings[key] = list[Math.floor(Math.random() * list.length)]; + timeGreetings[key] = list; } }); diff --git a/themes/Ying/assets/js/modules/search.js b/themes/Ying/assets/js/modules/search.js index 5976acf7..85641740 100644 --- a/themes/Ying/assets/js/modules/search.js +++ b/themes/Ying/assets/js/modules/search.js @@ -354,17 +354,19 @@ function initInlineSearch() { } // 2. Check Time of Day (if greetings configured) else if (window.searchGreetings) { - if (hour >= 6 && hour < 11 && window.searchGreetings.morning) { - text = window.searchGreetings.morning; - } else if (hour >= 11 && hour < 14 && window.searchGreetings.noon) { - text = window.searchGreetings.noon; - } else if (hour >= 14 && hour < 18 && window.searchGreetings.afternoon) { - text = window.searchGreetings.afternoon; - } else if (hour >= 18 && hour < 22 && window.searchGreetings.evening) { - text = window.searchGreetings.evening; - } else if ((hour >= 22 || hour < 6) && window.searchGreetings.night) { - text = window.searchGreetings.night; + function pickGreeting(key) { + var val = window.searchGreetings[key]; + if (!val) return null; + if (Array.isArray(val)) return val[Math.floor(Math.random() * val.length)]; + return val; } + var picked = null; + if (hour >= 6 && hour < 11) picked = pickGreeting('morning'); + else if (hour >= 11 && hour < 14) picked = pickGreeting('noon'); + else if (hour >= 14 && hour < 18) picked = pickGreeting('afternoon'); + else if (hour >= 18 && hour < 22) picked = pickGreeting('evening'); + else if (hour >= 22 || hour < 6) picked = pickGreeting('night'); + if (picked) text = picked; } var typeInterval; diff --git a/write/src/lib/bot/handlers.ts b/write/src/lib/bot/handlers.ts index 57861f88..2d09785a 100644 --- a/write/src/lib/bot/handlers.ts +++ b/write/src/lib/bot/handlers.ts @@ -5,7 +5,7 @@ import { deployQueue } from "@/lib/git"; import { hugo } from "@/lib/hugo"; import { getLanIP, DEFAULT_AUTHOR } from "@/lib/config"; import { sendMessage, tg } from "./tg"; -import { getSession, hasSession, clearSession, saveSession, undoLastChunk } from "./sessions"; +import { getSession, hasSession, clearSession, saveSession, undoLastChunk, initSessionDir } from "./sessions"; import { makeSlug, sessionSummary, truncateText } from "./helpers"; import { getCached, setCache, invalidateByPrefix } from "./cache"; @@ -221,6 +221,7 @@ handlers.new = async (chatId, title) => { s.draft = true; s.author = DEFAULT_AUTHOR; s.chunks = []; + initSessionDir(chatId, title); await tg("sendMessage", { chat_id: chatId, text: "📝 开始写:" + title + "\n\n📂 设置分类(可选)", @@ -320,6 +321,7 @@ handlers.edit = async (chatId, slug) => { s.originalSlug = post.frontMatter.slug; s.content = ""; s.chunks = []; + s.dirPath = post.dirPath; s.categories = (post.frontMatter.categories as string[]) || []; s.tags = (post.frontMatter.tags as string[]) || []; s.author = post.frontMatter.author || DEFAULT_AUTHOR; diff --git a/write/src/lib/bot/helpers.ts b/write/src/lib/bot/helpers.ts index 81f36cad..37992651 100644 --- a/write/src/lib/bot/helpers.ts +++ b/write/src/lib/bot/helpers.ts @@ -1,13 +1,12 @@ -import path from "path"; -import { CONTENT_DIR } from "@/lib/config"; - export function makeSlug(title: string): string { - const dateStr = new Date().toISOString().slice(0, 10); - const slugPart = (title || "untitled") - .replace(/[^\w一-鿿㐀-䶿]+/g, "-") - .replace(/^-+|-+$/g, "") - .toLowerCase() || "post"; - return dateStr + "-" + slugPart; + const now = new Date(); + const y = now.getFullYear(); + const m = String(now.getMonth() + 1).padStart(2, "0"); + const d = String(now.getDate()).padStart(2, "0"); + const h = String(now.getHours()).padStart(2, "0"); + const mi = String(now.getMinutes()).padStart(2, "0"); + const s = String(now.getSeconds()).padStart(2, "0"); + return `${y}${m}${d}${h}${mi}${s}`; } export function sessionSummary(s: { @@ -26,11 +25,6 @@ export function sessionSummary(s: { return parts.filter(Boolean).join(" · "); } -export function getArticleDirPath(slug: string): string { - const year = slug.slice(0, 4); - return path.join(CONTENT_DIR, year, slug); -} - export function truncateText(text: string, maxLen: number): string { if (text.length <= maxLen) return text; return text.slice(0, maxLen) + "\n\n... 前 " + maxLen + " 字"; diff --git a/write/src/lib/bot/poll.ts b/write/src/lib/bot/poll.ts index 21d93069..455d1ad4 100644 --- a/write/src/lib/bot/poll.ts +++ b/write/src/lib/bot/poll.ts @@ -171,11 +171,14 @@ async function handlePhoto(chatId: number, photos: { file_id: string }[], captio try { const fs = await import("fs"); const path = await import("path"); - const { CONTENT_DIR } = await import("@/lib/config"); const { getSession } = await import("./sessions"); - const { getArticleDirPath } = await import("./helpers"); const s = getSession(chatId); + if (!s.dirPath) { + await sendMessage(chatId, "❌ 请先发 /new 或 /edit 开始写作"); + return; + } + const largestPhoto = photos[photos.length - 1]; const fileRes = await tg<{ file_path?: string }>("getFile", { file_id: largestPhoto.file_id }); if (!fileRes.ok || !fileRes.result?.file_path) return; @@ -185,7 +188,7 @@ async function handlePhoto(chatId: number, photos: { file_id: string }[], captio const imgBuffer = await fetch(fileUrl).then((r) => r.arrayBuffer()); // Save to article's own folder (Hugo page bundle) - const articleDir = getArticleDirPath(s.slug); + const articleDir = s.dirPath; if (!fs.existsSync(articleDir)) fs.mkdirSync(articleDir, { recursive: true }); const ext = filePath.split(".").pop() || "jpg"; diff --git a/write/src/lib/bot/sessions.ts b/write/src/lib/bot/sessions.ts index 875b445b..fba84b86 100644 --- a/write/src/lib/bot/sessions.ts +++ b/write/src/lib/bot/sessions.ts @@ -1,5 +1,6 @@ import { createPost, updatePost, getPost } from "@/lib/posts"; -import { DEFAULT_AUTHOR } from "@/lib/config"; +import { DEFAULT_AUTHOR, CONTENT_DIR } from "@/lib/config"; +import path from "path"; export interface Session { title: string; @@ -11,6 +12,18 @@ export interface Session { draft: boolean; chunks: string[]; originalSlug?: string; + dirPath: string; +} + +function computeDirPath(title: string, date?: string): string { + const d = date ? new Date(date) : new Date(); + const year = d.getFullYear().toString(); + const dateStr = d.toISOString().slice(0, 10); + const titlePart = (title || "untitled") + .replace(/[^\w一-鿿㐀-䶿]+/g, "-") + .replace(/^-+|-+$/g, "") + .toLowerCase() || "post"; + return path.join(CONTENT_DIR, year, `${dateStr}-${titlePart}`); } const sessions = new Map(); @@ -26,6 +39,7 @@ export function getSession(chatId: number): Session { author: DEFAULT_AUTHOR, draft: true, chunks: [], + dirPath: "", }); } return sessions.get(chatId)!; @@ -56,11 +70,19 @@ export function undoLastChunk(chatId: number): boolean { return true; } +export function initSessionDir(chatId: number, title: string, date?: string): void { + const s = getSession(chatId); + if (!s.dirPath) { + s.dirPath = computeDirPath(title, date); + } +} + export async function saveSession(s: Session, isDraft: boolean): Promise { + const dateStr = new Date().toISOString().slice(0, 10); const frontMatter = { title: s.title, slug: s.slug, - date: new Date().toISOString().slice(0, 10), + date: dateStr, draft: isDraft, categories: s.categories, tags: s.tags, @@ -71,7 +93,9 @@ export async function saveSession(s: Session, isDraft: boolean): Promise { if (existing) { const result = updatePost(s.slug, frontMatter, s.content); if (!result.success) throw new Error("更新文章失败"); + s.dirPath = result.dirPath; } else { - createPost(frontMatter, s.content); + const dirPath = createPost(frontMatter, s.content); + s.dirPath = dirPath; } } diff --git a/write/src/lib/posts.ts b/write/src/lib/posts.ts index 1dfecdee..4246086d 100644 --- a/write/src/lib/posts.ts +++ b/write/src/lib/posts.ts @@ -155,7 +155,7 @@ export function createPost(frontMatter: PostFrontMatter, content: string): strin const date = new Date(frontMatter.date || new Date()); const year = date.getFullYear().toString(); const dateStr = date.toISOString().slice(0, 10); - // Folder name: date + sanitized title (Chinese-friendly) + // Folder name: date + sanitized title (human-readable on disk) const titlePart = (frontMatter.title || "untitled") .replace(/[^\w一-鿿㐀-䶿]+/g, "-") .replace(/^-+|-+$/g, "") @@ -202,7 +202,11 @@ export function updatePost( const newDate = new Date(merged.date || post.frontMatter.date); const newYear = newDate.getFullYear().toString(); const newDateStr = newDate.toISOString().slice(0, 10); - const newDirName = `${newDateStr}-${frontMatter.slug}`; + const titlePart = (merged.title || "untitled") + .replace(/[^\w一-鿿㐀-䶿]+/g, "-") + .replace(/^-+|-+$/g, "") + .toLowerCase() || "post"; + const newDirName = `${newDateStr}-${titlePart}`; const newDirPath = path.join(CONTENT_DIR, newYear, newDirName); if (fs.existsSync(newDirPath) && newDirPath !== post.dirPath) { diff --git a/write/src/types/marked.d.ts b/write/src/types/marked.d.ts index fe365636..24c2d3bf 100644 --- a/write/src/types/marked.d.ts +++ b/write/src/types/marked.d.ts @@ -1,4 +1,4 @@ declare module "marked" { - export function marked(src: string): string; - export function parse(src: string): string; + export function parse(src: string, options?: Record): string; + export const marked: { parse: typeof parse }; }