CÓDIGO DE PRODUÇÃO & AUTOMAÇÃO

Script de Alerta: Detector de Anomalias de Gastos

Script automatizado para monitoramento e alerta em tempo real de saltos anômalos de CPC, CPA e budget no Google Ads por Wagner Hörlle.

💬 Suporte Técnico no WhatsApp
/**
 * SCRIPT 2: ALERTA DE ANOMALIA DE GASTOS E CLIQUES EM TEMPO REAL
 * Pacote de Proteção de Conta Google Ads - Growth OS
 * 
 * Finalidade:
 * Executado a cada 1 ou 2 horas, detecta anomalias críticas na conta:
 * 1. Consumo acelerado do orçamento diário antes do meio-dia sem conversões.
 * 2. Queda súbita de CTR (abaixo do normal histórico).
 * 3. Disparo imediato de webhook (Telegram / Discord / Slack) e e-mail.
 */

const CONFIG = {
  // Se o gasto de hoje atingir esta % do orçamento diário com zero conversões, alerta!
  MAX_PERCENT_BUDGET_NO_CONV: 0.60, // 60%
  
  // Limite mínimo de gasto hoje para acionar a verificação (em R$)
  MIN_SPEND_THRESHOLD: 150.00,
  
  // Webhook para notificação instantânea (Telegram, Discord, Slack)
  WEBHOOK_URL: 'https://api.telegram.org/botSEU_TOKEN/sendMessage?chat_id=SEU_CHAT_ID&text=',
  
  // E-mail de emergência
  ALERT_EMAIL: 'seu-email@dominio.com.br'
};

function main() {
  Logger.log('Iniciando checagem horária de anomalias de conta...');
  
  const alerts = [];
  const campaignIterator = AdsApp.campaigns()
    .withCondition('Status = ENABLED')
    .get();

  while (campaignIterator.hasNext()) {
    const campaign = campaignIterator.next();
    const stats = campaign.getStatsFor('TODAY');
    const costToday = stats.getCost();
    const conversionsToday = stats.getConversions();
    const clicksToday = stats.getClicks();
    const impressionsToday = stats.getImpressions();
    const dailyBudget = campaign.getBudget().getAmount();

    // 1. Verificação de gasto excessivo sem conversões
    if (dailyBudget > 0 && costToday >= CONFIG.MIN_SPEND_THRESHOLD) {
      const budgetUsedRatio = costToday / dailyBudget;
      
      if (budgetUsedRatio >= CONFIG.MAX_PERCENT_BUDGET_NO_CONV && conversionsToday === 0) {
        const msg = `🚨 [ANOMALIA DE GASTO] Campanha "${campaign.getName()}" consumiu ${(budgetUsedRatio * 100).toFixed(0)}% do orçamento diário (R$ ${costToday.toFixed(2)}) e gerou ZERO conversões hoje!`;
        Logger.log(msg);
        alerts.push(msg);
      }
    }

    // 2. Verificação de CTR anormalmente baixo com alto volume
    if (impressionsToday > 500 && clicksToday > 0) {
      const ctrToday = (clicksToday / impressionsToday) * 100;
      if (ctrToday < 0.35) {
        const msg = `⚠️ [QUEDA DE CTR] Campanha "${campaign.getName()}" está com CTR de apenas ${ctrToday.toFixed(2)}% hoje (${clicksToday} cliques em ${impressionsToday} impressões). Verifique segmentação e criativos.`;
        Logger.log(msg);
        alerts.push(msg);
      }
    }
  }

  if (alerts.length > 0) {
    Logger.log(`Disparando notificações de emergência para ${alerts.length} alertas...`);
    
    // Disparo por E-mail
    if (CONFIG.ALERT_EMAIL) {
      MailApp.sendEmail(
        CONFIG.ALERT_EMAIL,
        `[URGENTE Google Ads] ${alerts.length} anomalias detectadas hoje`,
        alerts.join('\n\n')
      );
    }

    // Disparo por Webhook
    if (CONFIG.WEBHOOK_URL && CONFIG.WEBHOOK_URL.indexOf('SEU_TOKEN') === -1) {
      try {
        const payload = encodeURIComponent("🚨 ALERTA GOOGLE ADS:\n" + alerts.join("\n\n"));
        UrlFetchApp.fetch(CONFIG.WEBHOOK_URL + payload, { muteHttpExceptions: true });
      } catch (err) {
        Logger.log('Erro ao disparar webhook: ' + err.toString());
      }
    }
  } else {
    Logger.log('Nenhuma anomalia detectada. Conta operando dentro dos parâmetros de segurança.');
  }
}