This workflow corresponds to n8n.io template #14892 — we link there as the canonical source.
This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ef00edf2-80ac-4b81-a346-91f96e1cac4a",
"name": "Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
1952,
784
],
"parameters": {
"width": 508,
"height": 880,
"content": "## Weekly SEO Keyword Report \u2014 GSC + GPT-4o-mini + Gmail\n\nFor SEO agencies and consultants who want to automatically send clients a professional weekly keyword performance digest every Monday morning. The workflow runs on a schedule, pulls the top 10 keywords from Google Search Console for the past 7 days, formats the data, and passes it to a GPT-4o-mini agent that writes a professional email report. Gmail delivers it directly to the client.\n\n## How it works\n- **1. Schedule \u2014 Every Monday 8AM** triggers the workflow automatically each week\n- **2. Set \u2014 Config Values** stores the site URL, client name, recipient email, and agency name\n- **3. HTTP \u2014 Fetch GSC Top Keywords** queries the Google Search Console API for the top 10 keywords\n- **4. Set \u2014 Extract Fields** pulls config values and raw GSC rows into clean named fields\n- **5. Code \u2014 Format Data for GPT** converts raw GSC API rows into readable text for the AI\n- **6. AI Agent \u2014 Write SEO Report Email** uses GPT-4o-mini to write a professional email body\n- **8. Set \u2014 Prepare Final Email** assembles the subject line, recipient, and body into one item\n- **9. Gmail \u2014 Send Weekly Report** delivers the final email to the client\n\n## Set up steps\n1. In **2. Set \u2014 Config Values** \u2014 replace YOUR-WEBSITE.com, YOUR CLIENT NAME, client@example.com, and YOUR AGENCY NAME with real values\n2. In **3. HTTP \u2014 Fetch GSC Top Keywords** \u2014 connect your Google Search Console OAuth2 credential\n3. In **7. OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI credential\n4. In **9. Gmail \u2014 Send Weekly Report** \u2014 connect your Gmail OAuth2 credential\n5. Activate the workflow \u2014 it will run every Monday at 8AM automatically"
},
"typeVersion": 1
},
{
"id": "f4a603e1-91ea-43c8-b8c8-5cbf038ed878",
"name": "Section \u2014 Schedule and Config",
"type": "n8n-nodes-base.stickyNote",
"position": [
2528,
1008
],
"parameters": {
"color": 5,
"width": 404,
"height": 292,
"content": "## Schedule and Config\nWorkflow triggers every Monday at 8AM. Config values \u2014 site URL, client name, recipient email, and agency name \u2014 are set here once and used throughout."
},
"typeVersion": 1
},
{
"id": "b44763f3-c310-4915-ae4c-eae80c76b098",
"name": "Section \u2014 GSC Data Collection",
"type": "n8n-nodes-base.stickyNote",
"position": [
2960,
1008
],
"parameters": {
"color": 6,
"width": 612,
"height": 292,
"content": "## GSC Data Collection\nFetches the top 10 keywords from Google Search Console for the past 7 days. Extracts and formats the raw API response into clean readable text for the AI."
},
"typeVersion": 1
},
{
"id": "cf0e0d81-ceef-4763-a981-91ca9bfb95f5",
"name": "Section \u2014 AI Report Writing",
"type": "n8n-nodes-base.stickyNote",
"position": [
3600,
1008
],
"parameters": {
"color": 6,
"width": 292,
"height": 516,
"content": "## AI Report Writing\nGPT-4o-mini reads the keyword data and writes a professional 150\u2013200 word SEO digest email body with highlights and one actionable tip."
},
"typeVersion": 1
},
{
"id": "c8809f44-2ef6-4fa2-b258-4a6e3095e694",
"name": "Section \u2014 Email Delivery",
"type": "n8n-nodes-base.stickyNote",
"position": [
3952,
1008
],
"parameters": {
"color": 4,
"width": 420,
"height": 372,
"content": "## Email Delivery\nAssembles the subject line, recipient address, and email body into one item. Gmail sends the final report to the client."
},
"typeVersion": 1
},
{
"id": "0b8ed751-7c28-4fb3-be23-f075c931dfb2",
"name": "Note \u2014 Edit Config Before Activating",
"type": "n8n-nodes-base.stickyNote",
"position": [
2704,
1424
],
"parameters": {
"color": 3,
"width": 604,
"content": "## \u26a0\ufe0f Edit This Node Before Activating\nThis is the only node you need to change. Replace all four values before running: siteUrl must match your exact GSC property URL, clientName is the client business name, recipientEmail is where the report goes, and agencyName appears in the email footer."
},
"typeVersion": 1
},
{
"id": "664a732f-0f77-4d3e-816c-1547a5131208",
"name": "1. Schedule \u2014 Every Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
2560,
1152
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "760f4f3d-1c7d-489c-8e65-d59d1dfe22f5",
"name": "2. Set \u2014 Config Values",
"type": "n8n-nodes-base.set",
"position": [
2784,
1152
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "cfg-001",
"name": "siteUrl",
"type": "string",
"value": "https://www.YOUR-WEBSITE.com/"
},
{
"id": "cfg-002",
"name": "clientName",
"type": "string",
"value": "YOUR CLIENT NAME"
},
{
"id": "cfg-003",
"name": "recipientEmail",
"type": "string",
"value": "user@example.com"
},
{
"id": "cfg-004",
"name": "agencyName",
"type": "string",
"value": "YOUR AGENCY NAME"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f402ba28-4931-4230-b425-35a3d6c7ef4a",
"name": "3. HTTP \u2014 Fetch GSC Top Keywords",
"type": "n8n-nodes-base.httpRequest",
"position": [
3008,
1152
],
"parameters": {
"url": "=https://www.googleapis.com/webmasters/v3/sites/{{ encodeURIComponent($json.siteUrl) }}/searchAnalytics/query",
"method": "POST",
"options": {},
"jsonBody": "={\n \"startDate\": \"{{ $now.minus({days: 7}).toFormat('yyyy-MM-dd') }}\",\n \"endDate\": \"{{ $now.minus({days: 1}).toFormat('yyyy-MM-dd') }}\",\n \"dimensions\": [\"query\"],\n \"rowLimit\": 10,\n \"orderby\": [{\"fieldName\": \"clicks\", \"sortOrder\": \"DESCENDING\"}]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "oAuth2",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "0385d709-010c-446d-b059-ff565ad1bf86",
"name": "4. Set \u2014 Extract Fields",
"type": "n8n-nodes-base.set",
"position": [
3232,
1152
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "fld-001",
"name": "siteUrl",
"type": "string",
"value": "={{ $('2. Set \u2014 Config Values').item.json.siteUrl }}"
},
{
"id": "fld-002",
"name": "clientName",
"type": "string",
"value": "={{ $('2. Set \u2014 Config Values').item.json.clientName }}"
},
{
"id": "fld-003",
"name": "recipientEmail",
"type": "string",
"value": "={{ $('2. Set \u2014 Config Values').item.json.recipientEmail }}"
},
{
"id": "fld-004",
"name": "agencyName",
"type": "string",
"value": "={{ $('2. Set \u2014 Config Values').item.json.agencyName }}"
},
{
"id": "fld-005",
"name": "weekStart",
"type": "string",
"value": "={{ $now.minus({days: 7}).toFormat('dd MMM yyyy') }}"
},
{
"id": "fld-006",
"name": "weekEnd",
"type": "string",
"value": "={{ $now.minus({days: 1}).toFormat('dd MMM yyyy') }}"
},
{
"id": "fld-007",
"name": "rawRows",
"type": "string",
"value": "={{ JSON.stringify($json.rows || []) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3d98555c-216c-4652-8613-728ee8734e9f",
"name": "5. Code \u2014 Format Data for GPT",
"type": "n8n-nodes-base.code",
"position": [
3440,
1152
],
"parameters": {
"jsCode": "const item = $input.first().json;\n\nlet rows = [];\ntry {\n rows = JSON.parse(item.rawRows || '[]');\n} catch(e) {\n rows = [];\n}\n\nlet keywordText = '';\nif (rows.length === 0) {\n keywordText = 'No keyword data found for this week. Please check your GSC property URL and credentials.';\n} else {\n rows.forEach((row, i) => {\n const query = (row.keys && row.keys[0]) ? row.keys[0] : 'unknown';\n const clicks = row.clicks || 0;\n const impressions = row.impressions || 0;\n const ctr = ((row.ctr || 0) * 100).toFixed(1);\n const pos = (row.position || 0).toFixed(1);\n keywordText += `${i + 1}. \"${query}\" | Clicks: ${clicks} | Impressions: ${impressions} | CTR: ${ctr}% | Position: ${pos}\\n`;\n });\n}\n\nreturn [{\n json: {\n clientName: item.clientName,\n recipientEmail: item.recipientEmail,\n agencyName: item.agencyName,\n weekStart: item.weekStart,\n weekEnd: item.weekEnd,\n keywordText: keywordText,\n totalKeywords: rows.length\n }\n}];"
},
"typeVersion": 2
},
{
"id": "a35d0f79-8e0c-454e-817f-670a3deea04a",
"name": "6. AI Agent \u2014 Write SEO Report Email",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
3648,
1152
],
"parameters": {
"text": "=You are a professional SEO report writer working for {{ $json.agencyName }}.\n\nYour job is to write a weekly SEO performance digest email for the client.\n\nCLIENT NAME: {{ $json.clientName }}\nREPORT PERIOD: {{ $json.weekStart }} to {{ $json.weekEnd }}\n\nTOP KEYWORDS DATA (Last 7 Days from Google Search Console):\n{{ $json.keywordText }}\n\nWRITING INSTRUCTIONS:\n- Write the full email body only. Do NOT include subject line.\n- Use plain text only. No markdown, no asterisks, no bullet symbols, no hashtags.\n- Keep total length between 150 to 200 words.\n- Paragraph 1: Warm one-line greeting mentioning the client name and the report week.\n- Paragraph 2: Highlight the top 3 keywords by name. Mention their click count and average position. Keep it conversational.\n- Paragraph 3: One positive observation about overall performance this week.\n- Paragraph 4: One clear and actionable SEO tip the client should focus on next week.\n- Closing line: Professional sign-off. Do not write agency name \u2014 just end with 'Best regards,'",
"options": {},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "de0cb10e-3318-40d7-be59-c04fb8692c88",
"name": "7. OpenAI \u2014 GPT-4o-mini Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
3648,
1344
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {
"maxTokens": 500,
"temperature": 0.6
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "c468c676-e253-4b2c-9360-3c24f4b57d4a",
"name": "8. Set \u2014 Prepare Final Email",
"type": "n8n-nodes-base.set",
"position": [
4000,
1152
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "email-001",
"name": "toEmail",
"type": "string",
"value": "={{ $('5. Code \u2014 Format Data for GPT').item.json.recipientEmail }}"
},
{
"id": "email-002",
"name": "emailSubject",
"type": "string",
"value": "=Weekly SEO Report \u2014 {{ $('5. Code \u2014 Format Data for GPT').item.json.weekStart }} to {{ $('5. Code \u2014 Format Data for GPT').item.json.weekEnd }} | {{ $('5. Code \u2014 Format Data for GPT').item.json.clientName }}"
},
{
"id": "email-003",
"name": "emailBody",
"type": "string",
"value": "={{ $json.output || 'Email content could not be generated. Please check OpenAI credentials.' }}"
},
{
"id": "email-004",
"name": "agencyName",
"type": "string",
"value": "={{ $('5. Code \u2014 Format Data for GPT').item.json.agencyName }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "57afe42f-7a8d-4418-b5ee-2204cce645c1",
"name": "9. Gmail \u2014 Send Weekly Report",
"type": "n8n-nodes-base.gmail",
"position": [
4224,
1152
],
"parameters": {
"sendTo": "={{ $json.toEmail }}",
"message": "={{ $json.emailBody }}\n\n--\nThis report was auto-generated by {{ $json.agencyName }}.\nData source: Google Search Console | Powered by n8n + GPT-4o-mini",
"options": {
"appendAttribution": false
},
"subject": "={{ $json.emailSubject }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
}
],
"connections": {
"2. Set \u2014 Config Values": {
"main": [
[
{
"node": "3. HTTP \u2014 Fetch GSC Top Keywords",
"type": "main",
"index": 0
}
]
]
},
"4. Set \u2014 Extract Fields": {
"main": [
[
{
"node": "5. Code \u2014 Format Data for GPT",
"type": "main",
"index": 0
}
]
]
},
"8. Set \u2014 Prepare Final Email": {
"main": [
[
{
"node": "9. Gmail \u2014 Send Weekly Report",
"type": "main",
"index": 0
}
]
]
},
"5. Code \u2014 Format Data for GPT": {
"main": [
[
{
"node": "6. AI Agent \u2014 Write SEO Report Email",
"type": "main",
"index": 0
}
]
]
},
"7. OpenAI \u2014 GPT-4o-mini Model": {
"ai_languageModel": [
[
{
"node": "6. AI Agent \u2014 Write SEO Report Email",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"1. Schedule \u2014 Every Monday 8AM": {
"main": [
[
{
"node": "2. Set \u2014 Config Values",
"type": "main",
"index": 0
}
]
]
},
"3. HTTP \u2014 Fetch GSC Top Keywords": {
"main": [
[
{
"node": "4. Set \u2014 Extract Fields",
"type": "main",
"index": 0
}
]
]
},
"6. AI Agent \u2014 Write SEO Report Email": {
"main": [
[
{
"node": "8. Set \u2014 Prepare Final Email",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Scheduled weekly trigger — Fires automatically every Monday at 8AM so you never miss a reporting week, with zero manual effort.
Source: https://n8n.io/workflows/14892/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform
Created by: Peyton Leveillee Last updated: October 2025
The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe
This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p
SEO Blog Article Generation Workflow. Uses outputParserStructured, httpRequest, agent, lmChatOpenAi. Scheduled trigger; 56 nodes.