
π Framework Overview
This framework breaks down Google Ads management into seven distinct phases, each with clear objectives and deliverables. Use this as your north star when planning, launching, and optimizing campaigns.
Step 1: Campaign Strategy & Goal Setting
Objective: Define clear business goals and translate them into measurable campaign objectives.
What to do:
- Identify your primary business goal (leads, sales, brand awareness, app installs)
- Set specific KPI targets: CPA, ROAS, conversion volume, CTR benchmarks
- Determine budget allocation across campaigns and ad groups
- Map out customer journey stages and align ad messaging accordingly
- Document your target audience: demographics, pain points, search intent
Deliverables:
- Campaign brief document
- KPI targets spreadsheet
- Budget allocation plan
- Audience persona profiles
Step 2: Keyword Research & Account Structure
Objective: Build a robust keyword foundation and logical account architecture.
What to do:
- Conduct comprehensive keyword research using Google Keyword Planner, SEMrush, or similar tools
- Organize keywords by theme, intent (informational, navigational, transactional), and match type
- Create tightly themed ad groups (5-20 keywords per ad group)
- Develop negative keyword lists at campaign and account level
- Structure campaigns by product/service line, geography, or funnel stage
Deliverables:
- Master keyword list with search volumes and CPC estimates
- Account structure diagram
- Negative keyword master list
- Ad group mapping document
Step 3: Ad Copy & Creative Development
Objective: Write compelling ad copy that drives clicks and conversions.
What to do:
- Write 3-5 ad variations per ad group (use Responsive Search Ads)
- Incorporate target keywords in headlines and descriptions
- Highlight unique value propositions, offers, and CTAs
- Test different messaging angles: features vs. benefits, urgency vs. trust
- Ensure ad copy matches landing page messaging
- Add all relevant ad extensions (sitelinks, callouts, structured snippets, call extensions)
Deliverables:
- Ad copy spreadsheet with all variations
- Ad extensions library
- Brand messaging guidelines
Step 4: Landing Page Setup & QA
Objective: Ensure landing pages are optimized for conversion and align with ad messaging.
What to do:
- Review landing page load speed (target <3 seconds)
- Verify message match between ads and landing pages
- Check form functionality and tracking implementation
- Ensure mobile responsiveness
- Add conversion tracking pixels (Google Ads, Google Analytics 4)
- Set up conversion goals in Google Ads
- Test all CTAs and user flows
Deliverables:
- Landing page QA checklist (completed)
- Conversion tracking documentation
- Page speed test results
Step 5: Campaign Launch & Initial Monitoring
Objective: Launch campaigns smoothly and catch any issues within the first 48-72 hours.
What to do:
- Double-check budget settings, bid strategies, and targeting parameters
- Verify conversion tracking is firing correctly
- Monitor search term reports for irrelevant queries
- Add negative keywords based on initial data
- Check impression share and ad position metrics
- Ensure ads are running (not paused or disapproved)
Deliverables:
- Launch checklist (completed)
- Initial performance snapshot
- First batch of negative keywords
Step 6: Ongoing Optimization & Testing
Objective: Continuously improve campaign performance through data-driven optimizations.
What to do:
- Review search term reports and add negative keywords
- Pause underperforming keywords and ads
- Test new ad copy variations
- Adjust bids based on performance data
- Expand winning keywords to new ad groups
- Review audience insights and adjust targeting
- Test landing page variations
- Optimize Quality Scores (improve CTR, relevance, landing page experience)
Deliverables:
- Weekly optimization reports
- A/B test results documentation
- Updated keyword and negative keyword lists
Step 7: Reporting & Strategic Review
Objective: Analyze performance, extract insights, and plan strategic adjustments.
What to do:
- Compile monthly performance reports with KPI tracking
- Analyze trends: what's working, what's not, and why
- Calculate ROI and present business impact
- Identify opportunities for expansion or budget reallocation
- Review competitive landscape and adjust strategy
- Document learnings and best practices for future campaigns
Deliverables:
- Monthly performance report
- Strategic recommendations deck
- Updated campaign roadmap
β Actionable Checklists
Pre-Launch Checklist
Campaign Setup
- Campaign objectives and goals documented β Strategist/Account Manager β One-time
- Budget allocated across campaigns β Strategist/Account Manager β One-time
- Keyword research completed β PPC Specialist β One-time
- Account structure finalized β PPC Specialist β One-time
- Ad groups created with themed keywords β PPC Specialist β One-time
- Negative keyword lists uploaded β PPC Specialist β One-time
Ad Copy & Extensions
- Responsive Search Ads written (3-5 per ad group) β Copywriter/PPC Specialist β One-time
- Ad extensions created (sitelinks, callouts, structured snippets) β PPC Specialist β One-time
- Call extensions added with correct phone numbers β PPC Specialist β One-time
- Ad copy reviewed for brand compliance β Account Manager β One-time
Landing Pages & Tracking
- Landing pages created and optimized β Web Developer/Designer β One-time
- Message match verified between ads and landing pages β PPC Specialist β One-time
- Page load speed tested (<3 seconds) β Web Developer β One-time
- Mobile responsiveness confirmed β Web Developer β One-time
- Google Ads conversion tracking installed β PPC Specialist/Developer β One-time
- Google Analytics 4 connected and configured β PPC Specialist/Developer β One-time
- Conversion actions tested and verified β PPC Specialist β One-time
- Form submissions and phone calls tracked β Developer β One-time
Final Checks
- Bid strategy selected and configured β PPC Specialist β One-time
- Budget pacing settings verified β PPC Specialist β One-time
- Targeting parameters confirmed (location, language, devices) β PPC Specialist β One-time
- Ad scheduling set (if applicable) β PPC Specialist β One-time
- Client approval received β Account Manager β One-time
- Launch date and time scheduled β PPC Specialist β One-time
Daily Management Checklist
Performance Monitoring
- Check campaign spend vs. budget pacing β PPC Specialist β Daily (9 AM)
- Review conversion data for anomalies β PPC Specialist β Daily (9 AM)
- Monitor impression share and lost IS (budget/rank) β PPC Specialist β Daily (9 AM)
- Check for disapproved ads or policy violations β PPC Specialist β Daily (9 AM)
- Review automated alerts and notifications β PPC Specialist β Daily (9 AM)
Quick Optimizations
- Add negative keywords from search terms report β PPC Specialist β Daily (11 AM)
- Pause keywords with high spend and zero conversions β PPC Specialist β Daily (11 AM)
- Respond to any client questions or concerns β Account Manager β Daily (as needed)
Weekly Optimization Checklist
Search Terms & Keywords
- Full search terms report review β PPC Specialist β Weekly (Monday)
- Add 10-20 new negative keywords β PPC Specialist β Weekly (Monday)
- Identify and promote high-performing search terms to keywords β PPC Specialist β Weekly (Monday)
- Pause keywords with poor Quality Scores (<4) or no impressions β PPC Specialist β Weekly (Monday)
Ad Performance
- Review ad performance by CTR and conversion rate β PPC Specialist β Weekly (Tuesday)
- Pause ads with CTR <50% of ad group average β PPC Specialist β Weekly (Tuesday)
- Launch new ad copy variations for testing β Copywriter/PPC Specialist β Weekly (Tuesday)
- Update ad extensions based on performance β PPC Specialist β Weekly (Tuesday)
Bid Management
- Review keyword-level performance (CPA, ROAS, conversions) β PPC Specialist β Weekly (Wednesday)
- Adjust bids on top-performing keywords (+10-20%) β PPC Specialist β Weekly (Wednesday)
- Reduce bids on underperformers (-10-20%) β PPC Specialist β Weekly (Wednesday)
- Review automated bidding strategy performance β PPC Specialist β Weekly (Wednesday)
Budget & Pacing
- Analyze budget utilization across campaigns β PPC Specialist β Weekly (Thursday)
- Reallocate budget from low to high performers β PPC Specialist/Account Manager β Weekly (Thursday)
- Forecast spend to end of month β PPC Specialist β Weekly (Thursday)
Reporting
- Generate weekly performance snapshot β PPC Specialist β Weekly (Friday)
- Document key wins and optimizations β PPC Specialist β Weekly (Friday)
- Share client-facing update (if required) β Account Manager β Weekly (Friday)
Post-Campaign Wrap-Up Checklist
Performance Analysis
- Pull final campaign performance report β PPC Specialist β One-time
- Calculate final ROAS, CPA, and other KPIs β PPC Specialist β One-time
- Compare actual vs. target performance β PPC Specialist β One-time
- Analyze top-performing keywords, ads, and audiences β PPC Specialist β One-time
- Identify underperforming elements and root causes β PPC Specialist β One-time
Documentation
- Compile master keyword list (winners and losers) β PPC Specialist β One-time
- Document negative keyword additions β PPC Specialist β One-time
- Save top-performing ad copy for future use β Copywriter/PPC Specialist β One-time
- Screenshot best-performing landing pages β PPC Specialist β One-time
- Create campaign post-mortem document β Account Manager β One-time
Client Deliverables
- Prepare final campaign report with insights β Account Manager β One-time
- Schedule client review meeting β Account Manager β One-time
- Present findings and recommendations β Account Manager β One-time
- Gather client feedback β Account Manager β One-time
Next Steps
- Archive campaign or keep paused for future reactivation β PPC Specialist β One-time
- Update account-level negative keyword lists β PPC Specialist β One-time
- Apply learnings to active campaigns β PPC Specialist β One-time
- Plan next campaign iteration or new initiatives β Strategist/Account Manager β One-time
Download the Excel Checklist
A companion spreadsheet is available to track task completion across your team.
|
π Standard Operating Procedures (SOPs)
SOP: Keyword Research
Objective: Identify high-intent, relevant keywords to drive qualified traffic.
Frequency: One-time at campaign launch; quarterly refreshes
Tools Needed: Google Keyword Planner, SEMrush, Ahrefs, or similar
Steps:
- Brainstorm seed keywords β List 10-15 core terms related to your product/service
- Use keyword research tools β Input seed keywords into Google Keyword Planner or third-party tools
- Analyze search volume and competition β Filter for keywords with 100+ monthly searches and manageable CPC
- Group keywords by theme β Organize into logical ad groups (e.g., "running shoes for women," "best trail running shoes")
- Identify match types β Assign Exact, Phrase, or Broad Match Modifier based on intent
- Add long-tail variations β Include specific, high-intent queries (e.g., "buy Nike running shoes size 9")
- Research competitor keywords β Use SEMrush or SpyFu to see what competitors are bidding on
- Build negative keyword list β Identify irrelevant terms to exclude (e.g., "free," "cheap," "jobs")
- Document in master spreadsheet β Include columns for keyword, match type, search volume, CPC, ad group assignment
- Review and approve β Get sign-off from account manager or client before upload
Deliverable: Master keyword list with 100-500 keywords organized by ad group
SOP: Ad Copy Writing
Objective: Create compelling, high-CTR ad copy that drives conversions.
Frequency: One-time at launch; weekly for new variations
Steps:
- Review ad group keywords β Understand the theme and search intent
- Identify unique selling propositions β What makes your offer better? (price, quality, speed, guarantee)
- Write 15 headline variations β Include target keywords, benefits, offers, and CTAs
- Write 4 description variations β Expand on value props, include social proof or urgency
- Use dynamic keyword insertion (DKI) sparingly β Only where it makes sense grammatically
- Follow character limits β Headlines: 30 chars max; Descriptions: 90 chars max
- Pin critical elements β Pin your main headline or brand name to position 1 if needed
- Create 3-5 RSA combinations per ad group β Google will test variations automatically
- Add all relevant extensions β Sitelinks, callouts, structured snippets
- Review for brand compliance β Ensure tone, messaging, and claims align with brand guidelines
- Get approval β Review with client or account manager before launch
- Monitor ad strength β Aim for "Excellent" or "Good" ad strength ratings
Deliverable: 3-5 Responsive Search Ads per ad group with full ad extensions
SOP: Bid Management
Objective: Optimize bids to maximize conversions within target CPA or ROAS.
Frequency: Weekly for manual CPC; bi-weekly for automated strategies
Steps:
- Pull keyword performance report β Last 7-14 days of data (conversions, CPA, ROAS, CTR, Avg. Position)
- Identify top performers β Keywords with CPA below target and strong conversion volume
- Increase bids on winners β Raise bids by 10-20% to capture more volume
- Identify underperformers β Keywords with high spend, zero conversions, or CPA above target
- Decrease bids on losers β Lower bids by 10-20% or pause if consistently poor
- Review impression share β If IS Lost (Rank) is high, consider bid increases
- Check Quality Score β Low QS keywords may need ad copy or landing page improvements, not just bid changes
- Adjust for device performance β Increase/decrease mobile bid adjustments based on conversion data
- Monitor automated bid strategy performance β If using Target CPA or Maximize Conversions, review learning period and performance trends
- Document changes β Note all bid adjustments in optimization log
Deliverable: Updated keyword bids; optimization log with rationale
SOP: Landing Page QA
Objective: Ensure landing pages are conversion-optimized and technically sound.
Frequency: One-time before launch; monthly spot checks
Tools Needed: Google PageSpeed Insights, GTmetrix, Google Tag Assistant
Steps:
- Check page load speed β Test on desktop and mobile using PageSpeed Insights (target: <3 seconds)
- Verify mobile responsiveness β Test on multiple devices and screen sizes
- Review message match β Ensure headline and copy align with ad messaging
- Test form functionality β Submit test leads to verify form submissions work
- Check CTA visibility β Ensure primary CTA is above the fold and stands out
- Verify tracking implementation β Use Google Tag Assistant to confirm conversion tags fire correctly
- Test all links β Ensure no broken links or 404 errors
- Review trust signals β Check for security badges, testimonials, social proof
- Optimize images β Compress large images to improve load speed
- Run accessibility check β Ensure compliance with WCAG guidelines (contrast, alt text)
- Test across browsers β Chrome, Safari, Firefox, Edge
- Document findings β Create QA report with issues and fixes
Deliverable: QA report with pass/fail status and action items
SOP: Search Terms Report Review
Objective: Identify irrelevant queries and add negative keywords to improve efficiency.
Frequency: Daily for first week; then weekly
Steps:
- Pull search terms report β Last 7 days, all campaigns
- Filter by clicks or impressions β Focus on terms with meaningful volume
- Identify irrelevant queries β Flag searches that don't match intent (e.g., "free," "jobs," "DIY")
- Add negative keywords β Add at ad group, campaign, or account level depending on relevance
- Choose correct match type β Use Exact for specific terms, Phrase for broader exclusions
- Identify expansion opportunities β Promote high-performing search terms to keywords
- Flag quality issues β Note any terms that indicate poor keyword targeting
- Update negative keyword master list β Document all additions for future reference
- Review regularly β Repeat weekly to catch new irrelevant queries
- Monitor impact β Track how negative keywords improve CTR and reduce wasted spend
Deliverable: Updated negative keyword lists; list of search terms promoted to keywords
π KPI Dashboard
Core Metrics Definitions
Impressions
- Definition: Number of times your ad was shown
- Why it matters: Indicates reach and visibility
- Target: Varies by campaign; monitor impression share
Clicks
- Definition: Number of times users clicked your ad
- Why it matters: Shows ad engagement and interest
- Target: Varies by campaign; aim for consistent volume
CTR (Click-Through Rate)
- Definition: (Clicks Γ· Impressions) Γ 100
- Why it matters: Measures ad relevance and appeal
- Target: 3-5% for search campaigns; 0.5-1% for display
- Notion Formula:
prop("Clicks") / prop("Impressions") * 100
CPC (Cost Per Click)
- Definition: Total cost Γ· Total clicks
- Why it matters: Shows how much you pay per click
- Target: Varies by industry; aim to reduce over time
- Notion Formula:
prop("Cost") / prop("Clicks")
Conversions
- Definition: Number of desired actions completed (purchases, leads, signups)
- Why it matters: Direct measure of campaign effectiveness
- Target: Based on business goals and budget
Conversion Rate
- Definition: (Conversions Γ· Clicks) Γ 100
- Why it matters: Shows how well your landing page converts traffic
- Target: 2-5% for most industries; 10%+ for high-intent campaigns
- Notion Formula:
prop("Conversions") / prop("Clicks") * 100
CPA (Cost Per Acquisition)
- Definition: Total cost Γ· Total conversions
- Why it matters: Shows how much you pay per conversion
- Target: Must be lower than customer lifetime value (LTV)
- Notion Formula:
prop("Cost") / prop("Conversions")
ROAS (Return on Ad Spend)
- Definition: Revenue generated Γ· Ad spend
- Why it matters: Measures profitability and ROI
- Target: Minimum 4:1 for ecommerce; varies by business model
- Notion Formula:
prop("Revenue") / prop("Cost")
Quality Score
- Definition: Google's 1-10 rating based on expected CTR, ad relevance, landing page experience
- Why it matters: Higher QS = lower CPCs and better ad positions
- Target: 7-10 (anything below 5 needs immediate attention)
Impression Share
- Definition: (Impressions received Γ· Total eligible impressions) Γ 100
- Why it matters: Shows how often your ad could have shown but didn't
- Target: 80%+ for branded campaigns; 50-70% for competitive terms
- Notion Formula:
prop("Impressions") / prop("Eligible Impressions") * 100
π€ Google Ads Automation Scripts
Script 1: Pause Low-Quality Keywords
Purpose: Automatically pauses keywords with Quality Score below 4 to prevent wasted spend.
How to schedule: Set to run daily at 2 AM
// Pause Low Quality Score Keywords
function main() {
var QUALITY_SCORE_THRESHOLD = 4;
var keywordIterator = AdsApp.keywords()
.withCondition("Status = ENABLED")
.withCondition("QualityScore < " + QUALITY_SCORE_THRESHOLD)
.get();
var pausedCount = 0;
while (keywordIterator.hasNext()) {
var keyword = keywordIterator.next();
keyword.pause();
pausedCount++;
Logger.log("Paused keyword: " + keyword.getText() + " (QS: " + keyword.getQualityScore() + ")");
}
Logger.log("Total keywords paused: " + pausedCount);
// Send email notification
if (pausedCount > 0) {
MailApp.sendEmail({
to: "your-email@example.com",
subject: "Google Ads: " + pausedCount + " Low QS Keywords Paused",
body: "Check Google Ads script logs for details."
});
}
}Script 2: Pause Ads with High Spend and No Conversions
Purpose: Pauses ads that have spent more than $50 with zero conversions in the last 30 days.
How to schedule: Set to run weekly on Monday mornings
// Pause High-Spend, Zero-Conversion Ads
function main() {
var SPEND_THRESHOLD = 50;
var DATE_RANGE = "LAST_30_DAYS";
var adIterator = AdsApp.ads()
.withCondition("Status = ENABLED")
.withCondition("Conversions = 0")
.withCondition("Cost > " + SPEND_THRESHOLD)
.forDateRange(DATE_RANGE)
.get();
var pausedCount = 0;
while (adIterator.hasNext()) {
var ad = adIterator.next();
var stats = ad.getStatsFor(DATE_RANGE);
ad.pause();
pausedCount++;
Logger.log("Paused ad in campaign: " + ad.getCampaign().getName() +
" | Spend: $" + stats.getCost().toFixed(2) + " | Conversions: 0");
}
Logger.log("Total ads paused: " + pausedCount);
if (pausedCount > 0) {
MailApp.sendEmail({
to: "your-email@example.com",
subject: "Google Ads: " + pausedCount + " Zero-Conversion Ads Paused",
body: "Check logs for details on which ads were paused."
});
}
}Script 3: Daily Email Performance Summary
Purpose: Sends a daily email with key metrics from yesterday's performance.
How to schedule: Set to run daily at 8 AM
// Daily Performance Email Summary
function main() {
var DATE_RANGE = "YESTERDAY";
var accountStats = AdsApp.currentAccount().getStatsFor(DATE_RANGE);
var impressions = accountStats.getImpressions();
var clicks = accountStats.getClicks();
var cost = accountStats.getCost();
var conversions = accountStats.getConversions();
var ctr = accountStats.getCtr();
var cpa = conversions > 0 ? cost / conversions : 0;
var emailBody = "Google Ads Daily Performance Summary - " + DATE_RANGE + "\n\n";
emailBody += "Impressions: " + impressions.toLocaleString() + "\n";
emailBody += "Clicks: " + clicks.toLocaleString() + "\n";
emailBody += "CTR: " + (ctr * 100).toFixed(2) + "%\n";
emailBody += "Cost: $" + cost.toFixed(2) + "\n";
emailBody += "Conversions: " + conversions + "\n";
emailBody += "CPA: $" + cpa.toFixed(2) + "\n";
MailApp.sendEmail({
to: "your-email@example.com",
subject: "Google Ads Daily Summary - " + new Date().toLocaleDateString(),
body: emailBody
});
Logger.log(emailBody);
}Script 4: Label Top-Performing Search Queries
Purpose: Automatically labels search queries with 3+ conversions and CPA below target as "Top Performer".
How to schedule: Set to run weekly on Wednesdays
// Label Top-Performing Search Queries
function main() {
var MIN_CONVERSIONS = 3;
var MAX_CPA = 50; // Adjust to your target CPA
var LABEL_NAME = "Top Performer";
// Create label if it doesn't exist
if (!AdsApp.labels().withCondition("Name = '" + LABEL_NAME + "'").get().hasNext()) {
AdsApp.createLabel(LABEL_NAME);
}
var searchQueryReport = AdsApp.report(
"SELECT Query, Conversions, Cost, CampaignName " +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE Conversions >= " + MIN_CONVERSIONS + " " +
"AND Cost / Conversions <= " + MAX_CPA + " " +
"DURING LAST_30_DAYS"
);
var rows = searchQueryReport.rows();
var labeledCount = 0;
while (rows.hasNext()) {
var row = rows.next();
Logger.log("Top performer: " + row["Query"] + " | Conversions: " + row["Conversions"] +
" | CPA: $" + (row["Cost"] / row["Conversions"]).toFixed(2));
labeledCount++;
}
Logger.log("Total top-performing queries identified: " + labeledCount);
MailApp.sendEmail({
to: "your-email@example.com",
subject: "Google Ads: " + labeledCount + " Top Performers Identified",
body: "Check script logs for query details."
});
}Script 5: Auto-Add Negative Keywords Across Campaigns
Purpose: Scans search terms and adds common negative keywords to all campaigns.
How to schedule: Set to run daily at 3 AM
// Auto-Add Negative Keywords
function main() {
var NEGATIVE_KEYWORDS = ["free", "cheap", "jobs", "career", "salary", "diy", "tutorial", "download"];
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
var addedCount = 0;
while (campaignIterator.hasNext()) {
var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
for (var i = 0; i < NEGATIVE_KEYWORDS.length; i++) {
var negativeKeyword = NEGATIVE_KEYWORDS[i];
// Check if negative keyword already exists
var existingNegatives = campaign.negativeKeywords()
.withCondition("Text = '" + negativeKeyword + "'")
.get();
if (!existingNegatives.hasNext()) {
campaign.createNegativeKeyword("[" + negativeKeyword + "]"); // Exact match
addedCount++;
Logger.log("Added negative keyword '" + negativeKeyword + "' to campaign: " + campaign.getName());
}
}
}
Logger.log("Total negative keywords added: " + addedCount);
if (addedCount > 0) {
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads: " + addedCount + " Negative Keywords Added",
body: "Check logs for details."
});
}
}
Script 6: Smart Bid Adjustment for High & Low Performing Keywords
Purpose: Automatically increases bids on high performers and decreases bids on underperformers.
How to schedule: Set to run daily at 1 AM
// Smart Bid Adjustment Script
function main() {
var MIN_CONVERSIONS = 2;
var TARGET_CPA = 50; // Adjust to your target
var BID_INCREASE = 0.15; // 15% increase
var BID_DECREASE = 0.15; // 15% decrease
var MIN_SPEND = 20; // Minimum spend to consider
var keywordIterator = AdsApp.keywords()
.withCondition("Status = ENABLED")
.forDateRange("LAST_14_DAYS")
.get();
var increasedCount = 0;
var decreasedCount = 0;
while (keywordIterator.hasNext()) {
var keyword = [keywordIterator.next](<http://keywordIterator.next>)();
var stats = keyword.getStatsFor("LAST_14_DAYS");
var conversions = stats.getConversions();
var cost = stats.getCost();
var currentBid = keyword.bidding().getCpc();
// High performer: Increase bid
if (conversions >= MIN_CONVERSIONS && (cost / conversions) < TARGET_CPA) {
var newBid = currentBid * (1 + BID_INCREASE);
keyword.bidding().setCpc(newBid);
increasedCount++;
Logger.log("Increased bid for: " + keyword.getText() + " | Old: $" + currentBid.toFixed(2) +
" | New: $" + newBid.toFixed(2));
}
// Low performer: Decrease bid
if (conversions === 0 && cost > MIN_SPEND) {
var newBid = currentBid * (1 - BID_DECREASE);
keyword.bidding().setCpc(newBid);
decreasedCount++;
Logger.log("Decreased bid for: " + keyword.getText() + " | Old: $" + currentBid.toFixed(2) +
" | New: $" + newBid.toFixed(2));
}
}
Logger.log("Bids increased: " + increasedCount + " | Bids decreased: " + decreasedCount);
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads Bid Adjustments: +" + increasedCount + " / -" + decreasedCount,
body: "Check logs for keyword-level details."
});
}
Script 7: Auto-Expand Winning Search Terms into New Keywords
Purpose: Promotes high-performing search terms into keywords.
How to schedule: Set to run weekly on Fridays
// Auto-Expand Winning Search Terms
function main() {
var MIN_CONVERSIONS = 3;
var MAX_CPA = 50; // Adjust to your target CPA
var searchQueryReport = [AdsApp.report](<http://AdsApp.report>)(
"SELECT Query, Conversions, Cost, CampaignId, AdGroupId " +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE Conversions >= " + MIN_CONVERSIONS + " " +
"AND Cost / Conversions <= " + MAX_CPA + " " +
"DURING LAST_30_DAYS"
);
var rows = searchQueryReport.rows();
var addedCount = 0;
while (rows.hasNext()) {
var row = [rows.next](<http://rows.next>)();
var query = row["Query"];
var adGroupId = row["AdGroupId"];
var adGroup = AdsApp.adGroups()
.withIds([adGroupId])
.get()
.next();
// Check if keyword already exists
var existingKeywords = adGroup.keywords()
.withCondition("Text = '" + query + "'")
.get();
if (!existingKeywords.hasNext()) {
adGroup.newKeywordBuilder()
.withText(query)
.build();
addedCount++;
Logger.log("Added new keyword: '" + query + "' to ad group: " + adGroup.getName());
}
}
Logger.log("Total new keywords added: " + addedCount);
if (addedCount > 0) {
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads: " + addedCount + " Winning Search Terms Promoted",
body: "Check logs for details."
});
}
}
Script 8: Budget Rebalancer
Purpose: Reallocates budget from underperforming to top-performing campaigns.
How to schedule: Set to run weekly on Mondays
// Budget Rebalancer Script
function main() {
var BUDGET_CHANGE = 0.10; // 10% adjustment
var MIN_SPEND = 100; // Minimum spend to consider
var campaignData = [];
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.forDateRange("LAST_14_DAYS")
.get();
// Collect campaign performance data
while (campaignIterator.hasNext()) {
var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
var stats = campaign.getStatsFor("LAST_14_DAYS");
var cost = stats.getCost();
var conversions = stats.getConversions();
var cpa = conversions > 0 ? cost / conversions : 999999;
if (cost >= MIN_SPEND) {
campaignData.push({
campaign: campaign,
cpa: cpa,
conversions: conversions,
cost: cost
});
}
}
// Sort by CPA (ascending)
campaignData.sort(function(a, b) { return [a.cpa](<http://a.cpa>) - [b.cpa](<http://b.cpa>); });
var topPerformers = campaignData.slice(0, Math.ceil(campaignData.length * 0.3));
var bottomPerformers = campaignData.slice(-Math.ceil(campaignData.length * 0.3));
// Increase budget for top performers
for (var i = 0; i < topPerformers.length; i++) {
var campaign = topPerformers[i].campaign;
var currentBudget = campaign.getBudget().getAmount();
var newBudget = currentBudget * (1 + BUDGET_CHANGE);
campaign.getBudget().setAmount(newBudget);
Logger.log("Increased budget for: " + campaign.getName() + " | Old: $" + currentBudget.toFixed(2) +
" | New: $" + newBudget.toFixed(2));
}
// Decrease budget for bottom performers
for (var j = 0; j < bottomPerformers.length; j++) {
var campaign = bottomPerformers[j].campaign;
var currentBudget = campaign.getBudget().getAmount();
var newBudget = currentBudget * (1 - BUDGET_CHANGE);
campaign.getBudget().setAmount(newBudget);
Logger.log("Decreased budget for: " + campaign.getName() + " | Old: $" + currentBudget.toFixed(2) +
" | New: $" + newBudget.toFixed(2));
}
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads: Budget Rebalanced Across Campaigns",
body: "Check logs for campaign-level changes."
});
}
Script 9: Quality Score Recovery Script
Purpose: Flags keywords with low Quality Score components and emails recommendations.
How to schedule: Set to run weekly on Tuesdays
// Quality Score Recovery Script
function main() {
var LOW_QS_THRESHOLD = 5;
var report = [AdsApp.report](<http://AdsApp.report>)(
"SELECT CampaignName, AdGroupName, Criteria, QualityScore, " +
"CreativeQualityScore, SearchPredictedCtr, PostClickQualityScore " +
"FROM KEYWORDS_PERFORMANCE_REPORT " +
"WHERE QualityScore < " + LOW_QS_THRESHOLD + " " +
"AND Status = ENABLED " +
"DURING LAST_30_DAYS"
);
var rows = report.rows();
var issues = [];
while (rows.hasNext()) {
var row = [rows.next](<http://rows.next>)();
var keyword = row["Criteria"];
var qs = row["QualityScore"];
var expectedCtr = row["SearchPredictedCtr"];
var adRelevance = row["CreativeQualityScore"];
var lpExperience = row["PostClickQualityScore"];
var recommendations = [];
if (expectedCtr === "Below average" || expectedCtr === "1") {
recommendations.push("Improve ad copy CTR");
}
if (adRelevance === "Below average" || adRelevance === "1") {
recommendations.push("Improve ad relevance to keyword");
}
if (lpExperience === "Below average" || lpExperience === "1") {
recommendations.push("Improve landing page experience");
}
issues.push({
keyword: keyword,
qs: qs,
fixes: recommendations.join(", ")
});
}
if (issues.length > 0) {
var emailBody = "Quality Score Issues Detected:\\n\\n";
for (var i = 0; i < issues.length; i++) {
emailBody += "Keyword: " + issues[i].keyword + " (QS: " + issues[i].qs + ")\\n";
emailBody += "Recommended fixes: " + issues[i].fixes + "\\n\\n";
}
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads: " + issues.length + " Low Quality Score Keywords Flagged",
body: emailBody
});
Logger.log(emailBody);
} else {
Logger.log("No low QS keywords found.");
}
}
Script 10: Ad Extension Checker
Purpose: Scans campaigns for missing or underperforming ad extensions.
How to schedule: Set to run daily at 9 AM
// Ad Extension Health Check Script
function main() {
var issues = [];
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
while (campaignIterator.hasNext()) {
var campaign = [campaignIterator.next](<http://campaignIterator.next>)();
var campaignName = campaign.getName();
// Check for sitelinks
var sitelinks = campaign.extensions().sitelinks().get();
if (!sitelinks.hasNext()) {
issues.push(campaignName + ": Missing sitelinks");
}
// Check for callouts
var callouts = campaign.extensions().callouts().get();
if (!callouts.hasNext()) {
issues.push(campaignName + ": Missing callouts");
}
// Check for structured snippets
var snippets = campaign.extensions().snippets().get();
if (!snippets.hasNext()) {
issues.push(campaignName + ": Missing structured snippets");
}
// Check for phone extensions
var phoneNumbers = campaign.extensions().phoneNumbers().get();
if (!phoneNumbers.hasNext()) {
issues.push(campaignName + ": Missing call extensions");
}
}
if (issues.length > 0) {
var emailBody = "Ad Extension Issues Detected:\\n\\n";
for (var i = 0; i < issues.length; i++) {
emailBody += issues[i] + "\\n";
}
emailBody += "\\nPlease review and add missing extensions to improve ad performance.";
MailApp.sendEmail({
to: "[your-email@example.com](<mailto:your-email@example.com>)",
subject: "Google Ads: " + issues.length + " Extension Issues Found",
body: emailBody
});
Logger.log(emailBody);
} else {
Logger.log("All campaigns have complete ad extensions.");
}
}
π― How to Use This Framework
- Bookmark this page β Keep it accessible for daily reference
- Customize to your needs β Adjust KPI targets, script thresholds, and checklists based on your campaigns
- Schedule scripts in Google Ads β Go to Tools > Bulk Actions > Scripts, paste code, and set frequency
- Review weekly β Use the checklists to ensure nothing slips through the cracks
- Iterate and improve β Track what works, document learnings, and refine your approach
Questions or feedback? Use this framework as your foundation and adapt as you scale your Google Ads expertise.
