77 lines
2.0 KiB
TypeScript
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 };
|
|
}
|