function main() {
const SPEND_LIMIT = 5000; // account currency
const DATE_RANGE = 'LAST_30_DAYS';
const keywords = AdsApp.keywords()
.withCondition('Status = ENABLED')
.withCondition('Cost > ' + SPEND_LIMIT)
.withCondition('Conversions = 0')
.forDateRange(DATE_RANGE)
.get();
while (keywords.hasNext()) {
const keyword = keywords.next();
Logger.log(JSON.stringify({
action: 'pause',
campaign: keyword.getCampaign().getName(),
adGroup: keyword.getAdGroup().getName(),
keyword: keyword.getText(),
cost: keyword.getStatsFor(DATE_RANGE).getCost()
}));
keyword.pause();
}
}
SAFE USE: Run in Preview first. A zero-conversion keyword can still assist sales, so review search terms, conversion setup and business value before allowing automatic pauses.
function main() {
const OVER_PACE_PERCENT = 20;
const labelName = 'REVIEW_OVER_PACE';
const today = new Date();
const day = today.getDate();
const daysInMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();
const campaigns = AdsApp.campaigns().withCondition('Status = ENABLED').get();
while (campaigns.hasNext()) {
const campaign = campaigns.next();
const spend = campaign.getStatsFor('THIS_MONTH').getCost();
const dailyBudget = campaign.getBudget().getAmount();
const monthlyPlan = dailyBudget * daysInMonth;
const expected = monthlyPlan * (day / daysInMonth);
const overPace = expected > 0 ? ((spend - expected) / expected) * 100 : 0;
if (overPace >= OVER_PACE_PERCENT) campaign.applyLabel(labelName);
Logger.log(campaign.getName() + ': ' + overPace.toFixed(1) + '% vs pace');
}
}
SAFE USE: Month length, seasonality and conversion lag matter. Use labels for review instead of changing budgets automatically.
const HOUR_MS = 60 * 60 * 1000;
function auditDeduplication(events) {
const recent = events.filter(event => Date.now() - event.timestamp <= HOUR_MS);
const pairs = new Map();
for (const event of recent) {
const key = event.eventName + ':' + event.eventId;
const pair = pairs.get(key) || new Set();
pair.add(event.source); // 'browser' or 'server'
pairs.set(key, pair);
}
const complete = [...pairs.values()].filter(sources =>
sources.has('browser') && sources.has('server')
).length;
const rate = pairs.size ? (complete / pairs.size) * 100 : 0;
return {
checkedEvents: pairs.size,
matchedPairs: complete,
deduplicationRate: Number(rate.toFixed(1)),
status: rate >= 90 ? 'healthy' : 'review event_name and event_id'
};
}
// Schedule this against your consented event log every hour.
console.log(auditDeduplication(eventLog));
SAFE USE: Pass only consented, non-sensitive event metadata into the monitor. Never log access tokens, raw email, phone numbers or customer payloads.
const required = ['utm_source', 'utm_medium', 'utm_campaign'];
function auditUtm(urls) {
return urls.map(rawUrl => {
const url = new URL(rawUrl);
const missing = required.filter(key => !url.searchParams.get(key));
const uppercase = required.filter(key => /[A-Z]/.test(url.searchParams.get(key) || ''));
return { url: rawUrl, missing, uppercase, valid: !missing.length && !uppercase.length };
});
}
console.table(auditUtm([
'https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=brand_india'
]));
SAFE USE: Run on your staging or QA URL set. Do not append tracking values that expose customer or private account data.
function scoreLead({ locationFit, serviceFit, intent, reachable }) {
const weights = { locationFit: 25, serviceFit: 35, intent: 25, reachable: 15 };
const score =
(locationFit ? weights.locationFit : 0) +
(serviceFit ? weights.serviceFit : 0) +
(intent === 'high' ? weights.intent : intent === 'medium' ? 12 : 0) +
(reachable ? weights.reachable : 0);
return {
score,
band: score >= 75 ? 'qualified' : score >= 45 ? 'review' : 'low-fit'
};
}
console.log(scoreLead({
locationFit: true,
serviceFit: true,
intent: 'high',
reachable: true
}));
SAFE USE: Use the score to prioritise review, not to make sensitive or discriminatory decisions. Keep the rules visible to the sales team.