AutomationFlowsEmail & Gmail › Manage Employee Offboarding with Google Workspace, Slack, Hubspot and Notion

Manage Employee Offboarding with Google Workspace, Slack, Hubspot and Notion

ByAvkash Kakdiya @itechnotion on n8n.io

This workflow receives an HR offboarding webhook, validates and enriches the employee record, suspends the user in Google Workspace, deactivates the user in Slack, looks up the matching HubSpot contact, logs the event to Notion and Google Sheets, and notifies HR/IT via Gmail and…

Webhook trigger★★★★☆ complexity17 nodesHTTP RequestHubSpotGoogle SheetsGmailSlack
Email & Gmail Trigger: Webhook Nodes: 17 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #16403 — 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
{
  "id": "EEEbK1ShcUtrG40I",
  "name": "Employee Offboarding Compliance & Access Revocation",
  "tags": [
    {
      "id": "2V3HXFbv2wqNGm6s",
      "name": "Dev",
      "createdAt": "2025-06-17T05:42:41.949Z",
      "updatedAt": "2025-06-17T05:42:41.949Z"
    }
  ],
  "nodes": [
    {
      "id": "68b22055-f143-48fd-8757-66c84b9069b7",
      "name": "Overview Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        320
      ],
      "parameters": {
        "width": 496,
        "height": 896,
        "content": "## Employee Offboarding Compliance & Access Revocation\n\nThis workflow automates the full employee offboarding process from start to finish. When an HR system sends an offboarding webhook, the workflow validates the request, revokes access across key tools, notifies relevant teams, logs every action to a compliance sheet, and sends a final summary alert. It ensures no offboarding step is missed, reducing security risk and compliance gaps.\n\n### How it Works\n\n\t- Receives an offboarding trigger from an HR webhook when an employee is marked as departed\n\t- Validates and parses the employee payload to extract name, email, department, and manager\n\t- Checks if the offboarding date is valid and the record is complete\n\t- Enriches the record with risk metadata and sets revocation deadlines\n\t- Suspends the departing employee account in Google Workspace via Admin API\n\t- Disables the user in Slack and posts a heads-up to the IT channel\n\t- Removes the user from all active Notion workspaces and HubSpot\n\t- Logs every revocation action to a Google Sheet compliance tracker\n\t- Sends a final offboarding summary email to the manager and HR via Gmail\n\t- Posts a Slack digest to the IT ops channel confirming all steps completed\n\n### Setup Steps\n\n\t1. Create a webhook trigger URL in n8n and configure your HR system to POST to it on employee departure\n\t2. Add your Google Workspace Admin API credentials (service account with user management scope)\n\t3. Connect your Slack API credential with users:write and chat:write scopes\n\t4. Add HubSpot App Token credential with contacts write access\n\t5. Connect Notion API credential and set your workspace ID\n\t6. Create a Google Sheet named Offboarding Log with columns: Date, Name, Email, Department, Manager, Actions Taken, Status\n\t7. Add Gmail credential for sending summary emails\n\t8. Set the IT Slack channel ID in the Slack notification nodes"
      },
      "typeVersion": 1
    },
    {
      "id": "99cd5e0c-5beb-4f38-b9e5-aae0a5d51fc6",
      "name": "Section Note 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 896,
        "content": "## Step 1: Receive & Validate Offboarding Request\n\nThis section handles the incoming webhook from the HR system and validates the payload. The parser extracts all key employee fields and the IF node ensures only complete, valid records proceed. Invalid or incomplete payloads are dropped before any action is taken, preventing accidental revocations."
      },
      "typeVersion": 1
    },
    {
      "id": "2081eb31-bc65-425f-8d45-6d91ec69743d",
      "name": "Section Note 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 896,
        "height": 896,
        "content": "## Step 2: Enrich Record & Revoke Access\n\nOnce validated, the record is enriched with risk level, revocation deadlines, and a unique offboarding ID. The workflow then fires revocations in parallel across Google Workspace (account suspension), Slack (user deactivation), HubSpot (contact status update), and Notion (workspace removal). Each revocation feeds back into a merge node before logging."
      },
      "typeVersion": 1
    },
    {
      "id": "f392a29f-89d6-4231-9894-18abec2c012e",
      "name": "Section Note 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2304,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 768,
        "height": 896,
        "content": "## Step 3: Log, Notify & Close Out\n\nAfter all revocations are confirmed, the workflow logs the full offboarding record to a Google Sheet compliance tracker. A summary email is dispatched to the employee manager and HR, and a final Slack digest is posted to the IT ops channel confirming that all access has been revoked and the offboarding is complete."
      },
      "typeVersion": 1
    },
    {
      "id": "173d51a3-83ee-40b0-8f54-e954c2b11d70",
      "name": "HR Offboarding Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        800,
        880
      ],
      "parameters": {
        "path": "hr/employee-offboarding",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "6e6bd86e-40a3-4beb-b776-9287ea0bd268",
      "name": "Parse Employee Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        992,
        880
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json;\n\nconst email = (body.email || body.work_email || '').toLowerCase().trim();\nconst firstName = body.first_name || body.firstName || '';\nconst lastName = body.last_name || body.lastName || '';\nconst name = body.name || body.full_name || [firstName, lastName].filter(Boolean).join(' ') || 'Unknown';\nconst employeeId = body.employee_id || body.id || '';\nconst department = body.department || body.team || 'Unknown';\nconst managerEmail = (body.manager_email || body.manager || '').toLowerCase().trim();\nconst offboardingDate = body.offboarding_date || body.last_day || new Date().toISOString().split('T')[0];\nconst role = body.role || body.job_title || 'Unknown';\nconst hrEmail = body.hr_email || 'hr@company.com';\n\nif (!email || !name || name === 'Unknown') {\n  return [{ json: { _invalid: true, reason: 'Missing email or name', raw: body } }];\n}\n\nreturn [{\n  json: {\n    _invalid: false,\n    email,\n    name,\n    firstName,\n    lastName,\n    employeeId,\n    department,\n    managerEmail,\n    offboardingDate,\n    role,\n    hrEmail,\n    parsedAt: new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "19e9433c-7d0c-43b5-9d4f-640c4374a045",
      "name": "Valid Offboarding Record",
      "type": "n8n-nodes-base.if",
      "position": [
        1216,
        880
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "check-invalid",
              "operator": {
                "type": "boolean",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json._invalid }}",
              "rightValue": true
            },
            {
              "id": "check-email",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "3b36a61e-240a-4300-a288-e409c92a8435",
      "name": "Enrich Offboarding Record",
      "type": "n8n-nodes-base.set",
      "position": [
        1440,
        768
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "enrich-id",
              "name": "offboardingId",
              "type": "string",
              "value": "=OB-{{ $now.toFormat('yyyyMMdd') }}-{{ $json.employeeId || Math.random().toString(36).substring(2,8).toUpperCase() }}"
            },
            {
              "id": "enrich-risk",
              "name": "riskLevel",
              "type": "string",
              "value": "={{ ['Engineering','Finance','Legal','Executive'].includes($json.department) ? 'HIGH' : 'STANDARD' }}"
            },
            {
              "id": "enrich-deadline",
              "name": "revocationDeadline",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            },
            {
              "id": "enrich-log-date",
              "name": "logDate",
              "type": "string",
              "value": "={{ $now.toFormat('yyyy-MM-dd HH:mm:ss') }}"
            },
            {
              "id": "enrich-summary",
              "name": "actionsSummary",
              "type": "string",
              "value": "Google Workspace suspended, Slack deactivated, HubSpot updated, Notion removed"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "d0b6c43c-b4a0-4013-83b5-e9e2834938e4",
      "name": "Suspend Google Workspace Account",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1664,
        688
      ],
      "parameters": {
        "url": "=https://admin.googleapis.com/admin/directory/v1/users/{{ $json.email }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "={ \"suspended\": true }",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_GOOGLE_WORKSPACE_ACCESS_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "ccf359d5-3e53-4b69-9384-691a315298a3",
      "name": "Deactivate Slack User",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1664,
        880
      ],
      "parameters": {
        "url": "https://slack.com/api/users.admin.setInactive",
        "method": "POST",
        "options": {},
        "jsonBody": "={ \"email\": \"{{ $('Enrich Offboarding Record').item.json.email }}\" }",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_SLACK_ADMIN_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "e3bdb00d-3f19-484e-9794-bc44a06d74de",
      "name": "Find HubSpot Contact",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1872,
        688
      ],
      "parameters": {
        "limit": 1,
        "operation": "search",
        "authentication": "appToken",
        "filterGroupsUi": {
          "filterGroupsValues": [
            {
              "filtersUi": {
                "filterValues": [
                  {
                    "value": "={{ $('Enrich Offboarding Record').item.json.email }}",
                    "propertyName": "email|string"
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "properties": [
            "email",
            "firstname",
            "lastname",
            "lifecyclestage"
          ]
        }
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "13e3cd7c-2317-4a17-8afe-5d2ba5738e0e",
      "name": "Log to Notion Offboarding DB",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1872,
        880
      ],
      "parameters": {
        "url": "https://api.notion.com/v1/pages",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"parent\": { \"database_id\": \"YOUR_NOTION_DATABASE_ID\" },\n  \"properties\": {\n    \"Name\": { \"title\": [{ \"text\": { \"content\": \"Offboarding: {{ $('Enrich Offboarding Record').item.json.name }}\" } }] },\n    \"Email\": { \"email\": \"{{ $('Enrich Offboarding Record').item.json.email }}\" },\n    \"Status\": { \"select\": { \"name\": \"Access Revoked\" } },\n    \"Date\": { \"date\": { \"start\": \"{{ $('Enrich Offboarding Record').item.json.offboardingDate }}\" } }\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_NOTION_API_KEY"
            },
            {
              "name": "Notion-Version",
              "value": "2022-06-28"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "87dbddbc-fd44-43e2-aea1-c693480d29d2",
      "name": "Merge Revocation Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        2144,
        784
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "7192f5b0-1a92-4bca-ad43-d463fa01b926",
      "name": "Log to Compliance Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2416,
        784
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Enrich Offboarding Record').item.json.logDate }}",
            "Name": "={{ $('Enrich Offboarding Record').item.json.name }}",
            "Role": "={{ $('Enrich Offboarding Record').item.json.role }}",
            "Email": "={{ $('Enrich Offboarding Record').item.json.email }}",
            "Status": "COMPLETED",
            "Manager": "={{ $('Enrich Offboarding Record').item.json.managerEmail }}",
            "Department": "={{ $('Enrich Offboarding Record').item.json.department }}",
            "Risk Level": "={{ $('Enrich Offboarding Record').item.json.riskLevel }}",
            "Actions Taken": "={{ $('Enrich Offboarding Record').item.json.actionsSummary }}",
            "Offboarding ID": "={{ $('Enrich Offboarding Record').item.json.offboardingId }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Offboarding Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "db5b92e6-b767-43e8-9d66-cc32765c906c",
      "name": "Send Offboarding Summary Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2640,
        784
      ],
      "parameters": {
        "sendTo": "={{ $('Enrich Offboarding Record').item.json.managerEmail }},={{ $('Enrich Offboarding Record').item.json.hrEmail }}",
        "message": "=<h2>Employee Offboarding Completed</h2><p>This is an automated confirmation that the offboarding process for the following employee has been completed successfully.</p><table border='1' cellpadding='8' cellspacing='0'><tr><td><strong>Name</strong></td><td>{{ $('Enrich Offboarding Record').item.json.name }}</td></tr><tr><td><strong>Email</strong></td><td>{{ $('Enrich Offboarding Record').item.json.email }}</td></tr><tr><td><strong>Department</strong></td><td>{{ $('Enrich Offboarding Record').item.json.department }}</td></tr><tr><td><strong>Role</strong></td><td>{{ $('Enrich Offboarding Record').item.json.role }}</td></tr><tr><td><strong>Last Day</strong></td><td>{{ $('Enrich Offboarding Record').item.json.offboardingDate }}</td></tr><tr><td><strong>Risk Level</strong></td><td>{{ $('Enrich Offboarding Record').item.json.riskLevel }}</td></tr><tr><td><strong>Offboarding ID</strong></td><td>{{ $('Enrich Offboarding Record').item.json.offboardingId }}</td></tr></table><h3>Actions Completed</h3><ul><li>Google Workspace account suspended</li><li>Slack user deactivated</li><li>HubSpot contact updated</li><li>Notion offboarding record created</li><li>Compliance log entry added</li></ul><p><em>This is an automated message generated by n8n. Please do not reply to this email.</em></p>",
        "options": {},
        "subject": "=Offboarding Complete: {{ $('Enrich Offboarding Record').item.json.name }} ({{ $('Enrich Offboarding Record').item.json.offboardingId }})"
      },
      "typeVersion": 2.1
    },
    {
      "id": "8043d6a6-e407-40d5-b68e-879b2811eddc",
      "name": "Slack IT Ops Digest",
      "type": "n8n-nodes-base.slack",
      "position": [
        2848,
        784
      ],
      "parameters": {
        "text": "=:white_check_mark: *Offboarding Complete* | {{ $('Enrich Offboarding Record').item.json.offboardingId }}\n\n*Employee:* {{ $('Enrich Offboarding Record').item.json.name }}\n*Email:* {{ $('Enrich Offboarding Record').item.json.email }}\n*Department:* {{ $('Enrich Offboarding Record').item.json.department }}\n*Role:* {{ $('Enrich Offboarding Record').item.json.role }}\n*Last Day:* {{ $('Enrich Offboarding Record').item.json.offboardingDate }}\n*Risk Level:* {{ $('Enrich Offboarding Record').item.json.riskLevel }}\n\n*Revocations Confirmed:*\n- :google: Google Workspace - Suspended\n- :slack: Slack - Deactivated\n- :hubspot: HubSpot - Updated\n- :notion: Notion - Record Created\n- :bar_chart: Compliance Sheet - Logged\n\n_All access has been revoked. Offboarding summary emailed to manager and HR._",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_IT_SLACK_CHANNEL_ID"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3618462c-a476-4562-aeb8-64cc946d0b9b",
      "name": "Alert Invalid Record",
      "type": "n8n-nodes-base.slack",
      "position": [
        1440,
        976
      ],
      "parameters": {
        "text": "=:warning: *Invalid Offboarding Record Received* - payload was missing required fields (email or name). Manual review required.\n\n*Reason:* {{ $json.reason }}\n*Received at:* {{ $now.toISO() }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_IT_SLACK_CHANNEL_ID"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b5577069-0e37-44c6-9afa-7ab51797e0ef",
  "connections": {
    "Find HubSpot Contact": {
      "main": [
        [
          {
            "node": "Merge Revocation Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deactivate Slack User": {
      "main": [
        [
          {
            "node": "Log to Notion Offboarding DB",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HR Offboarding Webhook": {
      "main": [
        [
          {
            "node": "Parse Employee Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Employee Payload": {
      "main": [
        [
          {
            "node": "Valid Offboarding Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Compliance Sheet": {
      "main": [
        [
          {
            "node": "Send Offboarding Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Revocation Results": {
      "main": [
        [
          {
            "node": "Log to Compliance Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Valid Offboarding Record": {
      "main": [
        [
          {
            "node": "Enrich Offboarding Record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Alert Invalid Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich Offboarding Record": {
      "main": [
        [
          {
            "node": "Suspend Google Workspace Account",
            "type": "main",
            "index": 0
          },
          {
            "node": "Deactivate Slack User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Notion Offboarding DB": {
      "main": [
        [
          {
            "node": "Merge Revocation Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Send Offboarding Summary Email": {
      "main": [
        [
          {
            "node": "Slack IT Ops Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Suspend Google Workspace Account": {
      "main": [
        [
          {
            "node": "Find HubSpot Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow receives an HR offboarding webhook, validates and enriches the employee record, suspends the user in Google Workspace, deactivates the user in Slack, looks up the matching HubSpot contact, logs the event to Notion and Google Sheets, and notifies HR/IT via Gmail and…

Source: https://n8n.io/workflows/16403/ — 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

Who is this for? This template is ideal for event organizers, conference managers, and community teams who need an automated participant management system. Perfect for workshops, conferences, meetups,

Google Sheets, HTTP Request, Gmail +1
Email & Gmail

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

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

Streamline and standardize your entire client onboarding process with a single end-to-end automation. 🚀📋 This workflow captures detailed client intake data via webhook, automatically creates a fully s

Slack, Asana, HTTP Request +4
Email & Gmail

Human Approval AI Response. Uses httpRequest, slack, gmail, googleSheets. Webhook trigger; 20 nodes.

HTTP Request, Slack, Gmail +2
Email & Gmail

Workflow-Testaeg. Uses googleSheets, httpRequest, gmail, slack. Webhook trigger; 14 nodes.

Google Sheets, HTTP Request, Gmail +1