This workflow corresponds to n8n.io template #10920 — we link there as the canonical source.
This workflow follows the Gmail → OpenAI 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 →
{
"id": "7oIlhZtKASFMpBkr",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Google Analytics: Automated Weekly Data Aggregation and Report",
"tags": [
{
"id": "pLjpeop4FvQmVNJ8",
"name": "Google Analytics",
"createdAt": "2025-11-23T02:49:05.512Z",
"updatedAt": "2025-11-23T02:49:05.512Z"
},
{
"id": "RjfUrIwfmq5UpRPb",
"name": "Secops",
"createdAt": "2025-11-23T02:49:05.754Z",
"updatedAt": "2025-11-23T02:49:05.754Z"
},
{
"id": "AiMFg9JZIl9DlUAl",
"name": "Utility",
"createdAt": "2025-11-23T02:49:05.556Z",
"updatedAt": "2025-11-23T02:49:05.556Z"
},
{
"id": "SKGcIjFcqVt94o79",
"name": "\ud83d\udee0\ufe0f In progress",
"createdAt": "2025-11-23T02:49:05.649Z",
"updatedAt": "2025-11-23T02:49:05.649Z"
},
{
"id": "1UjT1Cct4Kl0om7c",
"name": "HR",
"createdAt": "2025-11-23T02:49:05.768Z",
"updatedAt": "2025-11-23T02:49:05.768Z"
}
],
"nodes": [
{
"id": "e6be1436-a0db-49a3-bf27-ac12fca73566",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-864,
-80
],
"parameters": {
"width": 790,
"height": 785,
"content": "## Overview\n\nThe workflow automatically gathers **weekly user and page view metrics**. It then **uses AI to analyze, compare, and compile a summary report**. Finally, it **sends the report** to the manager's email.\n\n## How it works\n\n### Get Data from GA\nAutomatically **retrieve data from Google Analytics (GA) for the two most recent weeks**.\n**Compare the data and calculate the variances** between the two weeks.\n\n### Generate Report\nAutomatically **analyze the data and generate reports using Artificial Intelligence (AI)**.\n**Generate charts** to visualize the data.\n**Export the report to PDF**.\n\n### Send Report\n**Send the report via email to the manager.**\n\n## Set up steps\n\n### Google cloud account\nCreate the [credentials](https://console.cloud.google.com/apis/credentials) and replace them in the workflow.\nPlease [enable](https://console.cloud.google.com/apis/dashboard) the following APIs:\n- Gmail API\n- Google Analytics Admin API\n- Google Analytics Data API\n\n### HTML to PDF account\nYou need to install node HTML to PDF.\nGet [API key](https://pdfmunk.com/api-keys) and replace in the workflow.\n\n"
},
"typeVersion": 1
},
{
"id": "b619e48d-3169-4d76-bf9b-69735c8d870e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 7,
"width": 529,
"height": 520,
"content": "## Get data from Google Analytics"
},
"typeVersion": 1
},
{
"id": "241005a9-68fc-4948-893f-8d043bdc5d32",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
32,
240
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "2b2bf49d-421f-496e-8c6e-cd9229cd64a1",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
2288,
224
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<html>\n <body style=\"font-family: Arial; padding: 20px\">\n \n <div id = \"report\">\n {{ $('Generate chart').item.json.report }}\n </div>\n\n <div id = \"chart\">\n <h3>Comparison Chart</h3>\n Click to view the <a href=\"{{ $json.pdf_url }}\">PDF Report</a>\n </div>\n\n </body>\n</html>",
"options": {},
"subject": "GA: Weekly report"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "3c80b2a3-395d-4c03-97b2-1291ff3934e9",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
0
],
"parameters": {
"color": 7,
"width": 577,
"height": 520,
"content": "## Compare the data from the two weeks and calculate the percentage difference."
},
"typeVersion": 1
},
{
"id": "43e84e81-8b15-4849-a6c3-856d43d03654",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
0
],
"parameters": {
"color": 7,
"width": 289,
"height": 520,
"content": "## Generate Report using AI"
},
"typeVersion": 1
},
{
"id": "29533da2-1397-4fab-98bd-dded8bcc7829",
"name": "Generate Date Range",
"type": "n8n-nodes-base.code",
"position": [
208,
240
],
"parameters": {
"jsCode": "// Tu\u1ea7n n\u00e0y: 7 ng\u00e0y g\u1ea7n nh\u1ea5t\nconst today = new Date();\nconst endThisWeek = today.toISOString().split(\"T\")[0];\n\nconst startThisWeekDate = new Date();\nstartThisWeekDate.setDate(startThisWeekDate.getDate() - 7);\nconst startThisWeek = startThisWeekDate.toISOString().split(\"T\")[0];\n\n// Tu\u1ea7n tr\u01b0\u1edbc: 14\u20137 ng\u00e0y tr\u01b0\u1edbc\nconst endLastWeekDate = new Date();\nendLastWeekDate.setDate(endLastWeekDate.getDate() - 7);\nconst endLastWeek = endLastWeekDate.toISOString().split(\"T\")[0];\n\nconst startLastWeekDate = new Date();\nstartLastWeekDate.setDate(startLastWeekDate.getDate() - 14);\nconst startLastWeek = startLastWeekDate.toISOString().split(\"T\")[0];\n\nreturn [\n {\n json: {\n startThisWeek,\n endThisWeek,\n startLastWeek,\n endLastWeek\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "c4e8eb2a-6ce9-45b0-9281-957cfe9573a3",
"name": "GA This Week",
"type": "n8n-nodes-base.googleAnalytics",
"position": [
400,
128
],
"parameters": {
"endDate": "={{ $json.endThisWeek }}",
"dateRange": "custom",
"startDate": "={{ $json.startThisWeek }}",
"metricsGA4": {
"metricValues": [
{},
{
"listName": "screenPageViews"
}
]
},
"propertyId": {
"__rl": true,
"mode": "list",
"value": "456857722",
"cachedResultUrl": "https://analytics.google.com/analytics/web/#/p456857722/",
"cachedResultName": "BinaryTech"
},
"dimensionsGA4": {
"dimensionValues": [
{}
]
},
"additionalFields": {}
},
"credentials": {
"googleAnalyticsOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "a76ebd18-71e2-4c27-a607-518c8a6dd681",
"name": "GA Last Week",
"type": "n8n-nodes-base.googleAnalytics",
"position": [
400,
320
],
"parameters": {
"endDate": "={{ $json.endLastWeek }}",
"dateRange": "custom",
"startDate": "={{ $json.startLastWeek }}",
"metricsGA4": {
"metricValues": [
{},
{
"listName": "screenPageViews"
}
]
},
"propertyId": {
"__rl": true,
"mode": "list",
"value": "456857722",
"cachedResultUrl": "https://analytics.google.com/analytics/web/#/p456857722/",
"cachedResultName": "BinaryTech"
},
"dimensionsGA4": {
"dimensionValues": [
{}
]
},
"additionalFields": {}
},
"credentials": {
"googleAnalyticsOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "4c1e0568-ab80-4507-a541-d9159aa6b209",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
816,
224
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "5ff4e0a8-ebae-419a-b31e-9127f2c2f67d",
"name": "Extract GA This Week",
"type": "n8n-nodes-base.code",
"position": [
608,
128
],
"parameters": {
"jsCode": "const data = $input.all().map(item => item.json);\n\nconst result = data.reduce(\n (acc, item) => {\n acc.totalUsers += Number(item.totalUsers) || 0;\n acc.screenPageViews += Number(item.screenPageViews) || 0;\n return acc;\n },\n { totalUsers: 0, screenPageViews: 0 }\n);\nreturn {\n this_week: result\n};"
},
"typeVersion": 2
},
{
"id": "a7823974-10d9-4e12-b387-ad918b1a2f38",
"name": "Extract GA Last Week",
"type": "n8n-nodes-base.code",
"position": [
608,
320
],
"parameters": {
"jsCode": "const data = $input.all().map(item => item.json);\n\nconst result = data.reduce(\n (acc, item) => {\n acc.totalUsers += Number(item.totalUsers) || 0;\n acc.screenPageViews += Number(item.screenPageViews) || 0;\n return acc;\n },\n { totalUsers: 0, screenPageViews: 0 }\n);\nreturn {\n last_week: result\n};"
},
"typeVersion": 2
},
{
"id": "5fc3fc8c-0dd3-4534-93c5-5aaf64cb3667",
"name": "Calculate Differences",
"type": "n8n-nodes-base.code",
"position": [
992,
224
],
"parameters": {
"jsCode": "const thisWeek = $input.first().json.this_week;\nconst lastWeek = $input.first().json.last_week;\n\nfunction pctChange(current, previous) {\n if (previous === 0) return 100; \n return ((current - previous) / previous) * 100;\n}\n\nreturn [\n {\n json: {\n users_this_week: thisWeek.totalUsers,\n users_last_week: lastWeek.totalUsers,\n users_change_pct: pctChange(thisWeek.totalUsers, lastWeek.totalUsers),\n pv_this_week: thisWeek.screenPageViews,\n pv_last_week: lastWeek.screenPageViews,\n pv_change_pct: pctChange(thisWeek.screenPageViews, lastWeek.screenPageViews)\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "e8be6b25-8228-42da-a1ea-457df0f71553",
"name": "HTML to PDF",
"type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
"position": [
2016,
224
],
"parameters": {
"html_content": "={{ $json.html }}"
},
"credentials": {
"htmlcsstopdfApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "67c0c17a-ea2c-4cac-995f-80f2e2962744",
"name": "Generate chart",
"type": "n8n-nodes-base.code",
"position": [
1568,
224
],
"parameters": {
"jsCode": "const chartConfig = {\n type: \"bar\",\n data: {\n labels: [\"PageView\", \"Users\"],\n datasets: [\n {\n label: \"This Week\",\n data: [\n $('Calculate Differences').first().json.pv_this_week,\n $('Calculate Differences').first().json.users_this_week\n ]\n },\n {\n label: \"Last Week\",\n data: [\n $('Calculate Differences').first().json.pv_last_week,\n $('Calculate Differences').first().json.users_last_week\n ]\n }\n ]\n }\n};\n\nconst encoded = encodeURIComponent(JSON.stringify(chartConfig));\n\nreturn {\n json: {\n report: $input.first().json.output[0].content[0].text,\n chart_url: `https://quickchart.io/chart?width=400&height=200&c=${encoded}`\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "6d80889d-392a-4f61-896f-37f2a5447e91",
"name": "Report template",
"type": "n8n-nodes-base.html",
"position": [
1824,
224
],
"parameters": {
"html": "<html>\n <body style=\"font-family: Arial; padding: 20px\">\n \n <div id = \"report\">\n {{ $json.report }}\n </div>\n\n <div id = \"chart\">\n <h3>Comparison Chart</h3>\n \n <img src={{ $json.chart_url }} />\n </div>\n\n </body>\n</html>"
},
"typeVersion": 1.2
},
{
"id": "e7a44d04-5c3d-4ff8-85e7-118b1d515a8f",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2224,
0
],
"parameters": {
"color": 7,
"width": 273,
"height": 520,
"content": "## Send report to the person in charge"
},
"typeVersion": 1
},
{
"id": "9088ad75-789a-4fbf-ba7e-8ad9bf48c6f6",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
0
],
"parameters": {
"color": 7,
"width": 241,
"height": 520,
"content": "## Generate Chart"
},
"typeVersion": 1
},
{
"id": "aca56d48-5f90-49b6-ae9a-27bab9959431",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1760,
0
],
"parameters": {
"color": 7,
"width": 433,
"height": 520,
"content": "## SGenerate PDF from Report"
},
"typeVersion": 1
},
{
"id": "3cdb100e-12a9-493d-96d2-70bddf79d934",
"name": "Message a model1",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1184,
224
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"messages": {
"values": [
{
"content": "=Analyze the weekly performance data provided below, comparing the current week to the last week.\n\nRequirements:\n\n1. Concise Summary Report: Generate a brief, bulleted report summarizing the overall performance trend (increase/decrease) for both Users and Page Views (PV).\n\n2. In-Depth Analysis: Identify which metric was the most affected (largest percentage drop) and which was the least affected.\n\n3. Severity Assessment: Given the drops of 24.56% for Users and 17.74% for Page Views, assess whether this decline is critical enough to warrant immediate action.\n\n4. Actionable Recommendations: Based on this significant drop, provide two (2) specific, actionable steps that the operations/marketing team should take immediately to investigate the root cause and reverse the trend.\n\nData:\n{{ JSON.stringify($json, null, 2) }}\n\nOUTPUT FORMATTING INSTRUCTIONS:\n- ONLY return the generated HTML code (no explanations, no ```html, introductory text, or Markdown code blocks).\n- Use the <h4> tag for the main title.\n- Use the <ul> and <li> tags for the summary points.\n- Use the <table> tag to display the raw data comparison."
}
]
}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.8
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "ee2627b8-df23-42c4-89de-06629897ff70",
"connections": {
"Merge": {
"main": [
[
{
"node": "Calculate Differences",
"type": "main",
"index": 0
}
]
]
},
"HTML to PDF": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"GA Last Week": {
"main": [
[
{
"node": "Extract GA Last Week",
"type": "main",
"index": 0
}
]
]
},
"GA This Week": {
"main": [
[
{
"node": "Extract GA This Week",
"type": "main",
"index": 0
}
]
]
},
"Generate chart": {
"main": [
[
{
"node": "Report template",
"type": "main",
"index": 0
}
]
]
},
"Report template": {
"main": [
[
{
"node": "HTML to PDF",
"type": "main",
"index": 0
}
]
]
},
"Message a model1": {
"main": [
[
{
"node": "Generate chart",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Generate Date Range",
"type": "main",
"index": 0
}
]
]
},
"Generate Date Range": {
"main": [
[
{
"node": "GA This Week",
"type": "main",
"index": 0
},
{
"node": "GA Last Week",
"type": "main",
"index": 0
}
]
]
},
"Extract GA Last Week": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Extract GA This Week": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Calculate Differences": {
"main": [
[
{
"node": "Message a model1",
"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.
gmailOAuth2googleAnalyticsOAuth2htmlcsstopdfApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
The workflow automatically gathers weekly user and page view metrics. It then uses AI to analyze, compare, and compile a summary report. Finally, it sends the report to the manager's email.
Source: https://n8n.io/workflows/10920/ — 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.
Get a weekly report on website traffic driven by large language models (LLMs) such as ChatGPT, Perplexity, and Gemini. This workflow helps you track how these tools bring visitors to your site. A week
Personalized Outreach & Follow-Up - Phase 2. Uses googleSheets, openAi, gmail, gmailTrigger. Scheduled trigger; 59 nodes.
A scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation sign
This workflow monitors filesystem sync and backup jobs by validating their execution logs, not by running or inspecting the jobs themselves.
This advanced workflow automates brand monitoring and media coverage tracking for musicians, bands, and music labels. The system uses multiple search queries (dorky) to discover mentions across the we