Perché il ROAS è una metrica sopravvalutata nel digital marketing
Responsive Search Ads incompleti: come smettere di ignorarli
15 Gennaio 2026
I Responsive Search Ads sono un formato “gentile” solo in apparenza. Google ti dice: “scrivi fino a 15 titoli e 4 descrizioni, poi ci penso io a combinare tutto”. E tu pensi: ok, perfetto, lo farò… appena ho tempo. Poi passano settimane. Cambi campagne, apri nuovi gruppi, duplichi annunci, fai A/B test. Entra un collega, esce un collega e nel frattempo alcuni RSA restano con 8 titoli e 2 descrizioni, come una valigia chiusa con lo scotch: funziona?… forse, ma non è esattamente il massimo.
Il problema è che questa incompletezza non fa rumore, non manda [sempre] notifiche. Semplicemente performa sotto potenziale. E tu te ne accorgi solo quando inizi a guardare gli annunci uno per uno (cioè: mai). Da qui nasce questo script: una piccola sentinella che gira nell’account e applica un’etichetta dove serve, senza fare danni collaterali.
Lo script
/**
* Google Ads Script
* Label "INCOMPLETO" su Responsive Search Ads (RSA) attivi che hanno:
* - < 15 titoli OR < 4 descrizioni
* In campagne ENABLED + ad group ENABLED + ad ENABLED.
*
* Ogni run (LIVE):
* 1) rimuove SOLO la label INCOMPLETO da tutto ciò che la possiede
* 2) ricalcola e riapplica la label solo agli incompleti
*
* In PREVIEW:
* - non crea label
* - non rimuove / applica label
* - fa solo scan e log dei conteggi
* - Copyright SDB srl 2026
*/
// =====================
// CONFIG
// =====================
var LABEL_INCOMPLETO = "INCOMPLETO";
var PREVIEW_ONLY = true; // true = preview (solo log) | false = live (applica davvero)
var MIN_HEADLINES = 15;
var MIN_DESCRIPTIONS = 4;
function main() {
// 0) Recupero label (in preview NON la creo)
var label = PREVIEW_ONLY
? getLabelIfExists_(LABEL_INCOMPLETO)
: getOrCreateLabelLive_(LABEL_INCOMPLETO);
// 1) RESET: rimuove SOLO la label INCOMPLETO (solo LIVE e solo se label esiste)
var resetFound = 0;
var resetRemoved = 0;
if (!PREVIEW_ONLY && label) {
var labeledAdsIter = label.ads().get();
while (labeledAdsIter.hasNext()) {
var ad = labeledAdsIter.next();
resetFound++;
ad.removeLabel(LABEL_INCOMPLETO); // rimuove SOLO questa label
resetRemoved++;
}
}
// 2) SCAN: trova gli RSA "incompleti"
var scannedRsa = 0;
var incompleteFound = 0;
var labeledApplied = 0;
var rsaIter = AdsApp.ads()
.withCondition("Type = RESPONSIVE_SEARCH_AD")
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdGroupStatus = ENABLED")
.withCondition("Status = ENABLED")
.get();
while (rsaIter.hasNext()) {
var ad = rsaIter.next();
scannedRsa++;
var rsa = ad.asType().responsiveSearchAd();
var headlinesCount = safeLength_(rsa.getHeadlines());
var descriptionsCount = safeLength_(rsa.getDescriptions());
var isIncomplete = (headlinesCount < MIN_HEADLINES) || (descriptionsCount < MIN_DESCRIPTIONS);
if (isIncomplete) {
incompleteFound++;
if (!PREVIEW_ONLY) {
// in LIVE la label esiste per forza (creata sopra), quindi posso applicare
ad.applyLabel(LABEL_INCOMPLETO);
labeledApplied++;
}
}
}
// 3) LOG (solo numeri + mode + info label)
Logger.log("MODE: " + (PREVIEW_ONLY ? "PREVIEW" : "LIVE"));
Logger.log("LABEL_EXISTS: " + (label ? "YES" : "NO"));
if (PREVIEW_ONLY && !label) {
Logger.log("NOTE: In PREVIEW non creo label. Passa a LIVE per creare/applicare 'INCOMPLETO'.");
}
Logger.log("RESET_FOUND_INCOMPLETO: " + resetFound);
Logger.log("RESET_REMOVED_INCOMPLETO: " + resetRemoved);
Logger.log("RSA_SCANNED: " + scannedRsa);
Logger.log("RSA_INCOMPLETI_FOUND: " + incompleteFound);
Logger.log("RSA_INCOMPLETI_LABELED: " + labeledApplied);
}
// ---------------------
// Helpers
// ---------------------
/**
* PREVIEW SAFE: restituisce la label se esiste, altrimenti null.
*/
function getLabelIfExists_(labelName) {
var it = AdsApp.labels().withCondition("Name = '" + escapeQuotes_(labelName) + "'").get();
return it.hasNext() ? it.next() : null;
}
/**
* LIVE: se non esiste la crea davvero, poi la recupera con retry.
*/
function getOrCreateLabelLive_(labelName) {
var label = getLabelIfExists_(labelName);
if (label) return label;
// Creo
AdsApp.createLabel(labelName);
// Retry (a volte c'è un micro-delay di consistenza)
for (var i = 0; i < 5; i++) {
label = getLabelIfExists_(labelName);
if (label) return label;
}
throw new Error("Non riesco a creare o recuperare la label '" + labelName + "' in LIVE. Verifica che lo script sia eseguito dentro un ACCOUNT (non MCC) e abbia permessi di modifica.");
}
function safeLength_(arr) {
if (!arr) return 0;
try {
return arr.length || 0;
} catch (e) {
return 0;
}
}
function escapeQuotes_(s) {
return String(s).replace(/'/g, "\\'");
}Il concetto
Un annuncio RSA completo sfrutta 15 titoli e 4 descrizioni. Non perché Google lo vuole, ma perché più asset hai, più combinazioni può testare, più segnali raccoglie, più riesce ad adattarsi a query e contesti diversi. Quando invece l’annuncio ha meno asset:
- riduci varietà semantica (meno angoli d’attacco),
- riduci copertura (meno chance di matchare intent diversi),
- riduci capacità di apprendimento (meno combinazioni testabili).
In pratica stai usando un formato “dinamico” in modalità “statica”.

Cosa fa lo script
Lo script analizza tutti gli annunci Responsive Search Ads attivi che si trovano in campagne, ad group e annunci attivi e identifica quelli che sono incompleti, cioè:
- meno di 15 titoli oppure,
- meno di 4 descrizioni.
A quel punto entra in gioco la label “INCOMPLETO”.
Due modalità: Preview e Live
1) PREVIEW (PREVIEW_ONLY = true)
È la modalità “mani in tasca”. Non crea label, non le rimuove, non le applica. Fa solo una scansione e scrive nel log quanti annunci sono incompleti. È perfetta per:
- capire la dimensione del problema,
- fare una prima fotografia dell’account,
- evitare cambiamenti “a sorpresa” in ambienti delicati.
Alla fine trovi nel log numeri chiari, tipo quanti annunci ha scansionato e quanti sono incompleti.
2) LIVE (PREVIEW_ONLY = false)
Qui lo script lavora davvero. E la cosa importante è come lavora: prima pulisce, poi ricalcola.
Il reset intelligente
Ogni esecuzione in LIVE fa questa sequenza:
- rimuove SOLO la label “INCOMPLETO” da tutto ciò che la possiede,
- riscansiona gli annunci attivi,
- riapplica la label solo agli annunci che sono incompleti in quel momento.
Questo risolve un problema molto comune: le label vecchie. Perché può succedere che:
- ieri un annuncio era incompleto = label applicata
- oggi lo hai sistemato = ma la label è ancora lì
Lo script evita che l’account si riempia di etichette zombie. Fa un reset: toglie solo “INCOMPLETO”, non tocca nient’altro.
Cosa trovi nei log
Lo script stampa sempre:
- MODE: PREVIEW o LIVE
- LABEL_EXISTS: YES/NO
- conteggio di reset (solo LIVE)
- quanti RSA sono stati scansionati
- quanti sono incompleti
- quanti hanno ricevuto la label
Quindi anche senza aprire l’interfaccia, capisci subito cosa sta succedendo.
Perché serve
Perché gli account crescono in modo asimmetrico. Tu magari sei bravissimo sulle campagne core, ma poi c’è:
- la campagna “test” che è diventata permanente,
- il gruppo annunci duplicato “solo per provare”,
- l’annuncio creato al volo per una promo e mai più rivisto,
- il nuovo account manager che non è così attento ai dettagli.
Questo script è un modo semplice per trasformare una best practice in una routine automatica.
Come usarlo in modo pratico
- Incolla lo script in Google Ads Scripts (dentro l’account, non MCC).
- Lascia PREVIEW_ONLY = true.
- Esegui e guarda i log.
- Se i numeri hanno senso, passa a PREVIEW_ONLY = false.
- (opzionale) Pianifica un’esecuzione ricorrente (es. giornaliera o settimanale).
A quel punto la label “INCOMPLETO” diventa una to-do list viva:
- clicchi la label,
- vedi gli annunci da completare,
- li sistemi,
- al run successivo spariscono automaticamente dalla lista.
Gli RSA incompleti non sono un errore evidente: funzionano, ma non spingono. Sono lì, ma non stanno facendo tutto quello che potrebbero. Con questo script, invece di andare a caccia manuale, lasci che l’account ti dica: “questi annunci non stanno sfruttando il formato. Sistemali.”. E lo fa con una label sola, aggiornata a ogni run, senza sporcare l’ecosistema di tag, senza confondere il team, senza creare caos.
Potrebbe interessarti anche
Corsi, articoli, eventi: il mondo Ninja è ricco di risorse e di appuntamenti da non perdere.








