feat: connect Google My Business and LinkedIn metrics via Windsor.ai API

This commit is contained in:
Marcos Fargas
2026-10-05 00:53:10 +02:00
parent 12f9c3cd1e
commit 777c4f9dfa

View File

@@ -86,10 +86,6 @@ export async function GET() {
K.src.gsc.m.clk[idx] = row.gsc_clicks; K.src.gsc.m.clk[idx] = row.gsc_clicks;
K.src.gsc.m.imp[idx] = row.gsc_impressions; K.src.gsc.m.imp[idx] = row.gsc_impressions;
K.src.gsc.m.posw[idx] = row.gsc_avg_position; K.src.gsc.m.posw[idx] = row.gsc_avg_position;
K.src.gbp.m.imp[idx] = row.gbp_impressions;
K.src.gbp.m.call[idx] = row.gbp_calls;
K.src.gbp.m.web[idx] = row.gbp_website_clicks;
K.src.gbp.m.dir[idx] = row.gbp_directions;
} }
} }
@@ -125,6 +121,52 @@ export async function GET() {
}); });
} }
// Fetch Windsor Google My Business & LinkedIn data in parallel
const WINDSOR_API_KEY = process.env.WINDSOR_API_KEY || 'e264872c03ed4af5b160e3480b7618d11723';
try {
const [gmbRes, liRes] = await Promise.allSettled([
fetch(
`https://connectors.windsor.ai/google_my_business?api_key=${WINDSOR_API_KEY}&date_from=${startStr}&date_to=${endStr}&fields=date,impressions,call_clicks,website_clicks,direction_requests`,
{ signal: AbortSignal.timeout(8000) }
).then((r) => r.json()).catch(() => null),
fetch(
`https://connectors.windsor.ai/linkedin_organic?api_key=${WINDSOR_API_KEY}&date_from=${startStr}&date_to=${endStr}&fields=date,impressions,clicks,engagement,followers`,
{ signal: AbortSignal.timeout(8000) }
).then((r) => r.json()).catch(() => null),
]);
const gmbData = gmbRes.status === 'fulfilled' ? gmbRes.value : null;
const liData = liRes.status === 'fulfilled' ? liRes.value : null;
if (gmbData?.data && Array.isArray(gmbData.data)) {
for (const row of gmbData.data) {
if (!row.date || row.date < startStr || row.date > endStr) continue;
const idx = getIdx(row.date);
if (idx >= 0 && idx < daysCount) {
if (row.impressions != null) K.src.gbp.m.imp[idx] = Number(row.impressions);
if (row.call_clicks != null) K.src.gbp.m.call[idx] = Number(row.call_clicks);
if (row.website_clicks != null) K.src.gbp.m.web[idx] = Number(row.website_clicks);
if (row.direction_requests != null) K.src.gbp.m.dir[idx] = Number(row.direction_requests);
}
}
}
if (liData?.data && Array.isArray(liData.data)) {
for (const row of liData.data) {
if (!row.date || row.date < startStr || row.date > endStr) continue;
const idx = getIdx(row.date);
if (idx >= 0 && idx < daysCount) {
if (row.impressions != null) K.src.li.m.imp[idx] = Number(row.impressions);
if (row.clicks != null) K.src.li.m.clk[idx] = Number(row.clicks);
if (row.engagement != null) K.src.li.m.eng[idx] = Number(row.engagement);
if (row.followers != null) K.src.li.m.fol[idx] = Number(row.followers);
}
}
}
} catch (err) {
console.error('Error fetching Windsor connectors:', err);
}
// Map published Instagram posts for 'Publicado' tab // Map published Instagram posts for 'Publicado' tab
const posts = (igCache?.posts || []).map((p: any) => { const posts = (igCache?.posts || []).map((p: any) => {
let t = 'I'; let t = 'I';