feat: Social con gráficas diarias por periodo y token Meta 4V2030
Series IG/FB (alcance, impresiones, clics, engagement, fans) según el rango del header; Meta y Google quedan como tokens separados. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -31,21 +31,35 @@ export function googleAdsConfigured(): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/** Prefer token saved in agency_oauth (pasted after App Review), else env. */
|
||||
/** Prefer env META_ACCESS_TOKEN (Dokploy / 4V2030), then agency_oauth paste. */
|
||||
export async function resolveMetaAccessToken(): Promise<string | null> {
|
||||
const tokens = await resolveMetaAccessTokens();
|
||||
return tokens[0] || null;
|
||||
}
|
||||
|
||||
/** All candidate Meta tokens (env first — production 4V2030 system user). */
|
||||
export async function resolveMetaAccessTokens(): Promise<string[]> {
|
||||
const out: string[] = [];
|
||||
const env = process.env.META_ACCESS_TOKEN?.trim();
|
||||
if (env) out.push(env);
|
||||
|
||||
const headers = serviceHeaders();
|
||||
if (headers) {
|
||||
const r = await fetch(
|
||||
`${supabaseUrl()}/rest/v1/agency_oauth?provider=eq.${META_OAUTH_PROVIDER}&select=access_token`,
|
||||
{ headers, cache: 'no-store' }
|
||||
);
|
||||
if (r.ok) {
|
||||
const rows = (await r.json()) as { access_token?: string }[];
|
||||
const t = rows[0]?.access_token?.trim();
|
||||
if (t) return t;
|
||||
try {
|
||||
const r = await fetch(
|
||||
`${supabaseUrl()}/rest/v1/agency_oauth?provider=eq.${META_OAUTH_PROVIDER}&select=access_token`,
|
||||
{ headers, cache: 'no-store' }
|
||||
);
|
||||
if (r.ok) {
|
||||
const rows = (await r.json()) as { access_token?: string }[];
|
||||
const t = rows[0]?.access_token?.trim();
|
||||
if (t && !out.includes(t)) out.push(t);
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return process.env.META_ACCESS_TOKEN?.trim() || null;
|
||||
return out;
|
||||
}
|
||||
|
||||
export async function metaConfigured(): Promise<boolean> {
|
||||
|
||||
Reference in New Issue
Block a user