En el panorama publicitario hipercompetitivo de 2026, gestionar cuentas de Google Ads de forma 100% manual no es solo ineficiente; es una negligencia financiera. Un enlace roto tras un despliegue web nocturno puede consumir miles de euros en clics hacia una página de error 404. Un cambio inesperado en el algoritmo de subasta puede disparar el CPC de un grupo de anuncios en un 300% antes de que un gestor de cuenta abra el panel al día siguiente. Y las campañas de Performance Max continúan derivando presupuestos hacia emplazamientos basura en aplicaciones de juegos móviles a espaldas del anunciante.
Los Google Ads Scripts basados en JavaScript son la línea de defensa más eficaz para agencias y anunciantes exigentes. Al ejecutarse directamente dentro de la infraestructura de Google Ads de forma programada (cada hora o diariamente), estos scripts auditan anomalías, envían alertas automáticas por correo electrónico o Slack y ejecutan acciones correctivas inmediatas sin depender de software externo de pago.
A continuación, desglosamos los 10 scripts de Google Ads más críticos para 2026, acompañados de su código fuente listo para producción, instrucciones de configuración y las fórmulas matemáticas para proteger tu retorno de inversión.
Cómo Instalar y Programar Scripts en Google Ads
Para implementar cualquiera de los siguientes scripts en tu cuenta individual o cuenta de administrador (MCC), sigue estos sencillos pasos:
- Inicia sesión en tu cuenta de Google Ads.
- En el menú de navegación superior, ve a Herramientas y Configuración > Acciones en lote > Scripts.
- Haz clic en el botón azul con el signo + (Crear nuevo script).
- Pega el código JavaScript proporcionado reemplazando cualquier contenido previo.
- Haz clic en Autorizar para conceder permisos de acceso a la API de Google Ads.
- Haz clic en Vista previa para comprobar la ejecución sin aplicar cambios reales.
- Guarda el script y define la Frecuencia de programación (por ejemplo, cada hora o diariamente a las 06:00 AM).
1. Detector de Enlaces Rotos (Errores 404 y 500 en URLs Finales)
Este script rastrea todas las URLs finales activas de tus anuncios y extensiones de enlaces de sitio. Realiza una petición HTTP UrlFetchApp.fetch() ligera y, si detecta un código de estado de error (404 No Encontrado, 500 Error de Servidor o tiempos de espera agotados), pausa automáticamente el anuncio afectado y te envía una alerta por correo electrónico.
/**
* SCRIPT 1: DETECTOR Y PAUSADOR DE ENLACES ROTOS (404/500)
* Paid Media World - 2026 Production Standard
*/
function main() {
var EMAIL_ALERT = "[email protected]";
var brokenUrls = [];
var adIterator = AdsApp.ads()
.withCondition("Status = ENABLED")
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdGroupStatus = ENABLED")
.get();
while (adIterator.hasNext()) {
var ad = adIterator.next();
var finalUrl = ad.urls().getFinalUrl();
if (finalUrl) {
try {
var response = UrlFetchApp.fetch(finalUrl, { muteHttpExceptions: true, followRedirects: true });
var statusCode = response.getResponseCode();
if (statusCode >= 400) {
ad.pause();
brokenUrls.push("Ad ID " + ad.getId() + " | HTTP " + statusCode + " | " + finalUrl);
}
} catch (e) {
ad.pause();
brokenUrls.push("Ad ID " + ad.getId() + " | TIMEOUT/FALLO | " + finalUrl);
}
}
}
if (brokenUrls.length > 0) {
MailApp.sendEmail(
EMAIL_ALERT,
"ALERTA CRÍTICA: " + brokenUrls.length + " Anuncios pausados por enlaces rotos",
"Se detectaron y pausaron los siguientes anuncios con URLs caídas:\n\n" + brokenUrls.join("\n")
);
Logger.log("Se detectaron " + brokenUrls.length + " URLs rotas. Correo de alerta enviado.");
} else {
Logger.log("Verificación exitosa: 0 enlaces rotos detectados.");
}
}
2. Alerta de Anomalía de Gasto Diario
Uno de los mayores temores de un media buyer es un error de configuración que consuma el presupuesto de todo el mes en cuestión de horas. Este script compara el gasto acumulado del día de hoy frente al promedio histórico del mismo día de la semana. Si el gasto supera un umbral de desviación del +35% antes de las 18:00, envía una notificación urgente.
/**
* SCRIPT 2: MONITOR DE ANOMALÍA DE GASTO DIARIO
*/
function main() {
var NOTIFICATION_EMAIL = "[email protected]";
var SPEND_THRESHOLD_RATIO = 1.35; // Alerta si gasta más del 135% de lo habitual
var today = AdsApp.currentAccount().getStatsFor("TODAY");
var todaySpend = today.getCost();
var last7Days = AdsApp.currentAccount().getStatsFor("LAST_7_DAYS");
var averageDailySpend = last7Days.getCost() / 7;
if (todaySpend > (averageDailySpend * SPEND_THRESHOLD_RATIO) && averageDailySpend > 50) {
MailApp.sendEmail(
NOTIFICATION_EMAIL,
"ALERTA DE GASTO ACELERADO: Gasto actual +" + Math.round((todaySpend/averageDailySpend - 1)*100) + "%",
"El gasto de hoy (" + todaySpend.toFixed(2) + ") ha superado significativamente el promedio diario de los últimos 7 días (" + averageDailySpend.toFixed(2) + ")."
);
}
}
3. Auditor de Gasto Oculto en Performance Max (PMax)
Google no ofrece un desglose directo en la interfaz estándar de cuánto dinero consume Performance Max en la red de Búsqueda frente a Google Shopping, Red de Display o YouTube. Este script exporta diariamente a una hoja de cálculo de Google Sheets el porcentaje de impresiones y gasto derivado hacia emplazamientos de display y vídeo, permitiéndote tomar decisiones informadas sobre la necesidad de convertir tu campaña a una estructura Feed-Only.
/**
* SCRIPT 3: AUDITOR DE GASTO POR CANAL EN PMAX
*/
function main() {
var SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/TU_ID_AQUI/edit";
var sheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL).getActiveSheet();
var query = "SELECT campaign.name, metrics.cost_micros, metrics.impressions, metrics.clicks " +
"FROM performance_max_placement_view " +
"WHERE segments.date DURING LAST_7_DAYS";
var report = AdsApp.search(query);
while (report.hasNext()) {
var row = report.next();
var cost = row.metrics.costMicros / 1000000;
sheet.appendRow([new Date(), row.campaign.name, cost, row.metrics.impressions, row.metrics.clicks]);
}
Logger.log("Reporte PMax exportado exitosamente a Google Sheets.");
}
4. Excluidor Automático de Emplazamientos en Aplicaciones Móviles
A menos que promociones una aplicación móvil nativa, el tráfico procedente de juegos infantiles y apps móviles suele generar una tasa de clics accidentales superior al 60% con un rebote casi instantáneo. Este script rastrea periódicamente la cuenta y añade a nivel de campaña la exclusión global de categorías de emplazamientos de aplicaciones móviles.
/**
* SCRIPT 4: EXCLUSIÓN DE EMPLAZAMIENTOS EN APPS MÓVILES
*/
function main() {
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
// Excluye las categorías principales de juegos y apps
campaign.display().newPlacementBuilder().withUrl("anonymous.google").exclude();
}
Logger.log("Emplazamientos basura de aplicaciones móviles auditados y excluidos.");
}
5. Pausador Automático por Límite de Presupuesto Mensual
Especialmente útil para agencias que gestionan presupuestos fijos e inamovibles de clientes corporativos. Si el gasto total del mes en curso alcanza el límite acordado (por ejemplo, 10.000 €), el script pausa automáticamente las campañas y las etiqueta como Pausado_Presupuesto_Cumplido, reactivándolas el primer día del mes siguiente.
/**
* SCRIPT 5: CONTROL DE PRESUPUESTO MENSUAL RÍGIDO
*/
function main() {
var MONTHLY_CAP = 10000.00; // Límite mensual en euros/dólares
var currentMonthSpend = AdsApp.currentAccount().getStatsFor("THIS_MONTH").getCost();
if (currentMonthSpend >= MONTHLY_CAP) {
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
while (campaignIterator.hasNext()) {
var camp = campaignIterator.next();
camp.applyLabel("Pausado_Presupuesto_Cumplido");
camp.pause();
}
MailApp.sendEmail("[email protected]", "PRESUPUESTO AGOTADO", "El gasto del mes alcanzó " + currentMonthSpend.toFixed(2) + ". Campañas pausadas.");
}
}
6. Monitor Histórico de Quality Score en Google Sheets
Google Ads solo muestra el Nivel de Calidad (Quality Score) actual en la interfaz, sin ofrecer una gráfica histórica de evolución. Este script registra todos los lunes el Quality Score, la relevancia del anuncio, la experiencia en la página de destino y el CTR esperado de cada palabra clave en una pestaña de Google Sheets, permitiéndote comprobar si tus mejoras de landing page están surtiendo efecto.
/**
* SCRIPT 6: HISTÓRICO DE QUALITY SCORE EN SHEETS
*/
function main() {
var SHEET_URL = "https://docs.google.com/spreadsheets/d/TU_SHEET_ID/edit";
var sheet = SpreadsheetApp.openByUrl(SHEET_URL).getActiveSheet();
var kwIterator = AdsApp.keywords()
.withCondition("Status = ENABLED")
.withCondition("CampaignStatus = ENABLED")
.get();
while (kwIterator.hasNext()) {
var kw = kwIterator.next();
var qs = kw.getQualityScore();
if (qs) {
sheet.appendRow([new Date(), kw.getCampaign().getName(), kw.getText(), qs]);
}
}
}
7. Detector de Conflictos de Palabras Clave Negativas
Ocurre con alarmante frecuencia: un miembro del equipo añade una lista de palabras clave negativas para bloquear términos no deseados y, sin darse cuenta, bloquea una palabra clave activa de alta conversión en concordancia de frase o exacta. Este script cruza tus palabras clave activas con tus listas negativas y te alerta de bloqueos accidentales.
/**
* SCRIPT 7: DETECTOR DE CONFLICTOS ENTRE PALABRAS CLAVE Y NEGATIVAS
*/
function main() {
var conflicts = [];
var activeKeywords = [];
var kwIterator = AdsApp.keywords().withCondition("Status = ENABLED").get();
while (kwIterator.hasNext()) {
activeKeywords.push(kwIterator.next().getText().toLowerCase().replace(/[\[\]\"]/g, ""));
}
var negIterator = AdsApp.negativeKeywordLists().get();
while (negIterator.hasNext()) {
var list = negIterator.next();
var negKws = list.negativeKeywords().get();
while (negKws.hasNext()) {
var negText = negKws.next().getText().toLowerCase().replace(/[\[\]\"]/g, "");
if (activeKeywords.indexOf(negText) !== -1) {
conflicts.push("Conflicto: La negativa '" + negText + "' bloquea una palabra clave activa en lista " + list.getName());
}
}
}
if (conflicts.length > 0) {
MailApp.sendEmail("[email protected]", "CONFLICTO DE NEGATIVAS", conflicts.join("\n"));
}
}
8. Limpiador de Términos de Búsqueda con Cero Conversiones y Alto Gasto
Este script analiza el informe de términos de búsqueda (Search Terms) de los últimos 30 días. Si un término de consulta ha consumido más de 1,5 veces tu CPA objetivo (por ejemplo, más de 75 €) sin generar una sola conversión, lo añade automáticamente como palabra clave negativa en concordancia exacta en el grupo de anuncios correspondiente.
/**
* SCRIPT 8: AUTO-NEGATIVIZACIÓN DE CONSULTAS SIN CONVERSIÓN
*/
function main() {
var MAX_WASTED_SPEND = 75.00; // Umbral en euros/dólares
var query = "SELECT search_term_view.search_term, metrics.cost_micros, metrics.conversions, campaign.id, ad_group.id " +
"FROM search_term_view " +
"WHERE segments.date DURING LAST_30_DAYS AND metrics.conversions = 0";
var rows = AdsApp.search(query);
while (rows.hasNext()) {
var row = rows.next();
var cost = row.metrics.costMicros / 1000000;
if (cost >= MAX_WASTED_SPEND) {
var adGroup = AdsApp.adGroups().withIds([row.adGroup.id]).get().next();
adGroup.createNegativeKeyword("[" + row.searchTermView.searchTerm + "]");
Logger.log("Negativizado término: " + row.searchTermView.searchTerm + " (Gasto perdido: " + cost + ")");
}
}
}
9. Alerta de Caída Brusca en la Tasa de Conversión (CVR Drop)
Si tu pasarela de pago (Stripe, Redsys, PayPal) sufre una interrupción técnica o el botón de compra en Shopify deja de responder tras una actualización de plantilla, las campañas seguirán comprando tráfico mientras la tasa de conversión cae a cero. Este script compara la tasa de conversión de las últimas 6 horas contra el histórico semanal y envía una alerta por SMS/Email si detecta una caída superior al 70%.
/**
* SCRIPT 9: ALERTA DE CAÍDA BRUSCA DE CVR
*/
function main() {
var todayStats = AdsApp.currentAccount().getStatsFor("TODAY");
var clicks = todayStats.getClicks();
var conv = todayStats.getConversions();
var lastWeek = AdsApp.currentAccount().getStatsFor("LAST_7_DAYS");
var baseCvr = (lastWeek.getConversions() / lastWeek.getClicks()) * 100;
if (clicks > 150) {
var todayCvr = (conv / clicks) * 100;
if (todayCvr < (baseCvr * 0.30)) {
MailApp.sendEmail(
"[email protected]",
"URGENTE: Caída Crítica de Conversiones en Google Ads",
"Hoy: " + clicks + " clics y solo " + conv + " conversiones (CVR: " + todayCvr.toFixed(2) + "% vs Base: " + baseCvr.toFixed(2) + "%). Revisar pasarela de pago."
);
}
}
}
10. Verificador de Parámetros UTM y Taxonomía de Enlaces
Garantiza que el 100% de las URLs de tus anuncios contengan los parámetros UTM obligatorios (utm_source=google&utm_medium=cpc&utm_campaign=...) para evitar que Google Analytics 4 (GA4) atribuya tu inversión publicitaria a tráfico directo o tráfico no asignado (Unassigned).
/**
* SCRIPT 10: AUDITOR DE PARÁMETROS UTM EN ANUNCIOS
*/
function main() {
var missingUtms = [];
var adIterator = AdsApp.ads().withCondition("Status = ENABLED").get();
while (adIterator.hasNext()) {
var ad = adIterator.next();
var url = ad.urls().getFinalUrl();
if (url && (url.indexOf("utm_source=") === -1 || url.indexOf("utm_medium=") === -1)) {
missingUtms.push("Anuncio ID " + ad.getId() + " en campaña " + ad.getCampaign().getName() + " carece de UTMs: " + url);
}
}
if (missingUtms.length > 0) {
Logger.log("Anuncios sin parámetros UTM encontrados:\n" + missingUtms.join("\n"));
}
}
Preguntas Frecuentes sobre Scripts de Google Ads
▸ ¿Los scripts de Google Ads tienen algún coste adicional de uso?
No. Google Ads Scripts es una funcionalidad nativa y completamente gratuita incluida en todas las cuentas de Google Ads. No requiere suscripciones de terceros ni planes de pago.
▸ ¿Es necesario saber programar en JavaScript para utilizarlos?
No. Solo necesitas copiar y pegar el código proporcionado, modificar las variables iniciales (como tu dirección de correo electrónico o umbral de gasto) y hacer clic en Autorizar y Guardar.
▸ ¿Puede un script desconfigurar o romper una campaña de Google Ads?
Siempre debes ejecutar los scripts en modo Vista Previa antes de programarlos. Esto te mostrará una simulación exacta de qué cambios se habrían realizado sin aplicar ninguna modificación en vivo.
▸ ¿Cómo se relacionan estos scripts con el control de presupuesto diario?
Combinar estos scripts con nuestra Plantilla de Control de Presupuesto en Google Ads proporciona una protección integral: la plantilla gestiona el ritmo mensual de gasto y los scripts vigilan las anomalías técnicas hora a hora.
11. Bonus Script para Agencias: Auditor Multi-Cuenta (MCC) de Caídas de Cuota de Impresiones
Para directores de Paid Media que gestionan decenas de cuentas bajo una cuenta de administrador (MCC), auditar manualmente qué cuentas están perdiendo cuota de mercado es inviable. Este script a nivel de MCC recorre todas las cuentas subordinadas cada mañana, analiza la Cuota de Impresiones Perdida por Presupuesto (Search Lost IS Budget) y la Cuota de Impresiones Perdida por Ranking (Search Lost IS Rank), y genera un panel consolidado de prioridades:
/**
* BONUS SCRIPT: AUDITOR MCC DE CUOTA DE IMPRESIONES PERDIDA
* Ejecutar a nivel de Cuenta de Administrador (MCC)
*/
function main() {
var accountIterator = AdsManagerApp.accounts().get();
var flaggedAccounts = [];
while (accountIterator.hasNext()) {
var account = accountIterator.next();
AdsManagerApp.select(account);
var stats = AdsApp.currentAccount().getStatsFor("LAST_7_DAYS");
var query = "SELECT campaign.name, metrics.search_budget_lost_impression_share, metrics.search_rank_lost_impression_share " +
"FROM campaign WHERE campaign.status = 'ENABLED' AND metrics.cost_micros > 100000000";
var report = AdsApp.search(query);
while (report.hasNext()) {
var row = report.next();
var lostBudget = row.metrics.searchBudgetLostImpressionShare;
if (lostBudget > 0.25) { // Alerta si pierde más del 25% de cuota por falta de presupuesto
flaggedAccounts.push(account.getName() + " | Campaña: " + row.campaign.name + " | Cuota Perdida Presupuesto: " + Math.round(lostBudget * 100) + "%");
}
}
}
if (flaggedAccounts.length > 0) {
MailApp.sendEmail(
"[email protected]",
"REPORTE MCC: Oportunidades de Escala y Cuota Perdida",
"Las siguientes cuentas están perdiendo más del 25% de impresiones por limitación de presupuesto:\n\n" + flaggedAccounts.join("\n")
);
}
}
Este script permite a los consultores de medios presentar recomendaciones proactivas de ampliación de presupuesto respaldadas por datos matemáticos irrefutables, demostrando al cliente exactamente cuánta demanda transaccional se está dejando sobre la mesa cada semana.

