From 4918e517e182c9452548326d97a901434a9db88f Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Wed, 24 Jun 2026 14:00:50 +0800 Subject: [PATCH] 1400 --- write-server/scripts/test-artalk.sh | 52 +++++++++++++++++++ write-server/src/lib/bot/notify.ts | 79 ++++++++++++++++++++++++++--- 2 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 write-server/scripts/test-artalk.sh diff --git a/write-server/scripts/test-artalk.sh b/write-server/scripts/test-artalk.sh new file mode 100644 index 00000000..5dea1875 --- /dev/null +++ b/write-server/scripts/test-artalk.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# 测试 Artalk API 连接 + +echo "" +echo "===================================" +echo " 测试 Artalk API" +echo "===================================" +echo "" + +# 从 .env 读取配置 +if [ -f ".env" ]; then + ARTALK_SERVER=$(grep "^ARTALK_SERVER=" .env | cut -d'=' -f2) + ARTALK_SITE=$(grep "^ARTALK_SITE=" .env | cut -d'=' -f2) +else + echo "错误: .env 文件不存在" + exit 1 +fi + +echo "Artalk 服务器: $ARTALK_SERVER" +echo "站点名称: $ARTALK_SITE" +echo "" + +# URL 编码站点名称 +ENCODED_SITE=$(echo -n "$ARTALK_SITE" | python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))" 2>/dev/null || echo -n "$ARTALK_SITE" | jq -sRr @uri 2>/dev/null || echo "$ARTALK_SITE") + +echo "编码后的站点名: $ENCODED_SITE" +echo "" + +# 测试 API +URL="$ARTALK_SERVER/api/v2/comments?site_name=$ENCODED_SITE&limit=5&sort_by=created_at&sort_order=desc" +echo "请求 URL: $URL" +echo "" +echo "--- 发送请求 ---" +echo "" + +# 发送请求并显示完整响应 +curl -v "$URL" 2>&1 + +echo "" +echo "" +echo "--- 测试完成 ---" +echo "" + +# 测试基本连通性 +echo "测试服务器连通性..." +if curl -s -o /dev/null -w "%{http_code}" "$ARTALK_SERVER" | grep -q "200\|301\|302"; then + echo "✓ Artalk 服务器可访问" +else + echo "✗ Artalk 服务器可能无法访问" +fi + +echo "" diff --git a/write-server/src/lib/bot/notify.ts b/write-server/src/lib/bot/notify.ts index 67921545..57b05d81 100644 --- a/write-server/src/lib/bot/notify.ts +++ b/write-server/src/lib/bot/notify.ts @@ -11,23 +11,86 @@ interface ArtalkComment { created_at: string; } +interface ArtalkPage { + id: number; + key: string; + title: string; +} + let lastCheckedId = 0; let notifierStarted = false; -async function fetchLatestComments(): Promise { +// 获取所有页面 +async function fetchAllPages(): Promise { try { - const url = `${ARTALK_SERVER}/api/v2/comments?site_name=${encodeURIComponent(ARTALK_SITE)}&limit=5&sort_by=created_at&sort_order=desc`; - const headers: Record = { - "Content-Type": "application/json", - }; - // Artalk 公开 API 不需要认证,但加上 token 以备后续需要 - const res = await fetch(url, { headers }); + const url = `${ARTALK_SERVER}/api/v2/pages?site_name=${encodeURIComponent(ARTALK_SITE)}&limit=100`; + const res = await fetch(url, { + headers: { "Content-Type": "application/json" }, + }); + if (!res.ok) { - console.error("[comment-notify] fetch failed:", res.status, res.statusText); + console.error("[comment-notify] fetch pages failed:", res.status); return []; } + + const data = await res.json() as { pages?: ArtalkPage[] }; + return data.pages || []; + } catch (e) { + console.error("[comment-notify] fetch pages error:", e instanceof Error ? e.message : String(e)); + return []; + } +} + +// 获取特定页面的最新评论 +async function fetchCommentsForPage(pageKey: string): Promise { + try { + const url = `${ARTALK_SERVER}/api/v2/comments?site_name=${encodeURIComponent(ARTALK_SITE)}&page_key=${encodeURIComponent(pageKey)}&limit=5&sort_by=created_at&sort_order=desc`; + const res = await fetch(url, { + headers: { "Content-Type": "application/json" }, + }); + + if (!res.ok) { + return []; + } + const data = await res.json() as { comments?: ArtalkComment[] }; return data.comments || []; + } catch (e) { + return []; + } +} + +// 获取所有页面的最新评论,合并后返回最新的 5 条 +async function fetchLatestComments(): Promise { + try { + // 1. 获取所有页面 + const pages = await fetchAllPages(); + if (pages.length === 0) { + console.log("[comment-notify] no pages found"); + return []; + } + + console.log("[comment-notify] found", pages.length, "pages, checking comments..."); + + // 2. 获取每个页面的最新评论(并行请求) + const allComments: ArtalkComment[] = []; + const promises = pages.map(async (page) => { + const comments = await fetchCommentsForPage(page.key); + return comments; + }); + + const results = await Promise.all(promises); + results.forEach(comments => allComments.push(...comments)); + + // 3. 按时间排序,取最新的 5 条 + allComments.sort((a, b) => + new Date(b.created_at).getTime() - new Date(a.created_at).getTime() + ); + + const latestComments = allComments.slice(0, 5); + console.log("[comment-notify] fetched", latestComments.length, "latest comments from", pages.length, "pages"); + + return latestComments; } catch (e) { console.error("[comment-notify] fetch error:", e instanceof Error ? e.message : String(e)); return [];