Daily
Post daily Google Ads results to Slack with drop alerts
Every morning Slack shows yesterday's spend, clicks and conversions per campaign, and warns you when a number changed sharply.
- Runs
- Daily
- Apps
- Google Ads, Slack
- AI
- Yes, uses the built-in AI allowance
- Access
- Ads read; Slack chat:write
Send this to your assistant
Create a ClickRuntime automation: every morning, post yesterday's Google Ads results per campaign to #paid: spend, clicks, CTR and conversions. Compare with the previous 7 days and flag any campaign whose CTR, conversions or spend moved by more than 40%, with a short AI note.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
An e-commerce marketer runs a dozen campaigns. A disapproved ad, a budget cap or a competitor's bid change can halve a campaign's results overnight, and they only notice when weekly revenue disappoints.
A morning post with each campaign's results, and a clear flag on anything that moved sharply, turns a weekly surprise into a same-day fix.
What you get out of it
Problems flagged the next morning
A campaign whose conversions or click-through rate collapsed is called out within a day.
Overspending caught too
Sudden jumps in spend are flagged before they eat the month's budget.
The whole team sees results
Daily numbers in Slack keep everyone aware of how paid search is doing.
Context with each alert
A short AI note suggests what to check, such as a disapproved ad or a budget limit.
How it works
What happens, step by step
Every morning, ClickRuntime asks Google Ads for yesterday's results per campaign.
It compares each campaign with its average over the previous seven days, which it keeps from earlier runs.
Campaigns where spend, click-through rate or conversions moved by more than 40% are flagged, with a short AI note on what to check.
The results and any flags are posted to your #paid Slack channel.
Before it runs live
- Connect Google Ads
- Connect Slack, then invite the app to the channel (type /invite @ClickRuntime there)
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Google Sheets
- Combine it with other Google Ads and Slack steps into one automation
Under the hood
The code that runs this automation
from clickruntime import on_trigger, http, credentials, ai, state, notify
CUSTOMER_ID = "1234567890"
def gaql(query):
headers = {"Authorization": f"Bearer {credentials.connection('google', 'ads')}", "developer-token": credentials.secret("GOOGLE_ADS_DEVELOPER_TOKEN")}
batches = http.post(f"https://googleads.googleapis.com/v21/customers/{CUSTOMER_ID}/googleAds:searchStream", headers=headers, json={"query": query}).json()
return [row for b in batches for row in b.get("results", [])]
@on_trigger
def run(event):
rows = gaql("SELECT campaign.name, metrics.cost_micros, metrics.clicks, metrics.ctr, metrics.conversions FROM campaign "
"WHERE segments.date DURING YESTERDAY AND campaign.status = 'ENABLED'")
history, lines, flags = state.get("history") or {}, [], []
for r in rows:
name, m = r["campaign"]["name"], r["metrics"]
today = {"spend": int(m.get("costMicros", 0)) / 1e6, "ctr": float(m.get("ctr", 0)), "conv": float(m.get("conversions", 0))}
lines.append(f"• {name}: £{today['spend']:,.2f}, {m.get('clicks', 0)} clicks, CTR {today['ctr']:.1%}, {today['conv']:.0f} conv")
past = history.get(name, [])
for k in today:
avg = sum(p[k] for p in past) / len(past) if past else 0
if avg and abs(today[k] - avg) / avg > 0.4:
flags.append(f"{name} {k}: {today[k]:,.2f} vs avg {avg:,.2f}")
history[name] = (past + [today])[-7:]
text = "*Google Ads yesterday*\n" + "\n".join(lines)
if flags:
text += "\n\n⚠️ " + ai.generate("\n".join(flags), system="For each change, say in one line what to check.", max_output_tokens=300).text
notify.slack(text, channel="#paid")
state.set("history", history)
return {"campaigns": len(rows), "flags": len(flags)}FAQ
Common questions
What does it compare against?
Can it skip small campaigns?
Can it cover several ad accounts?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Find search terms that waste ad spend each week
Every week, Slack lists the search terms that cost money without a single conversion, with suggested negative keywords.
See how it worksGet a daily news digest in Slack
Each morning your team gets a short summary of what's new on the sites and blogs you follow.
See how it worksFollow your stocks and crypto in Slack
During market hours you get a short update on the tickers you care about, with a heads-up on big moves.
See how it worksKeep exploring
Set up “Post daily Google Ads results to Slack with drop alerts” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.