1434
This commit is contained in:
1 parent
bfb5a13b75
commit
04ba3c51d0
2 files changed
+154
-24
No files matched your search
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# 测试不同的 Artalk API 端点
|
||||
|
||||
echo ""
|
||||
echo "==================================="
|
||||
echo " 测试 Artalk API 端点"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# 从 .env 读取配置
|
||||
ARTALK_SERVER=$(grep "^ARTALK_SERVER=" .env | cut -d'=' -f2)
|
||||
ARTALK_SITE=$(grep "^ARTALK_SITE=" .env | cut -d'=' -f2)
|
||||
ARTALK_ADMIN_EMAIL=$(grep "^ARTALK_ADMIN_EMAIL=" .env | cut -d'=' -f2)
|
||||
ARTALK_ADMIN_PASSWORD=$(grep "^ARTALK_ADMIN_PASSWORD=" .env | cut -d'=' -f2)
|
||||
|
||||
echo "服务器: $ARTALK_SERVER"
|
||||
echo "站点: $ARTALK_SITE"
|
||||
echo ""
|
||||
|
||||
# 1. 登录获取 token
|
||||
echo "1. 登录获取 token..."
|
||||
LOGIN_RESPONSE=$(curl -s -X POST "$ARTALK_SERVER/api/v2/auth/email/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"$ARTALK_ADMIN_EMAIL\",\"password\":\"$ARTALK_ADMIN_PASSWORD\"}")
|
||||
|
||||
TOKEN=$(echo "$LOGIN_RESPONSE" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "✗ 登录失败"
|
||||
echo "响应: $LOGIN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ 登录成功,获取到 token"
|
||||
echo ""
|
||||
|
||||
# 2. 测试不同的 API 端点
|
||||
echo "2. 测试 API 端点..."
|
||||
echo ""
|
||||
|
||||
# 端点列表
|
||||
ENDPOINTS=(
|
||||
"/api/v2/pages?site_name=$ARTALK_SITE&limit=100"
|
||||
"/api/v2/admin/pages?site_name=$ARTALK_SITE&limit=100"
|
||||
"/api/v2/comments?site_name=$ARTALK_SITE&page_key=/&limit=5"
|
||||
"/api/v2/comments?site_name=$ARTALK_SITE&limit=5"
|
||||
)
|
||||
|
||||
for endpoint in "${ENDPOINTS[@]}"; do
|
||||
echo "测试: $endpoint"
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" "$ARTALK_SERVER$endpoint" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $TOKEN")
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✓ 成功 ($HTTP_CODE)"
|
||||
echo " 响应: $BODY" | head -c 100
|
||||
echo ""
|
||||
break
|
||||
else
|
||||
echo "✗ 失败 ($HTTP_CODE)"
|
||||
echo " 响应: $BODY" | head -c 100
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "==================================="
|
||||
echo " 测试完成"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
@@ -11,6 +11,12 @@ interface ArtalkComment {
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface ArtalkPage {
|
||||
id: number;
|
||||
key: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
let lastCheckedId = 0;
|
||||
let notifierStarted = false;
|
||||
let authToken: string | null = null;
|
||||
@@ -67,26 +73,24 @@ async function getAuthToken(): Promise<string | null> {
|
||||
// 登录获取新 token
|
||||
authToken = await loginToArtalk();
|
||||
if (authToken) {
|
||||
// Token 有效期设为 24 小时(Artalk 默认较长)
|
||||
// Token 有效期设为 24 小时
|
||||
tokenExpiry = now + 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
return authToken;
|
||||
}
|
||||
|
||||
// 获取所有评论(使用管理员 API)
|
||||
async function fetchLatestComments(): Promise<ArtalkComment[]> {
|
||||
// 获取所有页面
|
||||
async function fetchAllPages(): Promise<ArtalkPage[]> {
|
||||
try {
|
||||
const token = await getAuthToken();
|
||||
if (!token) {
|
||||
console.error("[comment-notify] no auth token available");
|
||||
console.error("[comment-notify] no auth token for fetching pages");
|
||||
return [];
|
||||
}
|
||||
|
||||
// 使用管理员 API 获取所有评论
|
||||
const url = `${ARTALK_SERVER}/api/v2/admin/comments?site_name=${encodeURIComponent(ARTALK_SITE)}&limit=5&sort_by=date&sort_order=desc`;
|
||||
console.log("[comment-notify] fetching comments with admin API...");
|
||||
console.log("[comment-notify] URL:", url);
|
||||
const url = `${ARTALK_SERVER}/api/v2/pages?site_name=${encodeURIComponent(ARTALK_SITE)}&limit=200`;
|
||||
console.log("[comment-notify] fetching pages...");
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
@@ -95,31 +99,82 @@ async function fetchLatestComments(): Promise<ArtalkComment[]> {
|
||||
},
|
||||
});
|
||||
|
||||
console.log("[comment-notify] response status:", res.status, res.statusText);
|
||||
if (!res.ok) {
|
||||
console.error("[comment-notify] fetch pages failed:", res.status);
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = await res.json() as { pages?: ArtalkPage[]; count?: number });
|
||||
console.log("[comment-notify] found", data.pages?.length || 0, "pages (total:", data.count || 0, ")");
|
||||
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<ArtalkComment[]> {
|
||||
try {
|
||||
const token = await getAuthToken();
|
||||
if (!token) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const url = `${ARTALK_SERVER}/api/v2/comments?site_name=${encodeURIComponent(ARTALK_SITE)}&page_key=${encodeURIComponent(pageKey)}&limit=5&sort_by=date&sort_order=desc`;
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text().catch(() => "Unable to read response");
|
||||
console.error("[comment-notify] fetch failed:", res.status, res.statusText);
|
||||
console.error("[comment-notify] response body:", errorText);
|
||||
|
||||
// 如果是认证失败,清除 token 以便下次重试
|
||||
if (res.status === 401 || res.status === 403) {
|
||||
console.error("[comment-notify] authentication failed, clearing token");
|
||||
authToken = null;
|
||||
tokenExpiry = 0;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = await res.json() as { comments?: ArtalkComment[] };
|
||||
console.log("[comment-notify] fetched", data.comments?.length || 0, "comments");
|
||||
return data.comments || [];
|
||||
} catch (e) {
|
||||
console.error("[comment-notify] fetch error:", e instanceof Error ? e.message : String(e));
|
||||
if (e instanceof Error && e.stack) {
|
||||
console.error("[comment-notify] error stack:", e.stack.split('\n').slice(0, 5).join('\n'));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有页面的最新评论
|
||||
async function fetchLatestComments(): Promise<ArtalkComment[]> {
|
||||
try {
|
||||
// 1. 获取所有页面
|
||||
const pages = await fetchAllPages();
|
||||
if (pages.length === 0) {
|
||||
console.log("[comment-notify] no pages found");
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log("[comment-notify] checking comments from", pages.length, "pages...");
|
||||
|
||||
// 2. 并行获取每个页面的评论(只查最新的 20 个页面,避免过多请求)
|
||||
const recentPages = pages.slice(0, 20);
|
||||
const promises = recentPages.map(async (page) => {
|
||||
const comments = await fetchCommentsForPage(page.key);
|
||||
return comments;
|
||||
});
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
const allComments: ArtalkComment[] = [];
|
||||
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", recentPages.length, "recent pages");
|
||||
|
||||
return latestComments;
|
||||
} catch (e) {
|
||||
console.error("[comment-notify] fetch error:", e instanceof Error ? e.message : String(e));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user