This workflow corresponds to n8n.io template #14671 — 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
},
"name": "Brevo Email Campaign Stats \u2192 Weekly Google Sheets Report",
"tags": [],
"nodes": [
{
"id": "3544a224-7ab2-4c3e-8cfe-7a4311dd8e11",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
224,
0
],
"parameters": {
"url": "https://api.brevo.com/v3/emailCampaigns",
"options": {},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "status",
"value": "sent"
},
{
"name": "limit",
"value": "10"
}
]
},
"nodeCredentialType": "sendInBlueApi"
},
"typeVersion": 4.3
},
{
"id": "4057508b-9721-4988-9c84-1c43c432842c",
"name": "Append row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
704,
0
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $json.Date }}",
"Sent": "={{ $json.Sent }}",
"Delivered": "={{ $json.Delivered }}",
"Open Rate": "={{ $json[\"Open Rate\"] }}",
"Click Rate": "={{ $json[\"Click Rate\"] }}",
"Bounce Rate": "={{ $json[\"Bounce Rate\"] }}",
"Campaign Name": "={{ $json[\"Campaign Name\"] }}"
},
"schema": [
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Campaign Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Campaign Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sent",
"type": "string",
"display": true,
"required": false,
"displayName": "Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Delivered",
"type": "string",
"display": true,
"required": false,
"displayName": "Delivered",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Open Rate",
"type": "string",
"display": true,
"required": false,
"displayName": "Open Rate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Click Rate",
"type": "string",
"display": true,
"required": false,
"displayName": "Click Rate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Bounce Rate",
"type": "string",
"display": true,
"required": false,
"displayName": "Bounce Rate",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEET_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit",
"cachedResultName": "Brevo Data"
}
},
"typeVersion": 4.7
},
{
"id": "529e2213-0c10-4474-aebb-0bcc8a84be04",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1792,
0
],
"parameters": {
"text": "=You are a Senior Marketing Analyst. Review this comprehensive campaign data for the last 7 days:\n\n| Campaign | Sent | Delivered | Open Rate | Click Rate | Bounce Rate |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n{{ $json[\"Campaign Name\"].map((name, i) => `| ${name} | ${$json[\"Sent\"][i]} | ${$json[\"Delivered\"][i]} | ${($json[\"Open Rate\"][i] * 100).toFixed(1)}% | ${($json[\"Click Rate\"][i] * 100).toFixed(1)}% | ${($json[\"Bounce Rate\"][i] * 100).toFixed(1)}% |`).join('\\n') }}\n\nWrite a 3-sentence executive summary for the Marketing Lead:\n1. Identify the campaign with the best \"Engagement Depth\" (high Click-to-Open ratio).\n2. Alert the lead if any \"Bounce Rate\" is above or equal to 2% (indicating list health issues).\n3. Suggest a specific strategy for next week based on these conversion trends.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "0003e316-2e42-4244-b721-415e51006de1",
"name": "Groq Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
1864,
224
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"typeVersion": 1
},
{
"id": "74d41cf2-0720-41f1-8812-489aa40c4e31",
"name": "Edit Fields",
"type": "n8n-nodes-base.set",
"position": [
2144,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "40b7af5a-c109-4205-aff1-6a98df5b1be8",
"name": "emailBoady",
"type": "string",
"value": "=<div style=\"font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 700px; margin: auto; border: 1px solid #e0e0e0; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.05);\">\n \n <div style=\"background-color: #1a73e8; color: white; padding: 25px; text-align: center;\">\n <h1 style=\"margin: 0; font-size: 22px;\">Weekly Marketing Intelligence</h1>\n <p style=\"margin: 5px 0 0; opacity: 0.9;\">Reporting Period: {{ $today.minus({days: 7}).toFormat('dd LLL') }} - {{ $today.toFormat('dd LLL yyyy') }}</p>\n </div>\n\n <div style=\"padding: 25px; background-color: #f8f9fa;\">\n <h3 style=\"margin-top: 0; color: #1a73e8; font-size: 16px; display: flex; align-items: center;\">\n <span>\ud83e\udd16 AI Executive Summary</span>\n </h3>\n <p style=\"line-height: 1.6; color: #3c4043; font-style: italic; background: white; padding: 15px; border-radius: 8px; border-left: 4px solid #1a73e8;\">\n \"{{ $json.output }}\"\n </p>\n </div>\n\n <div style=\"padding: 0 25px 25px;\">\n <h3 style=\"color: #3c4043; font-size: 16px;\">Campaign Metrics Breakdown</h3>\n <table style=\"width: 100%; border-collapse: collapse; font-size: 13px;\">\n <thead>\n <tr style=\"border-bottom: 2px solid #eee; color: #70757a;\">\n <th style=\"padding: 12px 5px; text-align: left;\">Campaign</th>\n <th style=\"padding: 12px 5px; text-align: center;\">Delivered</th>\n <th style=\"padding: 12px 5px; text-align: center;\">Open Rate</th>\n <th style=\"padding: 12px 5px; text-align: center;\">Click Rate</th>\n <th style=\"padding: 12px 5px; text-align: center;\">Bounce</th>\n </tr>\n </thead>\n <tbody>\n {{ $node[\"Aggregate weekly data\"].json[\"Campaign Name\"].map((name, i) => `\n <tr style=\"border-bottom: 1px solid #f1f3f4;\">\n <td style=\"padding: 15px 5px; color: #202124;\"><strong>${name}</strong></td>\n <td style=\"padding: 15px 5px; text-align: center; color: #5f6368;\">${$node[\"Aggregate weekly data\"].json[\"Delivered\"][i]}</td>\n <td style=\"padding: 15px 5px; text-align: center; font-weight: bold; color: #188038;\">${($node[\"Aggregate weekly data\"].json[\"Open Rate\"][i] * 100).toFixed(1)}%</td>\n <td style=\"padding: 15px 5px; text-align: center; font-weight: bold; color: #1a73e8;\">${($node[\"Aggregate weekly data\"].json[\"Click Rate\"][i] * 100).toFixed(1)}%</td>\n <td style=\"padding: 15px 5px; text-align: center; color: ${ $node[\"Aggregate weekly data\"].json[\"Bounce Rate\"][i] >= 0.02 ? '#d93025' : '#5f6368' };\">\n ${($node[\"Aggregate weekly data\"].json[\"Bounce Rate\"][i] * 100).toFixed(1)}%\n </td>\n </tr>\n `).join('') }}\n </tbody>\n </table>\n </div>\n\n <div style=\"background-color: #f1f3f4; padding: 15px; text-align: center; font-size: 11px; color: #70757a;\">\n This automated report was generated by n8n Intelligence. Data sourced from Brevo & Google Sheets.\n </div>\n</div>"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d9ab4d26-70d1-46f7-8699-517291e6d2dc",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
2368,
0
],
"parameters": {
"sendTo": "user@example.com",
"message": "={{ $json.emailBoady }}",
"options": {},
"subject": "=\ud83d\ude80 Weekly Marketing Performance Brief: {{ $today.toFormat('dd/MM/yyyy') }}"
},
"typeVersion": 2.2
},
{
"id": "8839952d-ad31-4913-a4f6-2dd6274c0232",
"name": "Get row(s) in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1152,
0
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_SHEET_ID",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_GOOGLE_SHEET_ID/edit",
"cachedResultName": "Brevo Data"
}
},
"typeVersion": 4.7
},
{
"id": "32971d84-6da7-4a23-a8ac-b3f199fed010",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
960,
0
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "92dbdec2-6a0b-42a1-941e-0d5b9d01dcad",
"name": "Filtered 7 days data",
"type": "n8n-nodes-base.code",
"position": [
1344,
0
],
"parameters": {
"jsCode": "// 1. Get the date for exactly 7 days ago\nconst sevenDaysAgo = new Date();\nsevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);\nsevenDaysAgo.setHours(0, 0, 0, 0);\n\nconst weeklyData = [];\n\nfor (const item of items) {\n const rowDate = new Date(item.json.Date);\n\n if (rowDate >= sevenDaysAgo) {\n weeklyData.push({\n json: {\n ...item.json,\n aiContext: `${item.json['Campaign Name']} sent on ${item.json.Date} had a ${item.json['Open Rate']} open rate.`\n }\n });\n }\n}\n\nreturn weeklyData;"
},
"typeVersion": 2
},
{
"id": "7182d6fa-864d-4c30-8b0e-c3576f3763dd",
"name": "Aggregate weekly data",
"type": "n8n-nodes-base.aggregate",
"position": [
1568,
0
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "Campaign Name"
},
{
"fieldToAggregate": "Sent"
},
{
"fieldToAggregate": "Delivered"
},
{
"fieldToAggregate": "Open Rate"
},
{
"fieldToAggregate": "Click Rate"
},
{
"fieldToAggregate": "Bounce Rate"
}
]
}
},
"typeVersion": 1
},
{
"id": "7a362464-dac7-48e7-a0c3-169c51456125",
"name": "Data Cleaning1",
"type": "n8n-nodes-base.code",
"position": [
448,
0
],
"parameters": {
"jsCode": "const campaigns = items[0].json.campaigns || [];\n\nreturn campaigns.map(campaign => {\n const stats = campaign.statistics.campaignStats[0] || {};\n \n const sent = stats.sent || 0;\n const delivered = stats.delivered || 0;\n const opens = stats.uniqueViews || 0;\n const clicks = stats.uniqueClicks || 0;\n const bounces = (stats.softBounces || 0) + (stats.hardBounces || 0);\n\n const openRate = delivered > 0 ? (opens / delivered) : 0;\n const clickRate = delivered > 0 ? (clicks / delivered) : 0;\n const bounceRate = delivered > 0 ? (bounces / delivered) : 0;\n\n return {\n json: {\n \"Campaign Name\": campaign.name,\n \"Date\": campaign.sentDate.split('T')[0],\n \"Sent\": sent,\n \"Delivered\": delivered,\n \"Open Rate\": openRate,\n \"Click Rate\": clickRate,\n \"Bounce Rate\": bounceRate\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "075b271c-3fbc-40da-9605-6c522f545531",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 8
}
]
}
},
"typeVersion": 1.3
},
{
"id": "3489ef20-c734-4d2d-8dfe-7ac8e7cd7f7b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
-320
],
"parameters": {
"width": 592,
"height": 656,
"content": "## Brevo Email Campaign Stats \u2192 Weekly Google Sheets Report\n\n### HOW IT WORKS\nThis workflow serves as an automated \"Bridge\" between marketing execution and executive reporting. It triggers weekly to fetch sent campaign data from the Brevo API. A custom JavaScript layer cleans the raw JSON and calculates high-level metrics (Open, Click, and Bounce rates). This data is archived in Google Sheets to build a long-term performance history. Finally, Google Gemini AI analyzes the latest 7-day trends and generates a 3-sentence executive summary, which is delivered via a professionally formatted HTML Gmail report.\n\n### HOW TO SET UP\n\n**Credentials**: Ensure the HTTP Request node has a valid api-key header from Brevo.\n**Sheet Mapping**: Your Google Sheet must have headers matching the \"Data Cleaning\" node keys (e.g., Campaign Name, Open Rate).\n**AI Logic**: The Gemini node must be in \"Expression\" mode to map the aggregated arrays into a Markdown table.\n**Trigger**: Set the \"Schedule Trigger\" to your preferred reporting day (e.g., Mondays at 08:00).\n\n### CUSTOMIZATION\n\n**Thresholds**: Change the 0.02 (2%) value in the HTML code to adjust the \"Red Alert\" for Bounce Rates.\n**Channels**: Add a Slack or Discord node at the end for instant team notifications.\n**Depth**: Adjust the \"Filter\" node to analyze the last 30 days instead of 7 for monthly reviews."
},
"typeVersion": 1
},
{
"id": "94ba5320-79d4-45ef-bcb9-03d79b2f0ead",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-320
],
"parameters": {
"color": 7,
"width": 640,
"height": 656,
"content": "## STEP 1: Data Acquisition & Cleaning\nNodes: Schedule \u2192 HTTP Request \u2192 Data Cleaning (Code)\nExecution: Triggers the workflow to fetch \"Sent\" campaigns from the Brevo API. The code immediately flattens the nested JSON and calculates the Open, Click, and Bounce rates for the current run."
},
"typeVersion": 1
},
{
"id": "dd5b2369-fb12-4b25-bea9-64b52aa8b0af",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
608,
-320
],
"parameters": {
"color": 7,
"width": 288,
"height": 656,
"content": "## STEP 2: Database Logging\nNode: Append Row (Sheets)\nExecution: Maps the cleaned data fields to a Google Sheet. It appends the current campaign statistics as a new row to create a permanent, historical archive for long-term tracking."
},
"typeVersion": 1
},
{
"id": "0d163f4f-b2ce-4722-9d36-dc85901f4907",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
912,
-320
],
"parameters": {
"color": 7,
"width": 592,
"height": 656,
"content": "## STEP 3: Historical Retrieval & Filtering\nNodes: Aggregate \u2192 Get Rows (Sheets) \u2192 Filtered 7 Days (Code)\nExecution: Pulls the entire database from Google Sheets. The code then strips away any data older than one week, leaving only the relevant \"7-Day Window\" for the current report."
},
"typeVersion": 1
},
{
"id": "db01440f-6dcf-44cd-ba8a-a090194b0d5c",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1520,
-320
],
"parameters": {
"color": 7,
"width": 768,
"height": 656,
"content": "## STEP 4: Weekly Intelligence Analysis\nNodes: Aggregate Weekly Data \u2192 AI Agent (Gemini) \u2192 Edit Fields\nExecution: Bundles the 7-day data into a single object. Gemini analyzes the trends to write an executive summary, and Edit Fields cleans the text for the final email layout."
},
"typeVersion": 1
},
{
"id": "fe9407cc-b739-4b02-b2ff-8860e78f4ae2",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2304,
-320
],
"parameters": {
"color": 7,
"width": 288,
"height": 656,
"content": "## STEP 5: Executive Email Delivery\nNode: Gmail\nExecution: Injects the AI-generated insights and the campaign performance table into a responsive HTML template. It sends the finalized intelligence report to the designated stakeholders."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"connections": {
"AI Agent": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Data Cleaning1",
"type": "main",
"index": 0
}
]
]
},
"Data Cleaning1": {
"main": [
[
{
"node": "Append row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Groq Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Append row in sheet": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "Filtered 7 days data",
"type": "main",
"index": 0
}
]
]
},
"Filtered 7 days data": {
"main": [
[
{
"node": "Aggregate weekly data",
"type": "main",
"index": 0
}
]
]
},
"Aggregate weekly data": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
How it works:
Source: https://n8n.io/workflows/14671/ — 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.
Auto Follow-up Email (AI). Uses gmail, openAi, googleSheets. Scheduled trigger; 7 nodes.
How it works time trigger using the cron format, every weekday at 5pm gets CentralStationCRM people updates of today checks for tag "Outreach" if true, sends message on gmail (predefine in node) waits
This n8n workflow template, "Email Outreach Automation," is designed to help you set up an automated email outreach system using tools you might already be familiar with: Google Sheets and Google Docs
Chasing vendors for overdue Purchase Orders (POs) is a manual, repetitive task that eats up hours of procurement time. This workflow automates that entire process—intelligently.
Stop finding out you're out of stock after a customer already tried to buy. This workflow monitors your entire product inventory daily, calculates how fast each SKU is selling, and automatically raise