Un ambiente di lavoro in cui l’agente che si occupa delle vostre campagne Google Ads e Meta legge i report, propone il cambiamento con il motivo scritto ed esegue solo entro i limiti che gli avete dato.
Il servizio è un'offerta, non una realizzazione, e lo diciamo per primi: oggi non abbiamo un sistema che cambia budget o aste in Google Ads o Meta. Abbiamo costruito e messo in funzione i pezzi con cui si fa uno — l'invio del segnale di conversione reale a Google, un motore che acquista promozione a pagamento con dry-run attivato di default, un registro che scrive ogni azione che costa, e un interruttore che ferma un orchestrator senza via di aggiramento.
Offerta, con condizioni„offer”, non „delivered”, e il motivo si può verificare in pochi secondi. Abbiamo cercato in oltre 150 repository propri i campi attraverso i quali le API pubblicitarie muovono denaro — `budget_micros`, `campaignBudget`, `target_cpa`, `target_roas`, `bid_strategy` — e non compaiono da nessuna parte, né in Google né in Meta. Oggi non gestiamo budget pubblicitari. Ciò che compare, e si può aprire file per file, sono i pezzi che separano un’automazione da un incidente: l’invio delle conversioni offline a Google tramite Data Manager API, 264 righe in un nostro progetto di produzione; un motore di promozione a pagamento che acquista booster, etichette e pacchetti con dry-run attivato per impostazione predefinita; un A/B tester bayesiano che rifiuta di dichiarare un vincitore sotto 100 visualizzazioni per variante, e l’orchestratore di campagne in MEGA CRM con interruttore senza `--force`. Il servizio è descritto da questi pezzi. Non da un pannello che non esiste.
Un agente che si occupa di campagne non è un pulsante su cui c’è scritto «ottimizza». È un programma che ha il permesso di leggere certi report, il permesso di scrivere certi campi e nessun altro permesso. La parte difficile non è proporre un cambiamento — i modelli lo fanno bene e in fretta. La parte difficile è scrivere dove si ferma, come dimostra ciò che ha fatto, e cosa succede quando sbaglia. Di questo tratta il lavoro, e da lì iniziamo la discussione.
Diciamo da subito ciò che non abbiamo, così non lo saprete da altri. Oggi da noi non gira un sistema che alza un budget in Google Ads o che cambia un’offerta in Meta. Ciò che gira, e si può mostrare riga per riga, sono i meccanismi di sicurezza che abbiamo scritto per altre automazioni che spendono denaro reale: dry-run attivo per impostazione predefinita, contatore per ogni azione a pagamento, temporizzazione in caso di errore per non ripetere l’errore in loop, soglia di prova prima di una decisione, e un interruttore che rifiuta di avviare l’orchestratore.
Il pezzo che abbiamo già costruito non è una modifica di budget, ma un segnale — ed è quello da cui proponiamo di iniziare. Google impara da ciò che gli dite essere una conversione. Se gli dite «modulo inviato», cercherà persone che inviano moduli. Abbiamo scritto l’integrazione che gli dice «richiesta arrivata realmente nel sistema del cliente», con l’identificatore del clic e con gli identificatori utente passati tramite SHA-256, tramite Data Manager API. Questo si può iniziare subito, perché è codice esistente, non una promessa.
Il resto dell’ambiente di lavoro — lo strato che legge i report, lo strato che propone, lo strato che esegue — si costruisce con lo stesso schema che abbiamo usato dove abbiamo già speso denaro tramite codice. Si inizia rigorosamente con la sola lettura, si passa a proposte senza esecuzione, e solo alla fine si apre l’esecuzione, campo per campo, con un limite scritto su ciascuno.
Cosa comprende
Il lavoro, per componenti
Legge i report, non la dashboard
Si stabilisce fin dall’inizio cosa legge l’agente e da dove: spesa per campagna e per gruppo di annunci, conversioni attribuite, costo per acquisizione, quota di impressioni persa per budget rispetto a quella persa per posizione — due cifre diverse che richiedono decisioni diverse. La lettura avviene tramite API, con un account di servizio separato, non tramite screenshot dell’interfaccia. Lo strato di lettura viene consegnato e avviato per primo, da solo, senza alcun permesso di scrittura sull’account.
Propone il cambiamento con il motivo scritto accanto
Una proposta non è una cifra. È il campo che cambia, il valore vecchio, il valore nuovo, la finestra di dati su cui si è presa la decisione, e il perché. Le proposte vengono raccolte in un report che legge una persona, nella forma «aumenterei il budget giornaliero della campagna X da A a B perché negli ultimi N giorni è stata limitata dal budget nel M% delle aste, a un costo per acquisizione sotto la soglia concordata». Se il motivo non si può scrivere, la proposta non si fa.
Tre soglie: cosa fa da solo, cosa richiede una persona, cosa non fa mai
Ogni campo rientra in una di tre categorie, scritte prima di avviare qualcosa. Da solo: modifiche sotto una percentuale concordata, all’interno di un tetto giornaliero, su campagne contrassegnate come aperte. Con approvazione: qualsiasi superamento del tetto, qualsiasi nuova campagna, qualsiasi nuovo pubblico, qualsiasi modifica di offerta. Mai: l’arresto di una campagna che non ha avviato lui, la modifica del metodo di pagamento, l’intervento sugli account di fatturazione. L’elenco si scrive nel contratto, non nel codice, e il codice lo legge.
Dry-run attivo per impostazione predefinita — lo schema che portiamo con noi
Nel nostro motore di promozione a pagamento di 999.md, la funzione che decide se spendere denaro è scritta al contrario rispetto a come di solito viene scritta: dry-run è attivo se la variabile d’ambiente non ha esattamente il valore `false`. Non impostata, vuota, `true`, scritta in modo errato — tutto mantiene dry-run attivo. È una scelta deliberata: un errore di configurazione non può aprire il rubinetto, può solo tenerlo chiuso. La stessa funzione esiste in due punti indipendenti, il motore di promozione e l’esecutore di ripubblicazione.
Ogni azione che costa viene scritta in un registro
Nel sistema di promozione, ogni esecuzione entra in una tabella `agent_costs` con l’annuncio, l’utente, il tipo di azione, l’importo in lei, se è riuscita, la risposta grezza del fornitore e un contrassegno `dry_run`. La scrittura avviene nella stessa transazione dell’aggiornamento della programmazione, quindi non può esistere una spesa senza traccia o una traccia senza spesa. Quando è dry-run, l’importo registrato è zero, ma la riga esiste — si vede esattamente cosa sarebbe successo.
Il segnale di conversione reale — il pezzo che esiste già
Quando qualcuno arriva da un click a pagamento e invia una richiesta, il segnale viene inviato a Google solo dopo che la richiesta entra nel sistema del cliente, non alla pressione del pulsante. L'integrazione usa `https://datamanager.googleapis.com/v1/events:ingest`, invia l'identificatore del click, il momento, il valore e la valuta, più gli identificatori utente passati tramite SHA-256 — l'indirizzo normalizzato in minuscolo, il telefono portato al formato internazionale. Senza l'identificatore del click, l'invio si interrompe da solo ed è segnato come saltato, perché non sarebbe attribuibile.
Il consenso si mette prima delle etichette, non dopo
Consent Mode v2 si inizializza con tutti gli scopi di marketing e analisi su `denied`, prima che qualsiasi script Google si avvii, con una finestra di attesa di 500 ms per l'aggiornamento. Si passa a `granted` solo all'interazione della persona con il banner, senza ricaricare la pagina. La memorizzazione funzionale e quella di sicurezza restano attive, perché senza di esse la pagina non funziona. È scritto una volta e viene eseguito a ogni visita.
La decisione tra due varianti si prende sulla base delle prove, non dell'impressione
Il tester A/B che abbiamo costruito modella ogni variante come Beta-Binomial con prior uniforme e stima la probabilità che una sia migliore tramite 10.000 campioni Monte Carlo. Non dichiara un vincitore sotto 100 visualizzazioni per variante e sotto una probabilità di 0,95. Se dopo 168 ore non si è deciso, chiude l'esperimento e dice che è scaduto, invece di nominare un vincitore che non può sostenere.
Un interruttore che non si può aggirare
L'orchestratore di campagne nel nostro sistema interno verifica una variabile d'ambiente prima di qualsiasi cosa. Se è impostata, rifiuta di avviarsi — non esiste `--force`, non esiste argomento che la superi. È stato aggiunto dopo un incidente reale di invii duplicati, non come decorazione. Lo stesso schema si applica anche qui: un commutatore a livello di account che interrompe tutte le scritture, lasciando proseguire la lettura e la reportistica.
Come si presenta
Il percorso, passo dopo passo.
01
L'inventario degli account e dei diritti
Si elencano gli account pubblicitari, chi ha accesso oggi e con quale ruolo, quali conversioni sono definite e quali di esse sono in realtà duplicati dello stesso evento. Si stabiliscono le tre liste di campi — da solo, con approvazione, mai. Consegniamo: l'inventario scritto, la lista delle conversioni con ciò che misura davvero ciascuna, e l'accordo sulle tre liste.
02
Il livello di lettura, avviato da solo
La lettura via API viene collegata con un account che non ha diritto di scrittura, e si avvia il rapporto giornaliero. In questa fase non cambia nulla negli account — si vede solo ciò che vede l'agente. È il momento in cui emergono le conversioni che contavano male, le campagne limitate dal budget senza che nessuno lo sapesse, e i pubblici che si sovrappongono. Consegniamo: il rapporto giornaliero e la lista di ciò che abbiamo trovato leggendo.
03
Il segnale di conversione reale
Si acquisisce l’identificatore del clic sulla pagina di destinazione, lo si collega alla richiesta nel vostro sistema e lo si invia verso Google solo quando la richiesta è confermata a valle, non alla pressione del pulsante. Si avvia il nuovo tentativo per gli invii non riusciti, nella finestra di 90 giorni. Consegniamo: l’integrazione funzionale, una modalità di verifica che invia senza registrare, e il registro con ciò che è partito, ciò che è stato saltato e perché.
04
Il livello delle proposte, senza esecuzione
L'agente inizia a scrivere proposte: campo, valore vecchio, valore nuovo, motivo, finestra di dati. Non si esegue nulla. Si va avanti così finché le proposte diventano noiose — cioè finché la persona che le legge avrebbe premuto comunque "sì" su quasi tutte. Consegniamo: il flusso delle proposte, con tutto ciò che è stato proposto e ciò che avete approvato o respinto, per vedere dove sbaglia.
05
L'apertura dell'esecuzione, campo per campo
Si apre l'esecuzione per il primo campo dell'elenco "da solo", con dry-run attivato per impostazione predefinita e con tetto giornaliero. Si verifica nel registro che ciò che è stato scritto sia ciò che è stato proposto. Poi il secondo campo. Consegniamo: il registro delle azioni, l'interruttore che interrompe tutte le scritture lasciando attiva la lettura, e la procedura scritta per cosa fare quando l'agente ha sbagliato.
Il percorso di una decisione
I dati
Cosa tocchiamo, dove risiedono e quanto rimangono
Le domande che pone chiunque abbia un responsabile della protezione dei dati — poste qui prima che le ponga lui.
Quali dati raggiunge
Report di campagna, gruppo di annunci e parola chiave letti tramite API. L’identificatore di clic dell’annuncio, acquisito dall’indirizzo della pagina di destinazione e conservato sulla richiesta del cliente. Eventi di conversione con momento, valore e valuta. Su richiesta esplicita, l’indirizzo email e il telefono della persona che ha convertito, ma solo sotto forma di digest crittografico.
Cosa parte verso Google e in che forma
L’identificatore del clic parte in chiaro — è questo, un identificatore di click. L’email e il telefono partono solo come SHA-256, calcolato localmente prima dell’invio: l’email pulita dagli spazi e convertita in minuscolo, il telefono portato al formato internazionale. L’indirizzo postale non viene inviato affatto, perché lo schema Google lo richiede completo di codice postale e codice di regione, e il codice postale non è coerente nei dati reali — il motivo è scritto nel codice, non supposto.
Dove stanno e chi li vede
I dati di campagna e gli eventi stanno nel database del vostro progetto, sull’infrastruttura concordata. Le credenziali degli account pubblicitari stanno in un file di ambiente letto dal servizio di sistema, non nel codice e non nel repository sorgente. Il token di accesso si tiene in memoria al massimo 55 minuti, sebbene il fornitore lo fornisca valido per 3.600 secondi — il margine è intenzionale, così da non usare mai uno scaduto.
Per quanto tempo può ancora essere inviato un evento
La finestra pratica è di 90 giorni dal momento della conversione — questo è quanto Google accetta per le conversioni offline. Il ritentativo per gli invii falliti opera esattamente in questa finestra, in batch, con al massimo cinque tentativi per richiesta. Dopo cinque tentativi, la richiesta viene lasciata in pace e rimane marcata come non inviata, invece di essere ritentata all’infinito.
Cosa non facciamo con i dati
Non costruiamo pubblici dalle vostre liste clienti senza una base giuridica scritta e senza che compaiano nell’informativa che la persona vede. Non passiamo dati tra gli account di due clienti diversi. Non conserviamo copie dei report di campagna fuori dal sistema concordato. Il registro dei trattamenti si completa prima del primo invio, non dopo.
Un caso
Una campagna che pagava per i moduli, non per le richieste
La situazione
Una piattaforma di Chișinău che riceve richieste online comprava traffico dalla ricerca. La conversione definita nell’account pubblicitario era «modulo inviato». L’algoritmo di bidding faceva esattamente ciò che gli veniva richiesto: portava persone che inviano moduli. Quante di esse diventavano richieste reali, più avanti nella catena, non tornava mai alla piattaforma pubblicitaria.
Cosa abbiamo costruito
Abbiamo spostato il momento della conversione più avanti nella catena. L’identificatore del clic si acquisisce sulla pagina di destinazione e si conserva sulla richiesta. La richiesta prosegue verso il sistema a valle; se questo restituisce un identificatore proprio — cioè è entrata davvero — solo allora parte l’evento verso Google, tramite Data Manager API, con il momento, il valore, la valuta e identificatori utente passati tramite SHA-256. Senza identificatore di clic, l’invio si ferma da solo e viene marcato come saltato. Abbiamo aggiunto un job di nuovo tentativo che cerca le richieste con identificatore di clic e senza marcatura di invio, negli ultimi 90 giorni, in lotti da 50, con al massimo cinque tentativi.
Cosa è emerso
Il segnale che riceve la piattaforma pubblicitaria descrive ora le richieste che arrivano a destinazione, non i clic sui pulsanti. Tutte le operazioni sono inattive se l’integrazione non è configurata o è disattivata — la funzione verifica tutte e sette le credenziali prima di qualsiasi cosa, e restituisce «saltato» se ne manca una. Gli errori vengono registrati, ma non si propagano: se Google non risponde, la richiesta del cliente prosegue intatta.
Cosa non dice il caso
Questa è un’integrazione di segnale, non di gestione della campagna. Non modifica alcun budget e alcuna offerta. L’effetto sul costo per acquisizione non è stato misurato da noi e non lo pubblichiamo — nel codice esiste un’aspettativa scritta dall’autore, non una misurazione, e tra le due c’è tutta la differenza.
Domande
Cosa ci chiedono le persone prima di chiamare
Chi si assume la responsabilità quando l’agente aumenta un budget e la spesa sale?
Voi. Ed è per questo che l’ambiente è costruito in modo che possiate assumervi la responsabilità con cognizione di causa, non per sorprendervi. In concreto: l’agente non ha alcuna autorizzazione di scrittura che qualcuno non gli abbia dato per nome, per iscritto, campo per campo; ogni campo aperto ha un tetto oltre il quale la proposta va ad approvazione umana; ogni azione eseguita viene scritta in un registro con il valore vecchio, il valore nuovo e il motivo, nella stessa transazione dell’esecuzione; ed esiste un interruttore che arresta tutte le scritture senza arrestare la lettura. Noi rispondiamo di ciò che abbiamo costruito — che i limiti che avete scritto sono rispettati dal codice, che il registro è completo, che l’arresto funziona. Non rispondiamo del risultato commerciale di una modifica che avete approvato, così come non ne risponde neppure l’agenzia che preme il pulsante manuale. Se qualcuno vi promette altro, chiedetegli cosa scrive il contratto nel capitolo limitazione di responsabilità.
Oggi avete un sistema che gestisce campagne Google Ads o Meta?
No. Da nessuna parte nel nostro codice compare un campo tramite cui si cambia un budget, un’asta o una strategia di offerta su Google o su Meta. Abbiamo verificato cercando esattamente quei nomi di campo in tutti i repository. Ciò che abbiamo è l’invio delle conversioni a Google, un motore che acquista promozione a pagamento su un’altra piattaforma, e i meccanismi di sicurezza attorno ad essi. Il servizio si costruisce partendo da lì, ed è marcato come offerta proprio per evitare confusione.
Allora che cosa avete già costruito e sta spendendo denaro reale?
Il nostro motore di promozione a pagamento su una piattaforma di annunci classificati della Moldova. Appone etichette a pagamento, avvia booster con limite giornaliero e prezzo per clic, attiva pacchetti e ripubblica annunci dopo un intervallo calcolato dalla velocità reale della categoria. Rifiuta di avviare un booster il cui limite giornaliero non sia superiore al prezzo per clic — un controllo piccolo, ma esattamente il tipo di controllo che di solito manca. Ogni azione passa attraverso la verifica di dry-run prima di qualsiasi chiamata che costa.
Che cosa può modificare da solo e che cosa richiede approvazione?
Si decide insieme, in anticipo, e si scrive. Il nostro punto di partenza nella discussione: da solo — adeguamenti inferiori a una percentuale concordata del budget giornaliero, all’interno di un tetto giornaliero assoluto, sulle campagne che avete segnato come aperte; con approvazione — qualsiasi superamento del tetto, nuove campagne, nuovi pubblici, qualsiasi intervento sulle offerte; mai — arresto delle campagne avviate da altri, metodi di pagamento, account di fatturazione. Se all’inizio volete tutto con approvazione, è una scelta valida e noi la preferiamo.
Come sa l’agente che una conversione è reale e non un modulo vuoto?
Perché il segnale non parte alla pressione del pulsante. Parte solo quando la richiesta è confermata a valle, nel sistema che conta per voi — un identificatore di richiesta ricevuto indietro dal CRM o dal partner. Fino ad allora non è accaduto nulla che meriti di essere chiamato conversione. La differenza non è cosmetica: l’algoritmo di offerta di Google impara da ciò che gli inviate, quindi se gli inviate moduli, vi porterà persone che compilano moduli.
Che cosa succede ai dati personali di chi converte?
L’email e il telefono partono solo come riassunto crittografico SHA-256, calcolato localmente prima dell’invio, con normalizzazione — email senza spazi e in minuscolo, telefono portato al formato internazionale. L’indirizzo postale non viene inviato affatto. Nulla parte prima che la persona abbia accettato lo scopo di marketing nel banner, perché Consent Mode parte completamente su `denied`. La base giuridica e l’informativa si scrivono prima del primo invio, non dopo la prima domanda di qualcuno.
Che cosa succede se la chiamata alla piattaforma pubblicitaria si interrompe a metà?
Il fallimento viene registrato con la risposta grezza, e l’azione viene rinviata — nel nostro executor di ripubblicazione, con il massimo tra il raffreddamento configurato e cinque minuti, esplicitamente per non trasformare un errore in un ciclo di chiamate. Gli invii di conversione falliti vengono ritentati tramite un job separato, in batch da 50, con al massimo cinque tentativi per richiesta, nella finestra di 90 giorni. Dopo il quinto tentativo si ferma e resta marcata come non inviata, così da vedersi, non da sparire.
Come lo fermo, completamente e rapidamente?
L’interruttore di scrittura. La lettura e la reportistica continuano, l’esecuzione si ferma. Nei nostri sistemi esistenti questo è implementato in due modi, entrambi verificabili: una variabile di ambiente che deve avere esattamente il valore `false` perché si spenda denaro — qualsiasi altra cosa tiene il rubinetto chiuso — e un interruttore sull’orchestratore delle campagne che rifiuta l’avvio e non ha `--force`. Non dipendiamo da un pulsante in un’interfaccia che potrebbe non caricarsi.
Mi garantite una riduzione del costo per acquisizione?
No, e vale la pena dire perché, perché nel nostro codice esiste esattamente una cifra del genere. Nel commento in testa all’integrazione delle conversioni è scritto un obiettivo — di quanto potrebbe scendere il costo per acquisizione e di quanto potrebbe salire la quota di impressioni. È un obiettivo scritto da chi l’ha costruita, non una misurazione, e per questo non la troverete da nessuna parte su questo sito come risultato. Ciò che possiamo promettervi è che la misurazione sarà possibile: con conversioni che significano qualcosa e con un registro di ogni modifica, il confronto prima-dopo diventa possibile. Senza di esse, non lo è.
Su cosa si basano le affermazioni sopra (20 fonti)
20 di esse sono codice e file dei nostri repository. Non ne pubblichiamo il nome né la riga: insieme, in un'unica pagina, descriverebbero con troppa precisione come sono costruiti sistemi che non sono solo nostri. Le esaminiamo con te, nel repository, su richiesta — la verifica resta possibile, solo che avviene in una discussione.