Google Ads Script (JavaScript)
/**
* Goodlabs Google Ads script: broken landing page checker
* Author: Goodlabs (https://goodlabs.kz)
* Schedule: Daily at 06:00
*/
var CONFIG = {
SPREADSHEET_URL: "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
NOTIFICATION_EMAIL: "analytics@yourdomain.com",
PAUSE_BROKEN_ADS: false,
OUT_OF_STOCK_REGEX: "Out of stock|Товар распродан|Нет в наличии",
TIMEOUT_MS: 10000
};
function main() {
var brokenCount = 0;
var sheet = getOrCreateSheet(CONFIG.SPREADSHEET_URL);
var checkedUrls = {};
Logger.log("Starting Goodlabs Broken URL Audit...");
var adIterator = AdsApp.ads()
.withCondition("Status = ENABLED")
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdGroupStatus = ENABLED")
.get();
while (adIterator.hasNext()) {
var ad = adIterator.next();
var url = ad.urls().getFinalUrl();
if (!url || checkedUrls[url]) continue;
var result = checkUrl(url);
checkedUrls[url] = result;
if (!result.ok) {
brokenCount++;
sheet.appendRow([
new Date(),
ad.getCampaign().getName(),
ad.getAdGroup().getName(),
ad.getId(),
url,
result.statusCode,
result.error
]);
if (CONFIG.PAUSE_BROKEN_ADS) {
ad.pause();
Logger.log("PAUSED broken ad: " + ad.getId() + " (" + url + ")");
}
}
}
Logger.log("Audit finished. Broken URLs detected: " + brokenCount);
if (brokenCount > 0 && CONFIG.NOTIFICATION_EMAIL) {
MailApp.sendEmail(
CONFIG.NOTIFICATION_EMAIL,
"⚠️ Google Ads Alert: " + brokenCount + " Broken URLs Found",
"The broken landing page check found " + brokenCount + " failing landing pages in your Google Ads account.\n\n" +
"Review the full report here: " + CONFIG.SPREADSHEET_URL
);
}
}
function checkUrl(url) {
try {
var response = UrlFetchApp.fetch(url, {
muteHttpExceptions: true,
followRedirects: true,
validateHttpsCertificates: true,
headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" }
});
var code = response.getResponseCode();
if (code >= 400) {
return { ok: false, statusCode: code, error: "HTTP Error " + code };
}
var text = response.getContentText();
var oosPattern = new RegExp(CONFIG.OUT_OF_STOCK_REGEX, "i");
if (CONFIG.OUT_OF_STOCK_REGEX && oosPattern.test(text)) {
return { ok: false, statusCode: code, error: "Out of Stock Detected" };
}
return { ok: true, statusCode: code, error: "" };
} catch (err) {
return { ok: false, statusCode: 0, error: err.toString() };
}
}
function getOrCreateSheet(url) {
try {
var ss = SpreadsheetApp.openByUrl(url);
var sheet = ss.getActiveSheet();
if (sheet.getLastRow() === 0) {
sheet.appendRow(["Timestamp", "Campaign", "Ad Group", "Ad ID", "Final URL", "HTTP Status", "Error Details"]);
sheet.getRange(1, 1, 1, 7).setFontWeight("bold").setBackground("#f3f4f6");
}
return sheet;
} catch(e) {
Logger.log("Spreadsheet error: " + e);
return { appendRow: function() {} };
}
}Как это работает
- Обходит активные объявления, ключевые слова и ситлинки через
AdsApp.ads().withCondition("Status = ENABLED"). - Запрашивает каждый URL через
UrlFetchApp.fetch()с обычным User-Agent браузера. Запросы Apps Script синхронные, поэтому время выполнения растёт с числом уникальных URL — для этого и нужен кэш. - Фиксирует ошибки 4xx (404 Not Found, 410 Gone), сбои 5xx (500, 502, 503) и сканирует текст на фразы «нет в наличии» / «распродано».
- Записывает найденные ошибки в Google Таблицу, при включённой опции ставит битые объявления на паузу и отправляет email-отчёт.
Инструкция по установке
- В Google Ads перейдите в Инструменты и настройки > Массовые действия > Скрипты.
- Нажмите «+» для создания нового скрипта.
- Вставьте сгенерированный выше код в редактор.
- Создайте Google Таблицу и вставьте её URL в переменную SPREADSHEET_URL.
- Нажмите «Авторизовать» для выдачи прав на чтение Google Ads и Sheets.
- Нажмите «Просмотр» для тестового запуска, сохраните и настройте ежедневное расписание (например, 06:00 утра).
Частые вопросы
Создаёт ли это нагрузку на сайт?
Запросы отправляются последовательно и кэшируют уже проверенные URL, минимизируя нагрузку на веб-сервер.
Что если сайт временно недоступен из-за техработ?
Рекомендуется оставлять PAUSE_BROKEN_ADS: false для первого запуска, чтобы сначала получить сводный отчёт на почту.