import redis from '../redis.js'; import { getCredential, type Platform } from './credential-store.js'; const HEALTH_TTL = 600; // 10 minutes type HealthStatus = 'healthy' | 'expired' | 'disconnected' | 'unknown'; interface PlatformHealth { platform: Platform; status: HealthStatus; } const OAUTH_PLATFORMS: Platform[] = ['linkedin', 'twitter', 'tiktok', 'instagram', 'facebook', 'snapchat']; const ALL_PLATFORMS: Platform[] = ['email', 'whatsapp', 'linkedin', 'telegram', 'discord', 'instagram', 'twitter', 'tiktok', 'snapchat', 'facebook', 'obsidian']; async function checkPlatformHealth(customerId: string, platform: Platform): Promise { const cacheKey = `health:${customerId}:${platform}`; const cached = await redis.get(cacheKey); if (cached) return cached as HealthStatus; const cred = await getCredential(customerId, platform); let status: HealthStatus; if (!cred) { // getCredential returns null for both "not stored" and "expired with no refresh" // Check if there was a stored (but expired) credential by looking at the raw key const rawKey = `creds:${customerId}:${platform}`; const raw = await redis.get(rawKey); status = raw ? 'expired' : 'disconnected'; } else if (OAUTH_PLATFORMS.includes(platform)) { // Credential exists and is not expired — probe the API status = await probeOAuthPlatform(platform, cred as { accessToken: string }); } else { status = 'healthy'; } await redis.setEx(cacheKey, HEALTH_TTL, status); return status; } async function probeOAuthPlatform(platform: Platform, cred: { accessToken: string }): Promise { const probeUrls: Partial> = { linkedin: 'https://api.linkedin.com/v2/userinfo', twitter: 'https://api.twitter.com/2/users/me', tiktok: 'https://open.tiktokapis.com/v2/user/info/?fields=open_id', instagram: 'https://graph.instagram.com/me?fields=id', facebook: 'https://graph.facebook.com/me?fields=id', snapchat: 'https://adsapi.snapchat.com/v1/me', }; const url = probeUrls[platform]; if (!url) return 'unknown'; try { const res = await fetch(url, { headers: { Authorization: `Bearer ${cred.accessToken}` }, signal: AbortSignal.timeout(8000), }); return res.ok ? 'healthy' : 'expired'; } catch { return 'unknown'; } } export async function getAllPlatformHealth(customerId: string): Promise { return Promise.all( ALL_PLATFORMS.map(async (platform) => ({ platform, status: await checkPlatformHealth(customerId, platform), })) ); }