TL;DR: i webhook della Gemini API permettono di ricevere un evento quando un job asincrono termina, senza interrogare di continuo lo stato dell’operazione. Il vantaggio vero, però, non è eliminare qualche richiesta HTTP. È separare l’esecuzione AI dalla pubblicazione: il listener verifica la firma, registra l’evento, risponde subito e passa il lavoro a una coda. Solo un worker idempotente valida l’output e crea una bozza WordPress. Per una PMI è un’architettura più economica da mantenere e, soprattutto, più difficile da rompere con duplicati, timeout o callback contraffatte.
Il 30 luglio 2026 Google ha aggiornato la documentazione della Gemini API con il supporto ai webhook per job Batch, Interactions e generazione video. Finora molte automazioni gestivano questi processi con polling: avvio del job, attesa, richiesta dello stato, altra attesa, nuova richiesta. Funziona. Ma appena aumentano i job, i tempi o i sistemi coinvolti, quel ciclo diventa una sorgente di rumore operativo.
La novità è utile anche fuori dall’ecosistema Google. Mostra un pattern che vale per qualunque automazione AI collegata a WordPress, CRM, e-commerce o strumenti come n8n e Make: un risultato asincrono non deve entrare direttamente nel CMS. Deve attraversare una piccola macchina a stati, con controlli espliciti e una sola transizione autorizzata.
Cosa cambia tra polling e webhook
Con il polling è il tuo sistema a chiedere: “hai finito?”. Con un webhook è il fornitore a inviare una richiesta HTTP POST al tuo endpoint quando avviene un evento. La documentazione Gemini distingue due configurazioni:
- webhook statici, registrati a livello di progetto e adatti a eventi condivisi, come tutti i batch completati;
- webhook dinamici, associati a una singola richiesta e utili quando job diversi devono finire su endpoint o code differenti.
Il payload è volutamente sottile. Non contiene per forza tutto il risultato del modello: comunica il tipo di evento, l’identificativo del job e un riferimento al file o alla risorsa da recuperare. È una scelta corretta. Una callback deve notificare, non trasportare megabyte di output e tenere aperta la connessione mentre il CMS lavora.
Gemini espone eventi distinti per successo, fallimento, cancellazione e scadenza dei batch. Per le Interactions ci sono anche eventi di completamento e richiesta di azione. Questa granularità permette di smettere di trattare ogni esito come un generico “job finito”.
Il caso pratico: schede prodotto elaborate di notte
Immaginiamo una PMI con WooCommerce e 800 descrizioni prodotto da classificare. Ogni notte esporta le schede modificate, le invia a un job Batch e usa l’AI per proporre categoria, attributi, riassunto e testo alternativo delle immagini. Non è un’attività urgente: può essere eseguita in asincrono.
Con il polling, un workflow resta attivo e controlla lo stato a intervalli regolari. Se il job dura ore, accumula esecuzioni, log e possibili sovrapposizioni. Se il controllo fallisce proprio dopo il completamento, il risultato può restare sospeso fino al tentativo successivo. Se due poller vedono insieme lo stesso stato, entrambi possono avviare l’importazione.
Con il webhook, la parte AI termina il proprio lavoro e invia un evento batch.succeeded. Il listener non aggiorna 800 prodotti. Verifica la richiesta, salva l’identificativo del job, inserisce un messaggio in coda e risponde con un 2xx. Il worker recupera poi il risultato, valida ogni record e crea proposte in bozza.
Questo dettaglio conta: “job completato” non significa “contenuto pubblicabile”. Significa soltanto che l’elaborazione del fornitore è arrivata a uno stato terminale.
L’architettura minima che userei
Per una PMI non serve costruire una piattaforma distribuita. Servono cinque blocchi con responsabilità chiare.
- Job creator. Prepara input e metadati, avvia l’operazione asincrona e registra un identificativo interno.
- Webhook listener. Riceve il corpo grezzo, verifica firma e timestamp, controlla l’evento e risponde in pochi secondi.
- Registro eventi. Salva
webhook-id, job, tipo evento, data e stato di elaborazione. È la base per deduplicazione e audit. - Coda e worker. Recuperano il risultato fuori dalla richiesta HTTP, applicano retry controllati e aggiornano la macchina a stati.
- Adapter WordPress. Valida i dati e usa un account tecnico con permessi minimi per creare una bozza, mai per pubblicare direttamente.
Il punto più importante è il registro. I webhook hanno consegna at least once: lo stesso evento può arrivare più di una volta. Non è un’anomalia da sperare di non vedere. È parte del contratto. Prima di mettere un messaggio in coda, il listener deve verificare se quel webhook-id è già stato accettato.
received -> verified -> queued -> fetched -> validated -> draft_created
\-> rejected
\-> retryable_error
\-> manual_review
Una tabella con vincolo univoco sull’ID dell’evento basta per molte implementazioni. Se l’inserimento fallisce perché l’ID esiste già, si restituisce comunque un successo: il duplicato è già stato preso in carico.
Sicurezza: la callback non è una prova
Un endpoint pubblico riceverà richieste da Internet. Il fatto che il JSON contenga batch.succeeded non dimostra che l’abbia inviato Gemini. Per i webhook statici Google segue la specifica Standard Webhooks e fornisce un signing secret quando si crea l’endpoint. Quel segreto viene mostrato una sola volta e va conservato fuori dal codice e dal repository.
La verifica deve usare il corpo HTTP grezzo. Se un framework converte il JSON in un oggetto e poi lo serializza di nuovo, spazi, ordine o codifica possono cambiare e invalidare la firma. La sequenza corretta è:
- leggere il body senza modificarlo;
- verificare la firma con una libreria compatibile con Standard Webhooks;
- controllare
webhook-timestampe rifiutare eventi più vecchi di cinque minuti; - deduplicare tramite
webhook-id; - registrare l’evento e rispondere subito;
- analizzare il payload nella coda, non dentro il listener.
Gemini ritenta le consegne fallite per 24 ore con backoff esponenziale. Un listener che esegue chiamate AI, scarica file e scrive su WordPress prima di rispondere aumenta quindi il rischio di timeout e duplicati. La callback deve restare piccola.
I webhook dinamici usano invece firme JWT verificate tramite le chiavi pubbliche JWKS di Google. Non conviene tradurre a mano un esempio statico in dinamico: cambia il modello di verifica. Prima va scelto il tipo di webhook, poi va implementato il contratto corrispondente.
Come collegarlo a WordPress senza dare le chiavi del sito all’AI
Il modello non deve conoscere la password WordPress e il webhook non deve possedere un account amministratore. WordPress include le Application Passwords per accessi API: sono credenziali revocabili, legate a un singolo utente e separate dalla password principale. La documentazione ufficiale raccomanda una credenziale per integrazione, uso esclusivo su HTTPS e rotazione o revoca quando non serve più.
Creerei un utente tecnico con il ruolo minimo necessario. Se il workflow deve soltanto produrre proposte, la destinazione è status=draft. La pubblicazione resta una transizione distinta, autorizzata solo dopo controlli editoriali o approvazione umana.
Prima della chiamata REST, il worker deve validare uno schema rigido: campi ammessi, lunghezze, tassonomie, URL e formati. È lo stesso principio descritto nella guida su come validare l’output AI in JSON prima di WordPress. Il modello propone dati; il codice decide se sono accettabili.
La creazione della bozza dovrebbe memorizzare anche l’ID esterno del job. In questo modo un retry può cercare la bozza già creata prima di inserirne un’altra. Per i contenuti editoriali, aggiungerei poi un gate simile a quello usato per le bozze AI in WordPress: fact-check, preview, controlli SEO e approvazione prima del go-live.
Una migrazione in sette passaggi
Non spegnerei il polling il giorno in cui attivo il primo webhook. Procederei per fasi.
- Mappare gli stati reali. Elencare successo, errore, cancellazione, scadenza e azione manuale. Ogni stato deve avere un comportamento.
- Definire una chiave idempotente. Per esempio
provider + job_id + event_type, oltre alwebhook-id. - Costruire il listener passivo. Verifica e registra gli eventi, ma non esegue ancora azioni sul CMS.
- Confrontare webhook e poller. Per alcuni giorni misurare se entrambi osservano lo stesso stato terminale.
- Attivare il worker. Il webhook diventa il percorso principale; il polling resta un controllo di riconciliazione a bassa frequenza.
- Provare duplicati e ritardi. Reinviare lo stesso evento, simulare un worker fermo e verificare che non nascano doppie bozze.
- Ridurre il polling. Mantenerlo solo come rete di sicurezza, con una finestra ampia e un alert sulle operazioni bloccate.
Il confronto temporaneo non è spreco. È il modo più economico per dimostrare che il nuovo percorso copre gli esiti del vecchio senza perdere job.
Metriche che dicono se il sistema funziona
Contare le richieste HTTP risparmiate è utile, ma non basta. Monitorerei almeno questi segnali:
- tempo tra stato terminale del job e accettazione del webhook;
- percentuale di eventi duplicati, con conferma che non producano doppie azioni;
- tempo in coda e numero di retry del worker;
- job completati senza una transizione interna entro una soglia;
- output respinti dalla validazione;
- bozze WordPress create, approvate e scartate;
- eventi con firma o timestamp non validi.
Il polling resta sensato per prototipi con pochi job brevi, oppure come riconciliazione periodica. Se l’operazione dura secondi e il processo chiamante deve comunque attendere, introdurre endpoint, coda e registro può essere eccessivo. Ma per batch notturni, video, importazioni e workflow che attraversano più sistemi, il webhook riduce l’accoppiamento e rende visibili gli stati.
La mia take: il webhook non rende affidabile l’automazione
Il webhook cambia chi inizia la conversazione. Non risolve da solo duplicati, permessi, output malformati o pubblicazioni premature. Un callback collegato direttamente a wp_insert_post() è soltanto un poller più veloce con una superficie d’attacco pubblica.
L’unità da progettare non è la callback. È la transizione di stato: verificata, registrata, idempotente e reversibile. Se questa parte è solida, il fornitore AI può cambiare e l’adapter WordPress resta piccolo. È lo stesso motivo per cui MCP e REST vanno scelti in base al confine operativo, non alla moda del momento.
Cosa fare lunedì mattina
- Scegliere un solo job asincrono non urgente.
- Disegnare stati ed errori prima dell’endpoint.
- Creare un listener che verifica firma, timestamp e duplicati.
- Mettere il lavoro in coda e rispondere subito con
2xx. - Far creare al worker una bozza WordPress, non un contenuto live.
- Mantenere un controllo di riconciliazione finché i log non dimostrano che il flusso è completo.
Se il progetto non riesce a distinguere un evento ricevuto da un’azione completata, non è ancora pronto per togliere il polling. Prima si sistema lo stato. Poi si accelera.

