AutomationFlowsEmail & Gmail › Sync Mailchimp Unsubscribes with Hubspot Crm, Slack, Google Sheets and Gmail

Sync Mailchimp Unsubscribes with Hubspot Crm, Slack, Google Sheets and Gmail

ByAvkash Kakdiya @itechnotion on n8n.io

This workflow automatically handles every Mailchimp unsubscribe event by capturing the contact details, syncing the status to HubSpot, alerting the team on Slack, logging the record to Google Sheets, and sending the user a confirmation email — all without any manual effort.…

Event trigger★★★★☆ complexity19 nodesMailchimp TriggerHTTP RequestSlackGoogle SheetsGmail
Email & Gmail Trigger: Event Nodes: 19 Complexity: ★★★★☆ Added:

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

This workflow follows the Gmail → Google Sheets 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": false
  },
  "name": "Mailchimp Unsubscribe Manager",
  "tags": [],
  "nodes": [
    {
      "id": "618a235e-12fd-40eb-ba41-100eb9f14cf5",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        2656
      ],
      "parameters": {
        "width": 496,
        "height": 640,
        "content": "## Mailchimp Unsubscribe Manager\nThis workflow automatically handles people who unsubscribe from Mailchimp emails. When someone clicks unsubscribe, the workflow updates their information in HubSpot, sends alerts in Slack, stores the details in Google Sheets, and sends a confirmation email to the user. It helps the team keep customer records updated without doing manual work. The workflow also keeps a proper log of all unsubscribe activities for future tracking.\n\n### How it works\n\n\t\u2022\tThe workflow starts when someone unsubscribes from a Mailchimp email list.\n\t\u2022\tIt collects and organizes the user details like name and email.\n\t\u2022\tThe workflow checks whether the person already exists in HubSpot.\n\t\u2022\tIf the contact exists, the status is updated to \u201cUnsubscribed\u201d.\n\t\u2022\tIf the contact does not exist, a new contact is created.\n\t\u2022\tSlack notifications are sent to inform the team.\n\t\u2022\tThe details are saved in Google Sheets and a confirmation email is sent to the user.\n\n### Setup Steps\n\n\t1.\tConnect your Mailchimp account to receive unsubscribe events.\n\t2.\tConnect your HubSpot account for contact search and updates.\n\t3.\tConnect Slack to send team alerts and activity logs.\n\t4.\tConnect Google Sheets to save unsubscribe records.\n\t5.\tConnect Gmail to send confirmation emails to users."
      },
      "typeVersion": 1
    },
    {
      "id": "1d0be3d8-1c67-4441-9f30-0d99a5bce4eb",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1472,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 640,
        "content": "## Step 1 \u2013 Detect Unsubscribe Activity\n\nThis step starts the workflow when someone unsubscribes from Mailchimp. The workflow collects important user details like name, email, and audience name. It also cleans and organizes the data into a simple format. This makes the next workflow steps easier and more accurate."
      },
      "typeVersion": 1
    },
    {
      "id": "eea959e1-985a-49a7-890f-c01e07cd9a5a",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 640,
        "content": "## Step 2 \u2013 Check Contact in HubSpot\n\nThis step checks whether the unsubscribed person already exists in HubSpot. The workflow searches using the user\u2019s email address. If the contact exists, the workflow updates the record. If the contact does not exist, a new contact is prepared."
      },
      "typeVersion": 1
    },
    {
      "id": "e6937eab-874c-4e3c-9454-f679aeb851c5",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -528,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 640,
        "content": "## Step 3 \u2013 Update or Create Contact\n\nThis step updates the contact status in HubSpot. Existing users are marked as \u201cUnsubscribed\u201d automatically. New contacts are created if they are not already available. This helps maintain accurate customer records in the CRM system."
      },
      "typeVersion": 1
    },
    {
      "id": "d3aad83f-9adc-4d4d-b9c7-d3522ced649d",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 640,
        "content": "## Step 4 \u2013 Send Slack Notifications\n\nThis step prepares unsubscribe details for the team. A Slack alert message is sent to notify the team instantly. Another log message is also saved for tracking purposes. This helps the team monitor unsubscribe activity easily."
      },
      "typeVersion": 1
    },
    {
      "id": "790c94fa-a1f6-4cf5-80de-a351a5a01743",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 640,
        "content": "## Step 6 \u2013 Complete Workflow\n\nThis final step marks the workflow as completed successfully. It creates a summary of all completed actions. The workflow records the processing time and status. This helps in future tracking and monitoring of the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "9fcf549c-e4c0-460b-ae84-91fb0ab0bd74",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        2656
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 640,
        "content": "## Step 5 \u2013 Save Data and Send Email\n\nThis step stores unsubscribe details in Google Sheets. Information like email, name, audience, and reason is saved automatically. The workflow also sends a confirmation email to the user. This confirms that the unsubscribe request was completed successfully."
      },
      "typeVersion": 1
    },
    {
      "id": "60334951-402b-4770-bed1-c8e23c956a1e",
      "name": "Mailchimp - Unsubscribe Trigger",
      "type": "n8n-nodes-base.mailchimpTrigger",
      "position": [
        -1424,
        3104
      ],
      "parameters": {
        "list": "",
        "events": [
          "unsubscribe"
        ],
        "sources": [
          "user"
        ]
      },
      "credentials": {
        "mailchimpApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2aa21a8f-78fe-4656-afcd-bc0d2e24c96d",
      "name": "Set - Normalize & Enrich Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -1184,
        3104
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n  const raw = item.json;\n\n  // \u2500\u2500 STEP 1: Detect Shape \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  const keys = Object.keys(raw);\n  const isBracketFormat = keys.some(k => k.includes('['));\n\n  function parseBracketKeys(flatObj) {\n    const out = {};\n    for (const [rawKey, val] of Object.entries(flatObj)) {\n      const parts = rawKey\n        .replace(/\\]/g, '')\n        .split('[')\n        .map(p => p.trim())\n        .filter(Boolean);\n\n      let cursor = out;\n      for (let i = 0; i < parts.length - 1; i++) {\n        const part = parts[i];\n        if (cursor[part] === undefined || typeof cursor[part] !== 'object') {\n          cursor[part] = {};\n        }\n        cursor = cursor[part];\n      }\n      cursor[parts[parts.length - 1]] = val;\n    }\n    return out;\n  }\n\n  // \u2500\u2500 STEP 3: Resolve to a unified \"parsed\" object \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  const parsed = isBracketFormat ? parseBracketKeys(raw) : raw;\n\n  const root   = parsed?.data ?? parsed ?? {};\n  const merges = root?.merges ?? root?.merge_fields ?? parsed?.merges ?? parsed?.merge_fields ?? {};\n\n  // \u2500\u2500 STEP 4: Safe first-non-empty resolver \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  function first(...candidates) {\n    for (const v of candidates) {\n      if (v !== null && v !== undefined && String(v).trim() !== '') {\n        return String(v).trim();\n      }\n    }\n    return '';\n  }\n\n  // \u2500\u2500 STEP 5: Extract all fields with exhaustive fallbacks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  const email = first(\n    root?.email,\n    root?.email_address,\n    merges?.EMAIL,\n    parsed?.email,\n    parsed?.email_address\n  );\n\n  const firstName = first(\n    merges?.FNAME,\n    merges?.fname,\n    merges?.first_name,\n    root?.fname,\n    root?.first_name,\n    parsed?.fname\n  );\n\n  const lastName = first(\n    merges?.LNAME,\n    merges?.lname,\n    merges?.last_name,\n    root?.lname,\n    root?.last_name,\n    parsed?.lname\n  );\n\n  // MMERGE3 is your account's custom phone field\n  const phone = first(\n    merges?.PHONE,\n    merges?.phone,\n    merges?.MMERGE3,\n    root?.phone,\n    parsed?.phone\n  );\n\n  const listId = first(\n    root?.list_id,\n    root?.audience_id,\n    parsed?.list_id,\n    parsed?.audience_id\n  );\n\n  const listName = first(\n    root?.list_name,\n    root?.audience_name,\n    parsed?.list_name,\n    parsed?.audience_name\n  ) || 'Main Audience';\n\n  const unsubscribeReason = first(\n    root?.reason,\n    root?.unsubscribe_reason,\n    parsed?.reason,\n    parsed?.['data[reason]']\n  ) || 'manual';\n\n  const campaignId = first(\n    root?.campaign_id,\n    root?.campaignId,\n    parsed?.campaign_id\n  ) || 'N/A';\n\n  const memberRating = Number(\n    root?.member_rating ?? parsed?.member_rating ?? 0\n  ) || 0;\n\n  // \u2500\u2500 STEP 6: Address fields (MMERGE4 in your account) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  const addr = merges?.MMERGE4 ?? {};\n  const address = [addr?.addr1, addr?.city, addr?.state, addr?.zip, addr?.country]\n    .filter(Boolean).join(', ');\n\n  // \u2500\u2500 STEP 7: Computed fields \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  const fullName   = [firstName, lastName].filter(Boolean).join(' ') || email;\n  const now        = new Date();\n  const unsubscribeTimestamp = now.toISOString();\n  const formattedDate = now.toLocaleDateString('en-US', {\n    year: 'numeric', month: 'long', day: 'numeric',\n    hour: '2-digit', minute: '2-digit',\n  });\n\n  // \u2500\u2500 STEP 8: Guard \u2014 never proceed without an email \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  if (!email) {\n    console.error('[Normalizer] No email resolved \u2014 item skipped', JSON.stringify(raw));\n    continue;\n  }\n\n  // \u2500\u2500 STEP 9: Return clean normalized output \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  results.push({\n    json: {\n      email,\n      firstName,\n      lastName,\n      fullName,\n      phone,\n      address,\n\n      listId,\n      listName,\n      unsubscribeReason,\n      campaignId,\n      memberRating,\n\n      unsubscribeTimestamp,\n      formattedDate,\n\n      _raw: raw,\n      _parsed: parsed,\n    },\n  });\n}\n\nreturn results;"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "a8307a91-58e5-4562-95ab-bf8f923c27c9",
      "name": "Update HubSpot Contact",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -368,
        2832
      ],
      "parameters": {
        "url": "=https://api.hubapi.com/crm/v3/objects/contacts/{{ $('HubSpot - Search Contact by Email').item.json.results[0].id }}",
        "method": "PATCH",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "properties.email_optout",
              "value": "true"
            },
            {
              "name": "properties.contact_status",
              "value": "Unsubscribed"
            },
            {
              "name": "properties.unsubscribe_source",
              "value": "Mailchimp"
            },
            {
              "name": "properties.unsubscribe_date",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.unsubscribeTimestamp }}"
            },
            {
              "name": "properties.unsubscribe_reason",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.unsubscribeReason }}"
            },
            {
              "name": "properties.unsubscribe_campaign_id",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.campaignId }}"
            },
            {
              "name": "properties.mailchimp_list_id",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.listId }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "1ec1964c-0a71-4964-898a-249cbdaa817a",
      "name": "Create HubSpot Contact",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -368,
        3008
      ],
      "parameters": {
        "url": "=https://api.hubapi.com/crm/v3/objects/contacts",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "properties.email",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.email }}"
            },
            {
              "name": "properties.firstname",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.firstName }}"
            },
            {
              "name": "properties.lastname",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.lastName }}"
            },
            {
              "name": "properties.phone",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.phone }}"
            },
            {
              "name": "properties.email_optout",
              "value": "true"
            },
            {
              "name": "properties.contact_status",
              "value": "Unsubscribed"
            },
            {
              "name": "properties.unsubscribe_source",
              "value": "Mailchimp"
            },
            {
              "name": "properties.unsubscribe_date",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.unsubscribeTimestamp }}"
            },
            {
              "name": "properties.unsubscribe_reason",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.unsubscribeReason }}"
            },
            {
              "name": "properties.unsubscribe_campaign_id",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.campaignId }}"
            },
            {
              "name": "properties.mailchimp_list_id",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.listId }}"
            },
            {
              "name": "properties.leadsource",
              "value": "Mailchimp"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "c0071322-be67-437d-ad1a-a5b9aaa0d54b",
      "name": "Slack - Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        240,
        2800
      ],
      "parameters": {
        "text": "=\ud83d\udea8 Mailchimp Unsubscribe Alert\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\u2022 Name: {{ $json.fullName }}\n\u2022 Email: {{ $json.email }} \n\u2022 Audience/List: {{ $json.listName }}\n\ud83d\udd52 Unsubscribe Time: {{ $json.unsubscribeDate }}\n\n\u2705 Contact marked as \"Unsubscribed\" in HubSpot.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        },
        "otherOptions": {
          "mrkdwn": true,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "d308140d-3340-4b45-b128-d4188eeeb6a4",
      "name": "Slack - Log to",
      "type": "n8n-nodes-base.slack",
      "position": [
        240,
        3008
      ],
      "parameters": {
        "text": "=\ud83d\udcdd CRM Audit Log \u2014 Unsubscribe Event\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\ud83d\udc64 User Information\n\u2022 Name: {{ $json.fullName }}\n\u2022 Email: {{ $json.email }}\n\n\ud83d\udce8 Mailchimp Details\n\u2022 Audience: {{ $json.listName }}\n\u2022 Campaign ID: {{ $json.campaignId }}\n\u2022 Unsubscribe Reason: {{ $json.unsubscribeReason }}\n\n\ud83c\udfe2 HubSpot Details\n\u2022 Contact ID: {{ $json.hubspotContactId }}\n\u2022 CRM Status: Unsubscribed\n\n\u23f0 Processed At\n\u2022 {{ $json.unsubscribeDate }}\n\n\u2705 Audit event stored successfully.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "e3007394-76a0-421a-9336-e3a2d04ae713",
      "name": "Store Unsubscribe Details in Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        576,
        2912
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $json.email }}",
            "Full Name": "={{ $json.fullName }}",
            "Timestamp": "={{ $('Set - Normalize & Enrich Data').item.json.formattedDate }}",
            "Campaign ID": "={{ $json.campaignId }}",
            "List/Audience": "={{ $json.listName }}",
            "Member Rating": "={{ $json.memberRating }}",
            "HubSpot Status": "Unsubscribed",
            "HubSpot Contact ID": "={{ $json.hubspotContactId }}",
            "Unsubscribe Reason": "={{ $json.unsubscribeReason }}"
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Full Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Full Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "List/Audience",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "List/Audience",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Unsubscribe Reason",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Unsubscribe Reason",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Campaign ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Campaign ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HubSpot Contact ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "HubSpot Contact ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "HubSpot Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "HubSpot Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Member Rating",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Member Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5a6f7376-fd18-4a79-840a-568d97fece82",
      "name": "Send a confirmation email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        576,
        3104
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hi {{ $json.firstName || 'there' }}, \n\nWe've successfully removed you from {{ $json.listName }}. \nYou won't receive any further emails from us.  \n\nIf this was a mistake, you can resubscribe anytime.  \n\n\u2014 The Team",
        "options": {
          "appendAttribution": false
        },
        "subject": "We've received your unsubscribe request",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c78f3c29-8509-4bd5-a739-24015f287c38",
      "name": "Set - Workflow Completion Log",
      "type": "n8n-nodes-base.set",
      "position": [
        1040,
        2912
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "workflowStatus",
              "type": "string",
              "value": "completed"
            },
            {
              "id": "c2",
              "name": "processedAt",
              "type": "string",
              "value": "={{ new Date().toISOString() }}"
            },
            {
              "id": "c3",
              "name": "summary",
              "type": "string",
              "value": "={{ 'Unsubscribe processed for ' + $('Set - Prepare Slack Payload').item.json.email + '. HubSpot updated. Slack notified.' }}"
            },
            {
              "id": "c4",
              "name": "actionsCompleted",
              "type": "array",
              "value": "=[\"mailchimp_event_received\", \"data_normalized\", \"hubspot_contact_updated\", \"email_optout_set\", \"slack_marketing_alerted\", \"slack_audit_logged\"]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "59649f79-9462-4522-9b3c-4c0ef0821190",
      "name": "Set - Prepare Slack Payload",
      "type": "n8n-nodes-base.set",
      "position": [
        -32,
        2912
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b1",
              "name": "hubspotContactId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "b2",
              "name": "hubspotPortalId",
              "type": "string",
              "value": "={{ $json.properties?.hs_object_id || $json.id }}"
            },
            {
              "id": "b4",
              "name": "email",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.email }}"
            },
            {
              "id": "b5",
              "name": "fullName",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.fullName }}"
            },
            {
              "id": "b6",
              "name": "unsubscribeDate",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.formattedDate }}"
            },
            {
              "id": "b7",
              "name": "unsubscribeReason",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.unsubscribeReason }}"
            },
            {
              "id": "b8",
              "name": "listName",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.listName }}"
            },
            {
              "id": "b9",
              "name": "campaignId",
              "type": "string",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.campaignId }}"
            },
            {
              "id": "b10",
              "name": "memberRating",
              "type": "number",
              "value": "={{ $('Set - Normalize & Enrich Data').item.json.memberRating }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "7a80eb77-78ec-4a41-8b46-20e4d14c9ce3",
      "name": "IF - Contact Exists in HubSpot?",
      "type": "n8n-nodes-base.if",
      "position": [
        -704,
        2928
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond_exists",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.total }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c9037a7a-8b5c-4486-9976-90bfe2f7bb58",
      "name": "HubSpot - Search Contact by Email",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -896,
        2928
      ],
      "parameters": {
        "url": "https://api.hubapi.com/crm/v3/objects/contacts/search",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"filterGroups\": [\n    {\n      \"filters\": [\n        {\n          \"propertyName\": \"email\",\n          \"operator\": \"EQ\",\n          \"value\": \"{{ $('Set - Normalize & Enrich Data').item.json.email }}\"\n        }\n      ]\n    }\n  ],\n  \"limit\": 1\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Slack - Alert": {
      "main": [
        [
          {
            "node": "Set - Workflow Completion Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack - Log to": {
      "main": [
        [
          {
            "node": "Set - Workflow Completion Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create HubSpot Contact": {
      "main": [
        [
          {
            "node": "Set - Prepare Slack Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update HubSpot Contact": {
      "main": [
        [
          {
            "node": "Set - Prepare Slack Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set - Prepare Slack Payload": {
      "main": [
        [
          {
            "node": "Slack - Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Slack - Log to",
            "type": "main",
            "index": 0
          },
          {
            "node": "Store Unsubscribe Details in Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set - Normalize & Enrich Data": {
      "main": [
        [
          {
            "node": "HubSpot - Search Contact by Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send a confirmation email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Contact Exists in HubSpot?": {
      "main": [
        [
          {
            "node": "Update HubSpot Contact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create HubSpot Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mailchimp - Unsubscribe Trigger": {
      "main": [
        [
          {
            "node": "Set - Normalize & Enrich Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot - Search Contact by Email": {
      "main": [
        [
          {
            "node": "IF - Contact Exists in HubSpot?",
            "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 workflow automatically handles every Mailchimp unsubscribe event by capturing the contact details, syncing the status to HubSpot, alerting the team on Slack, logging the record to Google Sheets, and sending the user a confirmation email — all without any manual effort.…

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

More Email & Gmail workflows → · Browse all categories →

Related workflows

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

Email & Gmail

This workflow automatically manages every new Calendly booking from start to finish. When a prospect books a meeting, it captures all details, syncs everything to HubSpot, creates a prep task for the

HTTP Request, Calendly Trigger, ClickUp +4
Email & Gmail

Fluidflow Licensing Framework. Uses httpRequest, xero, googleSheetsTrigger, slack. Event-driven trigger; 25 nodes.

HTTP Request, Xero, Google Sheets Trigger +4
Email & Gmail

Stop chasing blurry receipts and manually typing expense data. This workflow creates an intelligent, "snap-and-submit" reimbursement pipeline that hosts photos via UploadToURL, extracts deep data via

Form Trigger, N8N Nodes Uploadtourl, HTTP Request +3
Email & Gmail

Automatically transform resume submissions into comprehensive candidate profiles with AI-powered parsing, GitHub analysis, and instant team notifications. Monitors Gmail for incoming resume attachment

Gmail, Gmail Trigger, @Vlm Run/N8N Nodes Vlmrun +3
Email & Gmail

Hiring teams often struggle with document follow-ups, offer letter generation, and stakeholder communication. Manual checks, email back-and-forth, and missing files slow down hiring and create chaos d

Google Sheets Trigger, HTTP Request, Slack +3