Google Sheets + Gmail, competitor ads tracked weekly
You spot a competitor’s new Google ad in the wild, think “we should save that,” and then it disappears the next day. Now you’re stuck with half-remembered headlines and a messy screenshot folder that no one checks.
PPC managers feel this pain weekly. But marketing leads and agency strategists get pulled into it too, because competitor ads tracking automation is the difference between “interesting” and “actionable.” This workflow turns ad watching into a repeatable system that reliably produces insights.
You’ll see how it pulls competitor Google Ads into Google Sheets, runs AI analysis to find themes and angles, then emails a clean report through Gmail so you don’t miss changes again.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Sheets + Gmail, competitor ads tracked weekly
flowchart LR
subgraph sg0["When clicking ‘Execute workflow’ Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Execute workf..", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Fetch Google Search Results .."]
n2@{ icon: "mdi:database", form: "rounded", label: "Get Keywords", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "set keyword", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-vertical", form: "rounded", label: "ads found", pos: "b", h: 48 }
n6@{ icon: "mdi:cog", form: "rounded", label: "No Operation, do nothing1", pos: "b", h: 48 }
n7@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split ads", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
n9@{ icon: "mdi:database", form: "rounded", label: "Top ads", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter1", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>extract ads"]
n12@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model", pos: "b", h: 48 }
n13@{ icon: "mdi:robot", form: "rounded", label: "Value Proposition & Messagin..", pos: "b", h: 48 }
n14@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser3", pos: "b", h: 48 }
n15@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model3", pos: "b", h: 48 }
n16@{ icon: "mdi:cog", form: "rounded", label: "extensions", pos: "b", h: 48 }
n17@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model1", pos: "b", h: 48 }
n18@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model4", pos: "b", h: 48 }
n19@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser4", pos: "b", h: 48 }
n20@{ icon: "mdi:robot", form: "rounded", label: "Site Link Extension Mining", pos: "b", h: 48 }
n21@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model2", pos: "b", h: 48 }
n22@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model5", pos: "b", h: 48 }
n23@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser5", pos: "b", h: 48 }
n24@{ icon: "mdi:cog", form: "rounded", label: "keywords", pos: "b", h: 48 }
n25@{ icon: "mdi:robot", form: "rounded", label: "Keyword-Ad Mapping", pos: "b", h: 48 }
n26["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge1"]
n27@{ icon: "mdi:swap-vertical", form: "rounded", label: "value proposition", pos: "b", h: 48 }
n28@{ icon: "mdi:swap-vertical", form: "rounded", label: "site links", pos: "b", h: 48 }
n29@{ icon: "mdi:swap-vertical", form: "rounded", label: "keywords1", pos: "b", h: 48 }
n30@{ icon: "mdi:brain", form: "rounded", label: "Google Gemini Chat Model6", pos: "b", h: 48 }
n31@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model3", pos: "b", h: 48 }
n32@{ icon: "mdi:robot", form: "rounded", label: "Generate HTML", pos: "b", h: 48 }
n33@{ icon: "mdi:message-outline", form: "rounded", label: "Send a message", pos: "b", h: 48 }
n34@{ icon: "mdi:cog", form: "rounded", label: "value proposition1", pos: "b", h: 48 }
n35@{ icon: "mdi:swap-horizontal", form: "rounded", label: "filter ads", pos: "b", h: 48 }
n26 --> n32
n10 --> n3
n24 --> n25
n7 --> n8
n5 --> n11
n29 --> n26
n16 --> n20
n35 --> n5
n28 --> n26
n8 --> n9
n11 --> n34
n11 --> n16
n11 --> n24
n11 --> n7
n4 --> n1
n2 --> n10
n32 --> n33
n3 --> n4
n3 --> n3
n27 --> n26
n25 --> n29
n34 --> n13
n12 -.-> n13
n17 -.-> n20
n21 -.-> n25
n31 -.-> n32
n15 -.-> n13
n18 -.-> n20
n22 -.-> n25
n30 -.-> n32
n14 -.-> n13
n19 -.-> n20
n23 -.-> n25
n20 --> n28
n1 --> n35
n1 --> n6
n0 --> n2
n13 --> n27
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n13,n14,n19,n20,n23,n25,n32 ai
class n12,n15,n17,n18,n21,n22,n30,n31 aiModel
class n10,n35 decision
class n2,n9 database
class n1 api
class n11 code
classDef customIcon fill:none,stroke:none
class n1,n11,n26 customIcon
The Challenge: Competitor ads change faster than you can log them
Competitor Google Ads are a moving target. Headline tests rotate, sitelinks shift, and suddenly that “new angle” you wanted to reference is gone, replaced by something totally different. The manual process is also weirdly time-consuming: search your keywords, open a few results, copy text into a doc, try to remember which keyword triggered which ad, then share it with your team in a way that doesn’t spark ten follow-up questions. And frankly, it’s easy to skip when you’re busy, which means you only notice changes after performance dips.
It adds up fast. Here’s where it usually breaks down.
- You rely on occasional “spot checks,” so you miss the quiet weekly shifts that explain why CPCs suddenly climbed.
- Copying ad text by hand introduces mistakes, and the mapping between keyword and ad gets muddled almost immediately.
- Screenshots don’t turn into strategy, so the insights stay trapped in Slack threads and personal notes.
- When multiple people track competitors, the format changes every time, which makes comparisons painful.
The Fix: Automatically pull competitor ads, analyze themes, email the report
This workflow starts with a simple source of truth: a Google Sheet where you list high-intent commercial keywords that reliably trigger ads in your niche. On each run, n8n reads that keyword list, sends each keyword to Bright Data’s SERP API (via an HTTP request), and pulls back structured results. If ads are present, it extracts the top and bottom ads, breaks them into individual ad records, and appends the raw results into Google Sheets so you have a historical log. Then the workflow groups the ad text and extension data, sends it through AI analysis (using LangChain-style nodes with chat models), and produces clear insights like messaging themes, value props, and sitelink strategy. Finally, it merges those insights and generates an HTML email report that lands in Gmail, ready to forward to your team or paste into a weekly performance recap.
The workflow begins by pulling keywords from Google Sheets, one batch at a time. From there, Bright Data collects ad payloads from Google search results, and the workflow cleans and stores them. The AI agent then summarizes patterns and sends a readable Gmail report that highlights what changed and what to do next.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you track 25 “money” keywords every week. Manually, you’ll spend maybe 5 minutes per keyword to search, capture top and bottom ads, and paste everything somewhere, which is roughly 2 hours, and that’s before summarizing. With this workflow, updating the keyword sheet takes about 5 minutes and the run happens automatically; you mostly just skim the Gmail report for 10 minutes. The weekly habit stays consistent, even when you’re slammed.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store keywords and ad history.
- Gmail to send the weekly HTML report.
- Bright Data SERP API key (get it from your Bright Data dashboard under SERP API zones).
Skill level: Intermediate. You’ll be comfortable connecting accounts, adding an API key, and editing a prompt without overthinking it.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A keyword list triggers the run. The workflow starts when you manually run it (or schedule it) and it retrieves your competitor-triggering keywords from Google Sheets, filtering out blank rows.
Bright Data pulls live SERP ad results. For each keyword, n8n builds the request parameters and calls the Bright Data SERP API through an HTTP Request node. If the response contains ads, the workflow selects the relevant ad arrays and extracts individual ad items so they’re usable.
Data gets stored, then summarized. Raw ads are appended into a Google Sheet for tracking, and the workflow aggregates ad text plus extension data (like sitelinks). AI nodes then analyze messaging themes, sitelink strategy, and how ads map back to keyword intent, which helps you understand what competitors are pushing and where.
Gmail delivers the report your team will actually read. The insights are merged, formatted into an HTML report by an AI agent, and sent via Gmail to the address you choose.
You can easily modify the keyword list format to include competitor names, target regions, or campaign notes based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
This workflow starts manually, allowing you to test keyword processing and ad intelligence generation on demand.
- Add or open Manual Run Trigger as the trigger node for the workflow.
- Connect Manual Run Trigger to Retrieve Keyword List to pass execution to your keyword source.
- Leave the node settings at defaults since it doesn’t require configuration or credentials.
Step 2: Connect Google Sheets for Keyword Input and Ad Storage
This step pulls the keyword list and appends ad records into the reporting sheet.
- Open Retrieve Keyword List and set Document to
Position Tracking for Keyword + Dashboardand Sheet toKeywords to Track. - Credential Required: Connect your googleSheetsOAuth2Api credentials to Retrieve Keyword List.
- Open Append Top Ads Sheet and set Operation to
append. - Set Document to
Position Tracking for Keyword + Dashboardand Sheet toTop ads. - Credential Required: Connect your googleSheetsOAuth2Api credentials to Append Top Ads Sheet.
⚠️ Common Pitfall: Ensure the sheet columns in Append Top Ads Sheet match the ad fields; mismatches can prevent rows from appending.
Step 3: Filter, Iterate, and Build Search Parameters
These nodes ensure only valid keywords are processed and create the search term payload for the SERP API.
- In Filter Nonempty Keywords, confirm the condition uses
{{ $json.Keyword }}with the notEmpty operator. - In Iterate Keyword Rows, leave Options as default to iterate row-by-row.
- In Assign Search Parameters, set search_term to
{{ $json.Keyword }}and country code to{{ $json['country code'] }}. - Connect Filter Nonempty Keywords → Iterate Keyword Rows → Assign Search Parameters.
Step 4: Configure SERP Request and Ad Extraction Pipeline
This section fetches SERP data, validates payloads, and extracts ad records for downstream analysis and storage.
- In Request SERP JSON, set URL to
https://api.brightdata.com/request, Method toPOST, and enable Send Body, Send Query, and Send Headers. - Set the body parameter url to
https://www.google.com/search?q={{$json.search_term .replaceAll(" ", "+")}}s&start=0&brd_json=1and country to{{ $json['country code'] }}. - Credential Required: Connect your httpHeaderAuth credentials to Request SERP JSON.
- In Validate Ad Payload, verify the condition checks
{{ $json.top_ads }}with lengthGte set to1. - In Select Ad Arrays, set top_ads to
{{ $json.top_ads }}and bottom_ads to{{ $json.bottom_ads }}. - In Extract Ad Items, keep the provided JavaScript that combines ad arrays and returns each ad as a separate item.
- Note that Request SERP JSON also outputs to No-Op Placeholder for debugging; this path can remain unchanged.
Extract Ad Items outputs to both Aggregate Ad Text, Collect Extension Data, Aggregate Keyword Ads, and Split Ad Records in parallel.
Step 5: Configure Data Aggregation and Storage
These nodes transform ad data for AI analysis and append top ads into your sheet.
- In Aggregate Ad Text, set Include to
allFieldsExceptand Fields to Exclude toreferral_link, image, image_base64. - In Collect Extension Data and Aggregate Keyword Ads, keep Fields to Exclude set to
referral_link, image, image_base64, rank, global_rank, image_alt. - In Split Ad Records, set Field to Split Out to
bottom_ads, top_ads. - In Adjust Keyword Field, keep Include Other Fields enabled and set keyword to
Business automations(replace with your desired value if needed). - Connect Adjust Keyword Field → Append Top Ads Sheet to store the ad records.
Step 6: Set Up AI Analysis Chains and Parsers
Three AI analysis chains interpret messaging themes, sitelink strategy, and keyword-to-ad mapping.
- In Analyze Messaging Themes, set Text to
{{ $json.data .toJsonString() }}and keep Needs Fallback enabled. - Ensure OpenRouter Model A and Gemini Model A are connected as language models for Analyze Messaging Themes.
- Credential Required: Connect your openRouterApi credentials to OpenRouter Model A and your googlePalmApi credentials to Gemini Model A.
- In Analyze Sitelink Strategy, set Text to
{{ $json.data.toJsonString() }}and keep Needs Fallback enabled. - Ensure OpenRouter Model B and Gemini Model B are connected as language models for Analyze Sitelink Strategy.
- Credential Required: Connect your openRouterApi credentials to OpenRouter Model B and your googlePalmApi credentials to Gemini Model B.
- In Map Keywords to Ads, set Text to
keyword: {{ $('Assign Search Parameters').item.json.search_term }}.
Ads : {{ $json.data.toJsonString() }} - Ensure OpenRouter Model C and Gemini Model C are connected as language models for Map Keywords to Ads.
- Credential Required: Connect your openRouterApi credentials to OpenRouter Model C and your googlePalmApi credentials to Gemini Model C.
- For parsers (Parse Messaging Output, Parse Sitelink Output, Parse Keyword Mapping), no credentials are needed on the parser nodes; add credentials to their parent AI nodes as above.
- Route outputs through Store Value Insights, Store Sitelink Insights, and Store Keyword Mapping to stage results for the merge step.
⚠️ Common Pitfall: If you update schema examples in the parser nodes, ensure the AI prompts still align with the schema to avoid parsing failures.
Step 7: Merge Insights and Build the HTML Report
This step combines three AI insight streams and formats them into an HTML report.
- In Combine AI Insights, set Mode to
combine, Combine By tocombineByPosition, and Number Inputs to3. - Connect Store Value Insights, Store Sitelink Insights, and Store Keyword Mapping into Combine AI Insights on inputs 0, 1, and 2 respectively.
- In Build HTML Report, set Text to
{{ $json.toJsonString() }}and keep Needs Fallback enabled. - Ensure OpenRouter Model D and Gemini Model D are connected as language models for Build HTML Report.
- Credential Required: Connect your openRouterApi credentials to OpenRouter Model D and your googlePalmApi credentials to Gemini Model D.
Step 8: Configure Email Delivery
Send the HTML report via Gmail with a keyword-specific subject line.
- Open Send Email Report and set To to
[YOUR_EMAIL](replace with a real recipient). - Set Message to
{{ $json.output }}. - Set Subject to
Ads overview report for the Keyword [{{ $('Assign Search Parameters').item.json.search_term }}]. - Credential Required: Connect your gmailOAuth2 credentials to Send Email Report.
Step 9: Test and Activate Your Workflow
Run a full test to confirm the SERP fetch, AI analysis, report generation, and email delivery.
- Click Execute Workflow on Manual Run Trigger to test the full pipeline.
- Verify that Request SERP JSON returns data and that Validate Ad Payload passes items forward.
- Confirm that Build HTML Report outputs HTML and Send Email Report sends an email to your inbox.
- Once successful, set the workflow to Active for production use.
Watch Out For
- Bright Data credentials can expire or need specific permissions. If things break, check your Bright Data SERP API zone settings and token in the n8n credential first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Common Questions
About an hour if your Google Sheet and Bright Data account are ready.
Yes. No coding required, but someone should be comfortable adding API credentials and editing a prompt.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Bright Data SERP API usage and any AI model costs based on how many keywords you analyze.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can. Most people customize the Google Sheets keyword input (add location, device, or competitor notes), then adjust the AI prompts that produce “messaging themes” and “sitelink strategy” so the output matches how your team briefs creative. If you don’t want Gmail, swap the final email step for Slack or another inbox tool, keeping the same HTML report format.
Usually it’s a revoked Google permission or a changed spreadsheet ID. Reconnect the Google Sheets credential in n8n, confirm the exact sheet/tab name still matches, and check that the account has edit access. If it only fails on append, you may also be hitting protected ranges or filters in the destination sheet.
It depends on your plan and how many keywords you run, but dozens of keywords per run is typical. n8n Cloud includes execution limits based on plan, while self-hosting has no execution cap (your server is the limit). The practical constraint is usually Bright Data and model rate limits, so if you scale to hundreds of keywords you may want longer waits or batching.
Often, yes. This workflow needs loops, filtering, branching when ads exist (or don’t), plus multi-step AI analysis and HTML report building, and n8n handles that kind of logic cleanly without turning into a pricing nightmare. Zapier and Make can still work if you simplify the scope, like tracking fewer keywords and skipping the structured AI parsing. If you’re trying to build a dependable weekly competitive intel pipeline, n8n is usually the calmer option. Talk to an automation expert if you want help choosing.
Once this is running, competitor ad monitoring stops being a half-done chore and becomes a weekly asset. The workflow does the collecting and summarizing, so you can focus on what to test next.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.