← Back to Tech Projects

Draft Mode

This project is currently a draft. It is not visible on the homepage or tech project lists.

https://ravisodha.co.uk/images/tech-alert.png

Google Ads Slack Alerts

Google Ads Slack Alerts

Google Ads Slack Alerts

Core Script Implementation

// ========================================== // CONFIGURATION VARIABLES // ==========================================

// Insert your Slack Incoming Webhook URL here var SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX';

// Set your threshold percentage (0.15 = 15%) var THRESHOLD_PERCENTAGE = 0.15;

// Set your preferred currency symbol for the Slack message var ACCOUNT_CURRENCY_SYMBOL = '£';

// ========================================== // MAIN SCRIPT // ==========================================

function main() { var accountName = AdsApp.currentAccount().getName(); var today = new Date();

// 1. Calculate date ranges var last7DaysEnd = new Date(today.getTime() - (1 24 3600 1000)); var last7DaysStart = new Date(today.getTime() - (7 24 3600 1000));

var prev7DaysEnd = new Date(today.getTime() - (8 24 3600 1000)); var prev7DaysStart = new Date(today.getTime() - (14 24 3600 1000));

var lastYear7DaysEnd = new Date(last7DaysEnd); lastYear7DaysEnd.setFullYear(lastYear7DaysEnd.getFullYear() - 1);

var lastYear7DaysStart = new Date(last7DaysStart); lastYear7DaysStart.setFullYear(lastYear7DaysStart.getFullYear() - 1);

// Format dates for the Google Ads API (YYYYMMDD) var strLast7Start = formatDate(last7DaysStart); var strLast7End = formatDate(last7DaysEnd);

var strPrev7Start = formatDate(prev7DaysStart); var strPrev7End = formatDate(prev7DaysEnd);

var strLastYearStart = formatDate(lastYear7DaysStart); var strLastYearEnd = formatDate(lastYear7DaysEnd);

// 2. Retrieve account-level spend data var spendLast7 = getSpend(strLast7Start, strLast7End); var spendPrev7 = getSpend(strPrev7Start, strPrev7End); var spendLastYear = getSpend(strLastYearStart, strLastYearEnd);

// 3. Calculate percentage differences var diffPrev7 = spendPrev7 > 0 ? (spendLast7 - spendPrev7) / spendPrev7 : 0; var diffLastYear = spendLastYear > 0 ? (spendLast7 - spendLastYear) / spendLastYear : 0;

var triggerAlert = false; var alertBlocks = [];

// 4. Evaluate conditions and pull campaign breakdowns if needed if (diffPrev7 > THRESHOLD_PERCENTAGE) { triggerAlert = true; var msg = 'Spend is up ' + (diffPrev7 100).toFixed(2) + '%* compared to the previous 7 days.\n'; msg += getTopSpendersText(strLast7Start, strLast7End, strPrev7Start, strPrev7End); alertBlocks.push(msg); }

if (diffLastYear > THRESHOLD_PERCENTAGE) { triggerAlert = true; var msg = 'Spend is up ' + (diffLastYear 100).toFixed(2) + '%* compared to the same 7 days last year.\n'; msg += getTopSpendersText(strLast7Start, strLast7End, strLastYearStart, strLastYearEnd); alertBlocks.push(msg); }

// 5. Send Slack Alert if (triggerAlert) { var message = '' + accountName + ' Spend Alert\n\n'; message += alertBlocks.join('\n\n') + '\n\n'; message += 'Account Totals:\n'; message += 'Last 7 Days: ' + ACCOUNT_CURRENCY_SYMBOL + spendLast7.toFixed(2) + '\n'; message += 'Previous 7 Days: ' + ACCOUNT_CURRENCY_SYMBOL + spendPrev7.toFixed(2) + '\n'; message += 'Same 7 Days Last Year: ' + ACCOUNT_CURRENCY_SYMBOL + spendLastYear.toFixed(2);

sendSlackMessage(message);

} else { Logger.log('Spend is within normal limits. No alert sent.'); } }

function getTopSpendersText(currentStart, currentEnd, pastStart, pastEnd) { var campaignData = [];

// Only check enabled campaigns to keep the script fast var campaignIterator = AdsApp.campaigns() .withCondition("campaign.status = ENABLED") .get();

while (campaignIterator.hasNext()) { var campaign = campaignIterator.next(); var currentCost = campaign.getStatsFor(currentStart, currentEnd).getCost(); var pastCost = campaign.getStatsFor(pastStart, pastEnd).getCost(); var diff = currentCost - pastCost;

// Only record campaigns that actually increased in spend
if (diff > 0) {
  campaignData.push({
    name: campaign.getName(),
    diff: diff
  });
}

}

// Sort by the highest spend increase campaignData.sort(function(a, b) { return b.diff - a.diff; });

// Get the top 3 drivers var limit = Math.min(3, campaignData.length); if (limit === 0) return "No active campaigns found with a spend increase.";

var text = "Top drivers for this increase:\n"; for (var i = 0; i < limit; i++) { text += "• " + campaignData[i].name + " (+" + ACCOUNT_CURRENCY_SYMBOL + campaignData[i].diff.toFixed(2) + ")\n"; }

return text; }

function getSpend(startDate, endDate) { return AdsApp.currentAccount().getStatsFor(startDate, endDate).getCost(); }

function formatDate(date) { var year = date.getFullYear().toString(); var month = (date.getMonth() + 1).toString(); var day = date.getDate().toString();

if (month.length === 1) month = '0' + month; if (day.length === 1) day = '0' + day;

return year + month + day; }

function sendSlackMessage(text) { var payload = { "text": text };

var options = { "method": "post", "contentType": "application/json", "payload": JSON.stringify(payload) };

UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options); Logger.log('Alert sent to Slack successfully.'); }