{
  "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
          }
        ]
      ]
    }
  }
}