Quote Pinnacle in Supabase con un'Edge Function
Risposta: tieni la chiave API come secret Supabase, scrivi un'Edge Function che chiama GET /v1/drops (o /v1/odds) e fa upsert tramite il client admin @supabase/server, poi lascia che pg_cron + pg_net la chiamino ogni minuto con una chiave in Vault. Le Edge Function sono brevi — è polling REST, non un listener WebSocket. Funziona su Free (ritardo 30 s, 2 sport) e in tempo reale da Hobby.
1. Tabella#
create table if not exists pinnacle_drops (
event_id bigint, market_id text, outcome text,
price_from numeric, price_to numeric, drop_pct numeric,
moved_at timestamptz, home text, away text,
primary key (market_id, outcome, moved_at)
);
2. Secret#
supabase secrets set PINNFEED_KEY=ps_live_your_key
3. Function supabase/functions/pinnfeed-drops/index.ts#
import { withSupabase } from 'npm:@supabase/server@1';
// auth: 'secret' accepts only callers that send your project's secret key on the apikey header
export default {
fetch: withSupabase({ auth: 'secret' }, async (_req, ctx) => {
const r = await fetch('https://pinnfeed.io/v1/drops?sport=soccer&minutes=5&min_pct=3&limit=100', {
headers: { 'x-api-key': Deno.env.get('PINNFEED_KEY')! },
});
if (!r.ok) return new Response(await r.text(), { status: r.status });
const { drops } = await r.json();
const rows = drops.map((d: any) => ({
event_id: d.eventId, market_id: d.marketId, outcome: d.outcome,
price_from: d.from, price_to: d.to, drop_pct: d.dropPct,
moved_at: d.movedAt, home: d.home, away: d.away,
}));
const { error } = await ctx.supabaseAdmin.from('pinnacle_drops').upsert(rows, { ignoreDuplicates: true });
return Response.json({ saved: rows.length, error: error?.message ?? null });
}),
};
4. Deploy#
Deploy della funzione, URL progetto e service role in Vault, pg_cron con net.http_post ogni minuto (auth apikey). Dettagli cron: doc EN Supabase Edge. Correlato: Cloudflare Worker, CORS.
CTA#
Builder (99 €/mese). Prova 3 giorni; carta richiesta. REST gratis: signup.
Domande frequenti#
Si può streamare il WebSocket da un'Edge Function?#
No — troppo breve. Polling REST qui; WS su server long-running (Builder).
Free basta?#
Sì per prototipare (ritardo 30 s, 2 sport, 1.000/giorno).
Contenuto educativo per adulti?#
Sì (18+).
Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.