AutomationFlowsAI & RAG › Generate Weekly Cold Email Performance Reports with Manyreach, Gpt-4.1 & Slack

Generate Weekly Cold Email Performance Reports with Manyreach, Gpt-4.1 & Slack

ByBhavy Shekhaliya @bhavyshekhaliya on n8n.io

This n8n workflow automatically generates weekly performance reports for completed email campaigns from ManyReach, converts them to Google Docs, and shares them via Slack. Schedule: Runs every Monday (weekly) Automates the entire reporting process without manual intervention…

Cron / scheduled trigger★★★★☆ complexityAI-powered17 nodesHTTP RequestOpenAI ChatSlackAgent
AI & RAG Trigger: Cron / scheduled Nodes: 17 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #11222 — we link there as the canonical source.

This workflow follows the Agent → HTTP Request 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "1c6d63fb-c7a7-43b2-a227-869b5a2dbddd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        176
      ],
      "parameters": {
        "width": 736,
        "height": 624,
        "content": "# \ud83d\udce7 ManyReach Weekly Cold Email Campaign Report\ud83d\udcc3\n\nThis workflow automates your weekly cold email reporting. It identifies completed campaigns in ManyReach, uses AI to analyze their performance against industry benchmarks, and generates a professional Google Doc report for your team.\n\n### How it works\n1. **Trigger:** Runs automatically once a week (e.g., Monday mornings).\n2. **Fetch & Filter:** Retrieves all campaigns from ManyReach and filters specifically for campaigns that are marked \"Active\" yet have a status of \"Completed.\"\n3. **AI Analyst:** GPT-4 analyzes the campaign metrics (Open Rate, Reply Rate, Conversions) and writes a strategic report including actionable recommendations.\n4. **Document Generation:** The workflow converts the AI's Markdown report into HTML and uses a custom code node to format it as a native Google Doc.\n5. **Upload & Notify:** The report is uploaded to Google Drive, and a direct link is sent to your Slack channel.\n\n### Setup steps\n1. **Credentials:** Configure credentials for **ManyReach**, **OpenAI**, **Google Drive**, and **Slack**.\n2. **Drive Folder:** Open the **Set Details** node and paste the `drive_folder_id` where you want the reports saved.\n3. **Slack Channel:** Open the **Send a Doc Link** node and select the channel where the team should receive the reports.\n4. **API URL:** Ensure the ManyReach API endpoints in the HTTP nodes match your specific account region if necessary."
      },
      "typeVersion": 1
    },
    {
      "id": "c29b6dab-bd39-4ac3-ace8-2dba69af093e",
      "name": "Fetch All Campaign",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -656,
        448
      ],
      "parameters": {
        "url": "https://app.manyreach.com/api/campaigns",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "100"
            }
          ]
        }
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "910e8d50-c471-4fc2-af38-8e596c5208d3",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -384,
        448
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "954f940a-fe0f-43fb-b86f-75892f45b97e",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        176,
        448
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "69f5e7fa-a6fa-484b-aa8c-d32537d504f4",
      "name": "Filter Active & Completed Campaign",
      "type": "n8n-nodes-base.filter",
      "position": [
        -160,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "22eefede-be0f-4a73-848b-95741e9df874",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.active }}",
              "rightValue": true
            },
            {
              "id": "60e38e2a-c77f-42a9-ac79-e9dfa47fb205",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.campStatus }}",
              "rightValue": "completed"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "147ee7e8-a5e9-49ce-aa4c-c293f2992f0e",
      "name": "4.1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        592,
        640
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1",
          "cachedResultName": "gpt-4.1"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "d1fb31c6-80f0-45b9-8807-94c66f5e5cb4",
      "name": "Markdown -> HTML",
      "type": "n8n-nodes-base.markdown",
      "position": [
        944,
        592
      ],
      "parameters": {
        "mode": "markdownToHtml",
        "options": {
          "emoji": true,
          "tables": true
        },
        "markdown": "={{ $json.output }}"
      },
      "typeVersion": 1
    },
    {
      "id": "2a7317c5-985f-4cdb-9b9a-ec70f929d583",
      "name": "Set Details",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        592
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e7ee03ac-13e3-4fca-a7bc-57c8fc56dc42",
              "name": "document_name",
              "type": "string",
              "value": "=dfdfdfdf"
            },
            {
              "id": "48a07ef2-ae46-4bfc-aa7e-d92a74ef46d6",
              "name": "html_content",
              "type": "string",
              "value": "={{ $json.data }}"
            },
            {
              "id": "22b02fba-ba72-423a-b92f-1191a183a554",
              "name": "drive_folder_id",
              "type": "string",
              "value": ""
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "849c3cb4-d096-4681-9ff4-494046950319",
      "name": "HTML -> Magic \ud83e\ude84",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        592
      ],
      "parameters": {
        "jsCode": "const boundary = 'divider';\nconst docName = $input.first().json.document_name;\n// const folderId = $input.first().json.drive_folder_id;\nconst htmlContent = $input.first().json.html_content;\n\nconst metadata = JSON.stringify({\n  name: docName,\n  mimeType: \"application/vnd.google-apps.document\",\n  // parents: [folderId]\n});\n\nconst htmlWithStyles = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <style>\n    /* Add bottom margin to block elements for spacing */\n    p,\n    ul,\n    ol,\n    table,\n    h1,\n    h2,\n    h3,\n    h4,\n    h5,\n    h6 {\n      margin-bottom: 10pt;\n    }\n\n    h2 {\n      margin-top: 20pt;\n    }\n\n    /* Prevent margin collapse issues or excessive space inside lists */\n    li {\n       margin-bottom: 2pt; /* Optional: small space between list items */\n    }\n\n    /* Remove margin from the last child within common containers if needed */\n    /* This might be overly aggressive, test without it first */\n    /*\n    body > *:last-child,\n    li > *:last-child {\n       margin-bottom: 0;\n    }\n    */\n  </style>\n</head>\n<body>\n  ${htmlContent}\n</body>\n</html>\n`;\n\n// Construct the body with literal \\r\\n ONLY\nlet body = `--${boundary}\\r\\n`;\nbody += `Content-Type: application/json; charset=UTF-8\\r\\n`;\nbody += `\\r\\n`; // Blank line\nbody += `${metadata}\\r\\n`;\nbody += `--${boundary}\\r\\n`;\nbody += `Content-Type: text/html\\r\\n`;\nbody += `\\r\\n`; // Blank line\nbody += `${htmlWithStyles}\\r\\n`; // Add the HTML content\nbody += `--${boundary}--\\r\\n`; // Final boundary\n\nreturn {\n  rawData: body \n};"
      },
      "typeVersion": 2
    },
    {
      "id": "294dd5aa-6ac3-4a69-8b60-5afebc6c239b",
      "name": "Upload Doc",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1472,
        592
      ],
      "parameters": {
        "url": "https://www.googleapis.com/upload/drive/v3/files",
        "body": "={{ $json.rawData }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendQuery": true,
        "contentType": "raw",
        "authentication": "predefinedCredentialType",
        "rawContentType": "multipart/related; boundary=divider",
        "queryParameters": {
          "parameters": [
            {
              "name": "uploadType",
              "value": "multipart"
            },
            {
              "name": "supportsAllDrives",
              "value": "true"
            }
          ]
        },
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "9c64a8a4-057b-432d-a2c5-f41d7947bdca",
      "name": "Send a Doc Link",
      "type": "n8n-nodes-base.slack",
      "position": [
        1648,
        592
      ],
      "parameters": {
        "text": "=Campaign: {{ $('Fetch One Campaign').item.json.data.name }}\n\nReport Link: https://docs.google.com/document/d/{{ $json.id }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09V55TL5JN",
          "cachedResultName": "manyreach"
        },
        "otherOptions": {
          "mrkdwn": true,
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8619ad60-4d30-461e-8903-86c948bd3988",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -928,
        448
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ]
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9e622711-fb52-4ae1-9beb-b48ecc6c795f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        320
      ],
      "parameters": {
        "color": 6,
        "width": 496,
        "height": 304,
        "content": "## 1. Weekly Trigger\n```Fetch All Campaigns every week and fetched campaign used for further nodes```"
      },
      "typeVersion": 1
    },
    {
      "id": "99eb65df-55f8-41b0-b234-c6dc6475cb1b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        320
      ],
      "parameters": {
        "color": 5,
        "width": 448,
        "height": 304,
        "content": "## 2. Filter Data\n```Process Only Active & also Completed Campaign for Generate Report```"
      },
      "typeVersion": 1
    },
    {
      "id": "146dcd2a-d715-4353-b8fc-1709b256233b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        336
      ],
      "parameters": {
        "color": 2,
        "width": 1744,
        "height": 464,
        "content": "## 3. Loop for \n```It process all Campaign individually```"
      },
      "typeVersion": 1
    },
    {
      "id": "41db9f75-f0f9-4e3c-a3c1-a45eb8ae5f2d",
      "name": "Campaign Report Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        592,
        464
      ],
      "parameters": {
        "text": "=# Campaign Details:\n\n- Subject: {{ $json.data.subject }}\n- Body: {{ $json.data.body }}\n- Prospects: {{ $json.data.prospects }}\n- Replies: {{ $json.data.replies }}\n- OpenInitial: {{ $json.data.opensInitial }}\n- ClickInitial: {{ $json.data.clicksInitial }}\n- ReplyInitial: {{ $json.data.repliesInitial }}\n- Conversions: {{ $json.data.conversions }}\n- ConversionsInitial: {{ $json.data.conversionsInitial }}\n- InterestedInitial: {{ $json.data.interestedInitial }}\n- InterestedCount: {{ $json.data.interestedCount }}\n- From Emails: {{ $json.data.from.split(',').length }}\n- Campaign Name: {{ $json.data.name }}\n- Campaign Description: {{ $json.data.desc }}\n- Daily Limit: {{ $json.data.dailyLimit }}\n- conversionTrackingUrlParameter: {{ $json.data.conversionTrackingUrlParameter }}\n- DeactivateIfMissingPlaceholder: {{ $json.data.deactivateIfMissingPlaceholder }}\n- StopCoworkersOnReply: {{ $json.data.stopCoworkersOnReply }}\n- SendUnsubscribeListHeader: {{ $json.data.sendUnsubscribeListHeader }}\n- EspMatchType: {{ $json.data.espMatchType }}\n- EspMatchEnabled: {{ $json.data.espMatchEnabled }}\n- EspLimitEnabled: {{ $json.data.espLimitEnabled }}\n- EspLimitToMS: {{ $json.data.espLimitToMS }}\n- EspLimitToGoogle: {{ $json.data.espLimitToGoogle }}\n- EspLimitToOther: {{ $json.data.espLimitToOther }}\n- textOnlyEmails: {{ $json.data.textOnlyEmails }}",
        "options": {
          "systemMessage": "You are an email campaign analytics expert. Analyze the provided campaign data and generate a comprehensive performance report.\n\n## Campaign Data Provided:\n- Campaign Name & Description\n- Email Content (Subject & Body)\n- Performance Metrics (Prospects, Replies, Opens, Clicks, Conversions, Interested)\n- Configuration Settings (Daily Limit, ESP settings, Email sending options)\n\n## Your Task:\nGenerate a detailed campaign performance report with the following sections:\n\n### 1. Executive Summary\n- Overall campaign performance (success/needs improvement)\n- Key achievements and highlights\n- Critical metrics at a glance\n\n### 2. Performance Metrics Analysis\n- **Engagement Rates:**\n  - Open Rate: (opensInitial / prospects) \u00d7 100\n  - Click Rate: (clicksInitial / prospects) \u00d7 100\n  - Reply Rate: (repliesInitial / prospects) \u00d7 100\n  - Interest Rate: (interestedInitial / prospects) \u00d7 100\n  - Conversion Rate: (conversionsInitial / prospects) \u00d7 100\n\n- Compare these rates against industry benchmarks (typical cold email benchmarks: 40-50% open, 2-5% reply, 1-3% conversion)\n\n### 3. Email Content Analysis\n- Subject line effectiveness\n- Email body assessment (tone, length, clarity)\n- Suggestions for improvement\n\n### 4. Configuration Insights\n- Assessment of daily sending limit appropriateness\n- ESP distribution strategy evaluation\n- Unsubscribe and compliance settings review\n\n### 5. Actionable Recommendations\nProvide 3-5 specific, actionable recommendations for:\n- Improving engagement rates\n- Optimizing email content\n- Adjusting campaign settings\n- Scaling successful strategies\n\n### 6. Next Steps\nSuggest concrete next steps based on the campaign's performance level.\n\n## Output Format:\n- Use clear headings and subheadings\n- Include specific numbers and percentages\n- Be concise but thorough\n- Highlight both strengths and areas for improvement\n- Maintain a professional, constructive tone\n\nGenerate the report in markdown Only now based on the campaign details provided above."
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "ef10b14b-774d-4cfc-8507-1e0ed514e312",
      "name": "Fetch One Campaign",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        416,
        464
      ],
      "parameters": {
        "url": "=https://app.manyreach.com/api/campaigns/{{ $json.campaignID }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth"
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    }
  ],
  "connections": {
    "4.1": {
      "ai_languageModel": [
        [
          {
            "node": "Campaign Report Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Filter Active & Completed Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Doc": {
      "main": [
        [
          {
            "node": "Send a Doc Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Details": {
      "main": [
        [
          {
            "node": "HTML -> Magic \ud83e\ude84",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Fetch One Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a Doc Link": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Markdown -> HTML": {
      "main": [
        [
          {
            "node": "Set Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Fetch All Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Campaign": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch One Campaign": {
      "main": [
        [
          {
            "node": "Campaign Report Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTML -> Magic \ud83e\ude84": {
      "main": [
        [
          {
            "node": "Upload Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Campaign Report Agent": {
      "main": [
        [
          {
            "node": "Markdown -> HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Active & Completed Campaign": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This n8n workflow automatically generates weekly performance reports for completed email campaigns from ManyReach, converts them to Google Docs, and shares them via Slack. Schedule: Runs every Monday (weekly) Automates the entire reporting process without manual intervention…

Source: https://n8n.io/workflows/11222/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

Runs automatically every Monday morning at 8 AM Collects your Google Search Console from the last month and the month before that for a given url (date range is configurable) Formats the data, aggrega

N8N Nodes Pdforge, HTTP Request, OpenAI Chat +2
AI & RAG

This workflow automates end-to-end sustainability lifecycle management for corporate sustainability teams, ESG governance officers, and circular economy programme leads. It addresses the challenge of

Form Trigger, Agent, OpenAI Chat +11
AI & RAG

Marketing, content, and enablement teams that need a quick, human-readable summary of every new video published by the YouTube channels they care about—without leaving Slack.

HTTP Request, Google Sheets, XML +7
AI & RAG

This workflow automates end-to-end ESG (Environmental, Social, and Governance) sustainability reporting for enterprise sustainability teams, compliance officers, and green governance leads. It solves

Agent, OpenAI Chat, Output Parser Structured +12