Files
erika/app/admin/backend/actions.ts
T

77 lines
2.0 KiB
TypeScript

"use server";
import { revalidateTag } from "next/cache";
const validPlatforms = ["youtube", "roblox", "discord", "tiktok"];
type FollowerFetcher = () => Promise<unknown>;
export async function refetchPlatform(
platform: string
): Promise<{ count: number | null }> {
if (!validPlatforms.includes(platform)) {
throw new Error("Invalid platform");
}
let count: number | null = null;
let tiktokProfile = null;
try {
const mod = (await import(`@/lib/followers/${platform}`)) as Record<string, unknown>;
const fns = Object.entries(mod).filter(
(entry): entry is [string, FollowerFetcher] => typeof entry[1] === "function"
);
// Prefer function with "Count" or "Member" in name
const countFn = fns.find(([name]) => /count|member/i.test(name));
const fn = countFn || fns[0];
if (fn) {
const result = await fn[1]();
if (typeof result === "number") {
count = result;
} else if (result === null) {
count = null;
} else if (
result &&
typeof result === "object" &&
"followerCount" in result &&
(typeof result.followerCount === "number" || result.followerCount === null)
) {
count = result.followerCount;
tiktokProfile = result;
}
}
} catch (err) {
console.error(`Failed to fetch ${platform}:`, err);
throw new Error(`Failed to fetch ${platform}`);
}
// Update Redis cache
try {
const { getRedisClient } = await import("@/lib/redis");
const redis = await getRedisClient();
const cached = await redis.get("erika:follower_counts");
const counts: Record<string, number | null> = cached
? JSON.parse(cached)
: {};
counts[platform] = count;
await redis.set("erika:follower_counts", JSON.stringify(counts), { ex: 3600 });
if (tiktokProfile) {
await redis.set(
"erika:tiktok_profile",
JSON.stringify(tiktokProfile),
{ ex: 3600 }
);
}
} catch {
// Redis unavailable
}
revalidateTag("follower-counts-api", 'max');
return { count };
}