1420
This commit is contained in:
1 parent
9a083b50b4
commit
bf0fae69d6
2 files changed
+84
-6
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
import { ARTALK_SERVER, ARTALK_SITE } from "@/lib/config";
|
import { ARTALK_SERVER, ARTALK_SITE, ARTALK_ADMIN_EMAIL, ARTALK_ADMIN_PASSWORD } from "@/lib/config";
|
||||||
import { sendMessage } from "./tg";
|
import { sendMessage } from "./tg";
|
||||||
import { ALLOWED_IDS } from "./config";
|
import { ALLOWED_IDS } from "./config";
|
||||||
|
|
||||||
@@ -13,22 +13,98 @@ interface ArtalkComment {
|
|||||||
|
|
||||||
let lastCheckedId = 0;
|
let lastCheckedId = 0;
|
||||||
let notifierStarted = false;
|
let notifierStarted = false;
|
||||||
|
let authToken: string | null = null;
|
||||||
|
let tokenExpiry = 0;
|
||||||
|
|
||||||
|
// 登录 Artalk 获取管理员 token
|
||||||
|
async function loginToArtalk(): Promise<string | null> {
|
||||||
|
if (!ARTALK_ADMIN_EMAIL || !ARTALK_ADMIN_PASSWORD) {
|
||||||
|
console.error("[comment-notify] ARTALK_ADMIN_EMAIL or ARTALK_ADMIN_PASSWORD not configured");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取所有评论(使用 type=all 参数)
|
|
||||||
async function fetchLatestComments(): Promise<ArtalkComment[]> {
|
|
||||||
try {
|
try {
|
||||||
// 尝试使用 type=all 参数获取所有评论
|
const url = `${ARTALK_SERVER}/api/v2/auth/email/login`;
|
||||||
const url = `${ARTALK_SERVER}/api/v2/comments?site_name=${encodeURIComponent(ARTALK_SITE)}&type=all&limit=5&sort_by=created_at&sort_order=desc`;
|
console.log("[comment-notify] logging in to Artalk...");
|
||||||
console.log("[comment-notify] fetching comments with type=all...");
|
|
||||||
|
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
email: ARTALK_ADMIN_EMAIL,
|
||||||
|
password: ARTALK_ADMIN_PASSWORD,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
console.error("[comment-notify] login failed:", res.status);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json() as { token?: string; user?: { name: string } };
|
||||||
|
if (!data.token) {
|
||||||
|
console.error("[comment-notify] no token in response");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[comment-notify] logged in as:", data.user?.name || "admin");
|
||||||
|
return data.token;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[comment-notify] login error:", e instanceof Error ? e.message : String(e));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取或刷新 token
|
||||||
|
async function getAuthToken(): Promise<string | null> {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
// Token 有效(提前 5 分钟刷新)
|
||||||
|
if (authToken && now < tokenExpiry - 5 * 60 * 1000) {
|
||||||
|
return authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录获取新 token
|
||||||
|
authToken = await loginToArtalk();
|
||||||
|
if (authToken) {
|
||||||
|
// Token 有效期设为 24 小时(Artalk 默认较长)
|
||||||
|
tokenExpiry = now + 24 * 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有评论(使用管理员 API)
|
||||||
|
async function fetchLatestComments(): Promise<ArtalkComment[]> {
|
||||||
|
try {
|
||||||
|
const token = await getAuthToken();
|
||||||
|
if (!token) {
|
||||||
|
console.error("[comment-notify] no auth token available");
|
||||||
|
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...");
|
||||||
|
|
||||||
|
const res = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const errorText = await res.text().catch(() => "Unable to read response");
|
const errorText = await res.text().catch(() => "Unable to read response");
|
||||||
console.error("[comment-notify] fetch failed:", res.status, res.statusText);
|
console.error("[comment-notify] fetch failed:", res.status, res.statusText);
|
||||||
console.error("[comment-notify] response:", errorText);
|
console.error("[comment-notify] response:", errorText);
|
||||||
|
|
||||||
|
// 如果是认证失败,清除 token 以便下次重试
|
||||||
|
if (res.status === 401 || res.status === 403) {
|
||||||
|
authToken = null;
|
||||||
|
tokenExpiry = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export const RECYCLE_POSTS_DIR = path.join(RECYCLE_DIR, "posts");
|
|||||||
export const RECYCLE_META_DIR = path.join(RECYCLE_DIR, "meta");
|
export const RECYCLE_META_DIR = path.join(RECYCLE_DIR, "meta");
|
||||||
export const ARTALK_SERVER = process.env.ARTALK_SERVER || "https://artalk.usj.cc";
|
export const ARTALK_SERVER = process.env.ARTALK_SERVER || "https://artalk.usj.cc";
|
||||||
export const ARTALK_SITE = process.env.ARTALK_SITE || "优世界";
|
export const ARTALK_SITE = process.env.ARTALK_SITE || "优世界";
|
||||||
|
export const ARTALK_ADMIN_EMAIL = process.env.ARTALK_ADMIN_EMAIL || "";
|
||||||
|
export const ARTALK_ADMIN_PASSWORD = process.env.ARTALK_ADMIN_PASSWORD || "";
|
||||||
export const ITEMS_PER_PAGE = parseInt(process.env.ITEMS_PER_PAGE || "20", 10);
|
export const ITEMS_PER_PAGE = parseInt(process.env.ITEMS_PER_PAGE || "20", 10);
|
||||||
export const RECYCLE_DAYS = parseInt(process.env.RECYCLE_DAYS || "30", 10);
|
export const RECYCLE_DAYS = parseInt(process.env.RECYCLE_DAYS || "30", 10);
|
||||||
export const HUGO_PREVIEW = process.env.NEXT_PUBLIC_HUGO_PREVIEW || process.env.HUGO_PREVIEW || "http://localhost:1313";
|
export const HUGO_PREVIEW = process.env.NEXT_PUBLIC_HUGO_PREVIEW || process.env.HUGO_PREVIEW || "http://localhost:1313";
|
||||||
|
|||||||
Reference in new issue
Block a user