Pendant longtemps, les scripts Google Ads ont été réservés à ceux qui savaient coder, ou qui acceptaient de copier un script trouvé en ligne sans vraiment le comprendre. L'IA générative a changé la donne : décrire précisément son besoin suffit désormais pour obtenir un script fonctionnel en quelques minutes.
Les 4 scripts d'alerte que j'installe sur chaque compte que je reprends ont été créés avec Claude. Je vous les partage ici, avec la méthode que j'utilise pour les écrire.
La méthode : décrire le besoin comme à un développeur
La qualité du script dépend directement de la précision de la demande. Un prompt vague ("fais-moi un script qui surveille mes conversions") donne un script vague. Je précise toujours cinq choses :
- Ce que le script doit vérifier, et sur quelle période.
- Le périmètre : tout le compte, certaines campagnes, une action de conversion précise, hors brouillons et tests.
- Le seuil ou la condition qui déclenche l'alerte.
- Ce qu'il doit faire : envoyer un email et rien d'autre (dans le cadre d'un script d'alerting comme dans les exemples si dessous). Je demande explicitement qu'il ne modifie rien dans le compte.
- La forme : un bloc de configuration en haut du script, des commentaires, des messages dans les journaux pour pouvoir suivre son exécution.
Voici par exemple le type de demande qui a donné mon script de suivi des conversions :
Écris un script Google Ads qui vérifie chaque matin le nombre de conversions enregistrées hier pour une action de conversion précise, dont je renseigne le nom exact. Si ce nombre est égal à zéro, envoie un email d'alerte avec quelques pistes de vérification. Le script ne doit rien modifier dans le compte.
Regroupe les paramètres (nom de l'action, email, nom du compte) dans un bloc de configuration en haut du script.
Ensuite, je teste, je reviens vers l'IA avec les messages d'erreur ou les comportements inattendus, et j'itère. C'est souvent à cette étape que le script devient vraiment adapté au compte.
Ma checklist avant de mettre un script d'alerting en production
- Je vérifie qu'il a bien le comportement attendu (ex : envoi d'un email lorsque les conditions sont réunies)
- Je vérifie qu'il ne modifie rien dans le compte sans que je l'aie décidé.
- Je provoque volontairement l'alerte (seuil très bas, URL cassée de test) pour vérifier que l'email part bien.
- Je surveille les journaux d'exécution pendant les premiers jours.
L'IA fait gagner un temps considérable sur l'écriture. Le test, l'adaptation au compte et le jugement restent votre travail.
Script 1 : alerte pages de destination cassées
Ce qu'il fait : il teste chaque jour les URL finales des annonces actives, dans les groupes et campagnes actifs, hors brouillons et tests. Si une page renvoie une erreur (404, 500, page injoignable), il envoie un email qui liste les URL concernées et les annonces qui y mènent.
Pourquoi : une page en erreur continue de recevoir des clics payants. Une refonte de site ou un changement d'URL suffit à casser des dizaines de liens d'un coup.
Fréquence conseillée : une fois par jour, tôt le matin.
/**
* Script Google Ads : alerte pages de destination cassées
* Script proposé par La tech dans les étoiles : https://www.latechdanslesetoiles.com
* Teste les URL finales des annonces actives (groupes et campagnes actifs,
* hors brouillons et tests) et envoie un email si une page renvoie une erreur.
* Fréquence conseillée : une fois par jour, tôt le matin.
*/
// ===== CONFIGURATION =====
var CONFIG = {
EMAIL: 'vous@exemple.com', // Plusieurs adresses : séparées par des virgules
OBJET: '[Alerte Google Ads] Pages de destination en erreur',
URL_IGNOREES: [] // URL à ne pas tester, ex. ['https://exemple.com/page']
};
// =========================
function main() {
var idsCampagnes = getCampagnesActives();
if (idsCampagnes.length === 0) {
Logger.log('Aucune campagne active. Fin du script.');
return;
}
var urls = regrouperParUrl(collecterUrls(idsCampagnes));
Logger.log(urls.length + ' URL uniques à tester.');
var erreurs = testerUrls(urls);
if (erreurs.length > 0) {
envoyerAlerte(erreurs);
Logger.log(erreurs.length + ' URL en erreur. Email envoyé.');
} else {
Logger.log('Toutes les pages répondent correctement.');
}
}
// Campagnes actives, hors brouillons et tests
function getCampagnesActives() {
var ids = [];
var rapport = AdsApp.report(
'SELECT campaign.id FROM campaign ' +
'WHERE campaign.status = ENABLED ' +
'AND campaign.experiment_type = BASE'
);
var lignes = rapport.rows();
while (lignes.hasNext()) {
ids.push(lignes.next()['campaign.id']);
}
return ids;
}
// URL finales des annonces actives, par lots de 50 campagnes
function collecterUrls(idsCampagnes) {
var liste = [];
for (var i = 0; i < idsCampagnes.length; i += 50) {
var lot = idsCampagnes.slice(i, i + 50).map(function(id) {
return '"' + id + '"';
}).join(', ');
var annonces = AdsApp.ads()
.withCondition('Status = ENABLED')
.withCondition('AdGroupStatus = ENABLED')
.withCondition('CampaignStatus = ENABLED')
.withCondition('CampaignId IN [' + lot + ']')
.get();
while (annonces.hasNext()) {
var annonce = annonces.next();
var url = annonce.urls().getFinalUrl();
if (!url || CONFIG.URL_IGNOREES.indexOf(url) !== -1) continue;
liste.push({
url: url,
campagne: annonce.getCampaign().getName(),
groupe: annonce.getAdGroup().getName(),
idAnnonce: annonce.getId()
});
}
}
return liste;
}
// Chaque URL n'est testée qu'une fois, en gardant la liste des annonces liées
function regrouperParUrl(liste) {
var parUrl = {};
liste.forEach(function(item) {
if (!parUrl[item.url]) parUrl[item.url] = { url: item.url, annonces: [] };
parUrl[item.url].annonces.push(item);
});
return Object.keys(parUrl).map(function(u) { return parUrl[u]; });
}
// Toute réponse hors 2xx/3xx est considérée comme une erreur
function testerUrls(urls) {
var erreurs = [];
urls.forEach(function(item) {
var statut;
try {
var reponse = UrlFetchApp.fetch(item.url, {
muteHttpExceptions: true,
followRedirects: true
});
statut = reponse.getResponseCode();
} catch (e) {
statut = 'ERREUR : ' + e.message;
}
Logger.log(item.url + ' : ' + statut);
if (typeof statut !== 'number' || statut >= 400) {
erreurs.push({ url: item.url, statut: statut, annonces: item.annonces });
}
});
return erreurs;
}
function envoyerAlerte(erreurs) {
var compte = AdsApp.currentAccount();
var lignes = [
'Bonjour,', '',
erreurs.length + ' page(s) de destination en erreur dans le compte ' +
compte.getName() + ' (' + compte.getCustomerId() + ').', ''
];
erreurs.forEach(function(e, i) {
lignes.push((i + 1) + '. ' + e.url);
lignes.push(' Statut : ' + e.statut);
e.annonces.forEach(function(a) {
lignes.push(' - ' + a.campagne + ' > ' + a.groupe + ' (annonce ' + a.idAnnonce + ')');
});
lignes.push('');
});
lignes.push('Email envoyé automatiquement par un script Google Ads.');
MailApp.sendEmail({
to: CONFIG.EMAIL,
subject: CONFIG.OBJET + ' (' + erreurs.length + ')',
body: lignes.join('\n')
});
}
Script 2 : alerte zéro conversion hier
Ce qu'il fait : il compte chaque matin les conversions enregistrées la veille pour une action de conversion précise. Si le total est nul, il envoie un email avec les premières pistes de vérification.
Pourquoi : si les conversions ne remontent plus, le Smart Bidding perd sa boussole, et toute la performance du compte en dépend. Si votre compte a l'habitude de recevoir des conversions tous les jours, un jour sans conversion doit vous alerter.
Fréquence conseillée : une fois par jour, le matin. À réserver aux actions qui enregistrent des conversions tous les jours, sinon les fausses alertes se multiplient. Pour les conversions importées (CRM, outil d'analyse), tenez compte du délai d'import.
/**
* Script Google Ads : alerte zéro conversion hier
* Script proposé par La tech dans les étoiles : https://www.latechdanslesetoiles.com
* Compte les conversions de la veille (fuseau horaire du compte) pour UNE
* action de conversion et envoie un email si le total est nul.
* Fréquence conseillée : une fois par jour, le matin.
*/
// ===== CONFIGURATION =====
var CONFIG = {
// Nom EXACT de l'action, tel qu'affiché dans Objectifs > Conversions
NOM_ACTION: 'nom_de_votre_action',
EMAIL: 'vous@exemple.com', // Plusieurs adresses : séparées par des virgules
NOM_COMPTE: 'Mon compte', // Nom affiché dans l'email
EMAIL_SI_OK: false // true : email de confirmation même quand tout va bien
};
// =========================
function main() {
var nom = CONFIG.NOM_ACTION.replace(/'/g, "\\'");
// Conversions rattachées à la date où elles ont eu lieu, pas à la date du clic
var lignes = AdsApp.search(
'SELECT metrics.conversions_by_conversion_date, ' +
'segments.conversion_action_name ' +
'FROM customer ' +
'WHERE segments.date DURING YESTERDAY ' +
"AND segments.conversion_action_name = '" + nom + "'"
);
var total = 0;
while (lignes.hasNext()) {
var ligne = lignes.next();
total += parseFloat(ligne.metrics.conversionsByConversionDate) || 0;
}
var hier = getHier();
Logger.log('Conversions "' + CONFIG.NOM_ACTION + '" le ' + hier + ' : ' + total);
if (total === 0) {
envoyerEmail(
'⚠️ Aucune conversion "' + CONFIG.NOM_ACTION + '" hier : ' + CONFIG.NOM_COMPTE,
'Bonjour,\n\n' +
'L\'action "' + CONFIG.NOM_ACTION + '" n\'a enregistré AUCUNE conversion le ' +
hier + ' sur le compte "' + CONFIG.NOM_COMPTE + '".\n\n' +
'Points à vérifier :\n' +
'- La balise ou l\'import de cette action sont-ils toujours actifs ?\n' +
'- L\'action a-t-elle été renommée dans l\'interface ?\n' +
'- Les pages de destination répondent-elles (pas d\'erreur 404 ou 500) ?\n' +
'- Les campagnes concernées sont-elles actives et ont-elles du budget ?\n'
);
} else if (CONFIG.EMAIL_SI_OK) {
envoyerEmail(
'✅ Conversions "' + CONFIG.NOM_ACTION + '" OK hier : ' + CONFIG.NOM_COMPTE,
'L\'action "' + CONFIG.NOM_ACTION + '" a enregistré ' + total +
' conversion(s) le ' + hier + '.\n'
);
}
}
function envoyerEmail(objet, message) {
MailApp.sendEmail(CONFIG.EMAIL, objet, message);
Logger.log('Email envoyé à ' + CONFIG.EMAIL);
}
function getHier() {
var hier = new Date();
hier.setDate(hier.getDate() - 1);
return Utilities.formatDate(hier, AdsApp.currentAccount().getTimeZone(), 'dd/MM/yyyy');
}
Script 3 : alerte dépense du jour
Ce qu'il fait : il additionne la dépense du jour sur tout le compte et envoie un email dès qu'elle dépasse le seuil que vous avez fixé.
Pourquoi : une erreur dans les budgets journaliers ou les systèmes d'enchères et votre budget peut vite s'évaporer.
Fréquence conseillée : toutes les heures. Les données du jour remontent avec un léger décalage : fixez un seuil qui laisse un peu de marge.
/**
* Script Google Ads : alerte dépense du jour
* Script proposé par La tech dans les étoiles : https://www.latechdanslesetoiles.com
* Envoie un email quand la dépense du jour, sur tout le compte,
* dépasse le seuil défini.
* Fréquence conseillée : toutes les heures.
*/
// ===== CONFIGURATION =====
var CONFIG = {
SEUIL: 500, // Dans la devise du compte
EMAIL: 'vous@exemple.com', // Plusieurs adresses : séparées par des virgules
OBJET: '[Alerte Google Ads] Seuil de dépense journalière dépassé'
};
// =========================
function main() {
var depense = getDepenseDuJour();
Logger.log('Dépense du jour : ' + depense.toFixed(2) + ' / seuil : ' + CONFIG.SEUIL);
if (depense > CONFIG.SEUIL) {
envoyerAlerte(depense);
Logger.log('Seuil dépassé. Email envoyé à ' + CONFIG.EMAIL);
} else {
Logger.log('Dépense sous le seuil. Pas d\'alerte.');
}
}
// Requête GAQL : le coût est renvoyé en micros (1 000 000 = 1 unité de devise)
function getDepenseDuJour() {
var lignes = AdsApp.search(
'SELECT metrics.cost_micros FROM customer WHERE segments.date DURING TODAY'
);
var total = 0;
while (lignes.hasNext()) {
total += Number(lignes.next().metrics.costMicros) / 1000000;
}
return total;
}
function envoyerAlerte(depense) {
var compte = AdsApp.currentAccount();
var devise = compte.getCurrencyCode();
var date = Utilities.formatDate(new Date(), compte.getTimeZone(), 'dd/MM/yyyy');
MailApp.sendEmail({
to: CONFIG.EMAIL,
subject: CONFIG.OBJET,
body:
'Bonjour,\n\n' +
'Compte : ' + compte.getName() + ' (' + compte.getCustomerId() + ')\n' +
'Date : ' + date + '\n' +
'Dépense du jour : ' + depense.toFixed(2) + ' ' + devise + '\n' +
'Seuil : ' + CONFIG.SEUIL.toFixed(2) + ' ' + devise + '\n\n' +
'La dépense du jour a dépassé le seuil défini.\n\n' +
'Email envoyé automatiquement par un script Google Ads.'
});
}
Script 4 : alerte dépenses nulles la veille
Ce qu'il fait : il vérifie chaque matin que le compte a bien dépensé la veille. Il n'alerte que si le compte aurait dû dépenser : au moins une campagne active en diffusion, ou des dépenses sur les 7 jours précédents. Un compte mis en pause volontairement ne déclenche donc pas de fausse alerte.
Pourquoi : un compte qui s'arrête net, c'est souvent un problème hors des campagnes. Moyen de paiement refusé, compte ou Merchant Center suspendu, annonces ou produits refusés, date de fin oubliée : autant de cas où Google n'envoie pas toujours d'alerte visible.
Fréquence conseillée : une fois par jour, vers 7 h ou 8 h. Évitez une exécution juste après minuit, car les données de la veille ne sont pas toujours consolidées.
/**
* Script Google Ads : alerte dépenses nulles la veille
* Script proposé par La tech dans les étoiles : https://www.latechdanslesetoiles.com
* Envoie un email si les dépenses d'hier sont nulles alors que le compte
* a des campagnes actives en diffusion ou a dépensé les jours précédents.
* Fréquence conseillée : une fois par jour, vers 7 h ou 8 h.
*/
// ===== CONFIGURATION =====
var CONFIG = {
EMAILS: ['vous@exemple.com'], // Plusieurs adresses possibles
JOURS_REFERENCE: 7, // Jours avant hier pris comme référence
ENVOYER_SI_TOUT_VA_BIEN: false // true : email aussi quand tout va bien
};
// =========================
function main() {
var compte = AdsApp.currentAccount();
var fuseau = compte.getTimeZone();
var devise = compte.getCurrencyCode();
var hier = dateDecalee(1, fuseau);
var depensesHier = depenses(hier, hier);
Logger.log('Dépenses du ' + hier + ' : ' + depensesHier + ' ' + devise);
if (depensesHier > 0) {
if (CONFIG.ENVOYER_SI_TOUT_VA_BIEN) {
envoyer('Google Ads OK : ' + compte.getName(),
'<p>Dépenses du ' + hier + ' : ' + depensesHier.toFixed(2) + ' ' + devise + '.</p>');
}
return;
}
var depensesRef = depenses(dateDecalee(CONFIG.JOURS_REFERENCE + 1, fuseau), dateDecalee(2, fuseau));
var campagnesActives = nombreCampagnesEnDiffusion();
// Compte volontairement à l'arrêt : pas d'alerte
if (depensesRef === 0 && campagnesActives === 0) {
Logger.log('Compte à l\'arrêt, pas d\'alerte.');
return;
}
var moyenne = depensesRef / CONFIG.JOURS_REFERENCE;
envoyer('ALERTE Google Ads : aucune dépense hier sur ' + compte.getName(),
'<p>Le compte <b>' + compte.getName() + '</b> (' + compte.getCustomerId() + ') ' +
'n\'a rien dépensé le ' + hier + '.</p>' +
'<p>Dépense moyenne sur les ' + CONFIG.JOURS_REFERENCE + ' jours précédents : ' +
moyenne.toFixed(2) + ' ' + devise + ' par jour.<br>' +
'Campagnes actives en diffusion : ' + campagnesActives + '.</p>' +
'<p>Pistes à vérifier : facturation et moyen de paiement, suspension du compte ' +
'ou du Merchant Center, refus d\'annonces ou de produits, budgets et dates de fin.</p>');
}
// Dépenses entre deux dates (le coût est renvoyé en micros)
function depenses(debut, fin) {
var lignes = AdsApp.search('SELECT metrics.cost_micros FROM customer ' +
"WHERE segments.date BETWEEN '" + debut + "' AND '" + fin + "'");
var total = 0;
while (lignes.hasNext()) {
total += Number(lignes.next().metrics.costMicros || 0);
}
return total / 1000000;
}
function nombreCampagnesEnDiffusion() {
var lignes = AdsApp.search('SELECT campaign.id FROM campaign ' +
"WHERE campaign.status = 'ENABLED' AND campaign.serving_status = 'SERVING'");
var n = 0;
while (lignes.hasNext()) { lignes.next(); n++; }
return n;
}
function dateDecalee(jours, fuseau) {
return Utilities.formatDate(new Date(Date.now() - jours * 86400000), fuseau, 'yyyy-MM-dd');
}
function envoyer(sujet, html) {
MailApp.sendEmail({ to: CONFIG.EMAILS.join(','), subject: sujet, htmlBody: html });
}Installer un script dans Google Ads
- Dans Google Ads, ouvrez le menu Outils, puis Actions groupées, puis Scripts.
- Cliquez sur le bouton +, puis sur Nouveau script.
- Collez le code et remplissez le bloc CONFIGURATION en haut du script.
- Autorisez le script à accéder au compte quand Google vous le demande.
- Lancez un aperçu et lisez les journaux.
- Enregistrez, puis choisissez la fréquence d'exécution.
En résumé
L'IA a rendu les scripts Google Ads accessibles à tous. Elle n'a pas rendu inutile le regard de quelqu'un qui sait ce qu'il faut surveiller, quelle métrique utiliser et pourquoi.
Mes 4 scripts d'alerte ne remplacent pas le pilotage d'un compte. Ils garantissent que ce pilotage repose sur des bases saines : des pages qui répondent, des conversions qui remontent, des dépenses ni nulles ni hors de contrôle.


