{
  "id": "3G84Vc8f3LHo8MzB",
  "name": "HR Onboarding Automation \u2014 Slack + Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "dabcbac8-894f-4c3f-9831-5bfc46d668cf",
      "name": "Sticky Note \u2014 Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        912
      ],
      "parameters": {
        "width": 468,
        "height": 624,
        "content": "# \ud83c\udfe2 HR Onboarding Automation\n## Workflow 1 \u2014 Employee Invite Sender\n\n**What this workflow does:**\nWhen HR submits a new employee form, this workflow:\n1. Validates the submitted data\n2. Saves employee record to Google Sheets\n3. Maps department \u2192 Slack channels\n4. Sends a welcome email with Slack invite link\n5. Notifies the manager on Slack\n6. Updates employee status in the sheet\n\n**Trigger:** POST webhook from HR dashboard/form\n**Required fields:** full_name, email, department, role, manager_email, start_date\n\n**Tech Stack:**\n- n8n (automation engine)\n- Google Sheets (employee database)\n- Gmail (welcome email)\n- Slack (manager notification)"
      },
      "typeVersion": 1
    },
    {
      "id": "6f593284-e3eb-4643-ac11-23e4d4aa58d8",
      "name": "Sticky Note \u2014 Webhook",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2096,
        1280
      ],
      "parameters": {
        "color": 6,
        "width": 344,
        "height": 476,
        "content": "## \ud83d\udce5 Step 1 \u2014 Webhook Trigger\n\nThis node listens for POST requests from the HR form/dashboard.\n\n**Endpoint:**\n`POST /webhook/onboard-employee`\n\n**Expected JSON Body:**\n```json\n{\n  \"full_name\": \"Ali Raza\",\n  \"email\": \"ali@company.com\",\n  \"department\": \"Engineering\",\n  \"role\": \"Backend Developer\",\n  \"manager_email\": \"mgr@company.com\",\n  \"start_date\": \"2026-07-15\"\n}\n```\n\n\u26a0\ufe0f Use `/webhook-test/` URL while testing.\nUse `/webhook/` URL in production (workflow must be Active)."
      },
      "typeVersion": 1
    },
    {
      "id": "1c6da62e-0e9f-4ff4-8c09-9020f9b6f17d",
      "name": "Sticky Note \u2014 Validation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2544,
        1280
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 448,
        "content": "## \u2705 Step 2 \u2014 Validation\n\nChecks that these 3 fields are not empty:\n- `full_name`\n- `email`\n- `department`\n\n**TRUE branch \u2192** Continue onboarding\n**FALSE branch \u2192** Return 400 error response\n\nNote: Fields come from `$json.body.*` because n8n wraps webhook payloads in a `body` object."
      },
      "typeVersion": 1
    },
    {
      "id": "7becf4be-8618-47ee-88cf-332522fbaf53",
      "name": "Sticky Note \u2014 Google Sheets Save",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2960,
        1280
      ],
      "parameters": {
        "color": 4,
        "width": 356,
        "height": 484,
        "content": "## \ud83d\udcbe Step 3 \u2014 Save to Google Sheets\n\nAppends a new row to the **Sheet1** tab.\n\n**Columns written:**\nfull_name, email, department, role, manager_email, start_date\n\n**Auto-filled later:**\n- `status` \u2192 updated by this workflow + WF2\n- `slack_invited_at` \u2192 timestamp when invite sent\n- `slack_user_id` \u2192 filled when employee joins Slack\n\n\ud83d\udccc Sheet ID: `1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo`"
      },
      "typeVersion": 1
    },
    {
      "id": "17a57b68-b33b-47d4-b69b-e29df0c03917",
      "name": "Sticky Note \u2014 Channel Mapping",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3424,
        1280
      ],
      "parameters": {
        "color": 4,
        "width": 392,
        "height": 520,
        "content": "## \ud83d\uddc2\ufe0f Step 4 \u2014 Department \u2192 Channel Mapping\n\nMaps each department to relevant Slack channels.\n\n**Current Mapping:**\n- Engineering \u2192 all-testn8n, new-channel\n- Sales \u2192 all-testn8n, social\n- Marketing \u2192 all-testn8n, social\n- HR \u2192 all-testn8n, new-channel\n- Design \u2192 all-testn8n, social\n\nAlso attaches the static **Slack Workspace Invite Link**.\n\n\u26a0\ufe0f Update `SLACK_INVITE_LINK` with a fresh link from:\nSlack \u2192 Workspace name \u2192 Invite people \u2192 Get invite link"
      },
      "typeVersion": 1
    },
    {
      "id": "19ef6658-b7c1-4cf7-b26a-7601a1ab7065",
      "name": "Sticky Note \u2014 Welcome Email",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3920,
        1280
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 532,
        "content": "## \ud83d\udce7 Step 5 \u2014 Welcome Email\n\nSends a welcome email to the new employee.\n\n**Contains:**\n- Personalized greeting with name, role, department\n- Start date\n- Slack workspace invite link (static link)\n- Instructions to click and join\n\n**Gmail credential required.**\n\n\u26a0\ufe0f Non-Enterprise Slack limitation:\nWe cannot auto-create Slack accounts via API.\nEmployee must click the invite link themselves.\nWorkflow 2 handles the rest once they join."
      },
      "typeVersion": 1
    },
    {
      "id": "2b006a9b-25d0-43d3-a16e-9f33cf17c78b",
      "name": "Sticky Note \u2014 Manager Notify",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4352,
        1280
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 468,
        "content": "## \ud83d\udd14 Step 6 \u2014 Notify Manager\n\nSends a Slack DM to the employee's manager.\n\n**Message includes:**\n- Employee name, department, role\n- Start date\n- Channels they'll be added to\n- Confirmation that invite email was sent\n\n**Slack OAuth2 credential required.**\n\nCurrently set to user ID `U0BDTGNCMJQ` for testing.\nIn production: resolve manager's Slack user ID dynamically from their email."
      },
      "typeVersion": 1
    },
    {
      "id": "a17dc09a-3ffa-4918-9797-3b426e0ac7e0",
      "name": "Sticky Note \u2014 Status Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4784,
        1280
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 432,
        "content": "## \ud83d\udcdd Step 7 \u2014 Update Sheet Status\n\nUpdates the employee row in Google Sheets:\n- `status` \u2192 \"Invite Sent\"\n- `slack_invited_at` \u2192 current timestamp\n\nMatches row by `email` column (must be unique).\n\nHR can see in real-time:\n- **Invite Sent** = email sent, waiting to join\n- **Joined** = added to channels \u2713 (set by WF2)"
      },
      "typeVersion": 1
    },
    {
      "id": "f943f1c0-85fc-4647-9713-cba19db83525",
      "name": "Sticky Note \u2014 Setup Checklist",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5216,
        1280
      ],
      "parameters": {
        "color": 2,
        "width": 436,
        "height": 616,
        "content": "## \u2699\ufe0f Setup Checklist\n\n**Before going live, make sure:**\n\n\u2705 Google Sheets has columns:\nfull_name, email, department, role, manager_email, start_date, status, slack_invited_at, slack_user_id\n\n\u2705 Slack App has scopes:\nusers:read, users:read.email, channels:read, channels:manage, chat:write\n\n\u2705 Slack App \u2192 Event Subscriptions \u2192 team_join subscribed\n\n\u2705 Workflow 2 is **Active** (toggle ON in n8n)\n\n\u2705 Bot invited to all target channels (`/invite @DemoApp`)\n\n\u2705 Static Slack invite link updated in 'Map Department + Attach Invite Link' node\n\n\u2705 Department names match exactly:\nEngineering, Sales, Marketing, HR, Design"
      },
      "typeVersion": 1
    },
    {
      "id": "f32264e5-4c61-410b-b7f5-3560e25f035f",
      "name": "Webhook - New Employee Form",
      "type": "n8n-nodes-base.webhook",
      "notes": "POST /webhook/onboard-employee \u2014 HR form trigger",
      "position": [
        2096,
        2176
      ],
      "parameters": {
        "path": "onboard-employee",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "4f951e64-cfb0-4ab2-a874-7fd84835664b",
      "name": "Validate Required Fields",
      "type": "n8n-nodes-base.if",
      "position": [
        2448,
        2176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-001",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.full_name }}",
              "rightValue": ""
            },
            {
              "id": "cond-002",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.email }}",
              "rightValue": ""
            },
            {
              "id": "cond-003",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.department }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ff397acc-bf2c-4987-9efb-18fd1212c4c8",
      "name": "Respond Validation Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2448,
        2432
      ],
      "parameters": {
        "options": {
          "responseCode": 400
        },
        "respondWith": "json",
        "responseBody": "={{ { \"success\": false, \"message\": \"Missing required fields: full_name, email, or department\" } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "f3dee535-3be8-4dad-aeb6-25bdcccbc590",
      "name": "Save Employee to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2800,
        2176
      ],
      "parameters": {
        "columns": {
          "value": {
            "role": "={{ $json.body.role }}",
            "email": "={{ $json.body.email }}",
            "full_name": "={{ $json.body.full_name }}",
            "department": "={{ $json.body.department }}",
            "start_date": "={{ $json.body.start_date }}",
            "manager_email": "={{ $json.body.manager_email }}"
          },
          "schema": [
            {
              "id": "full_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "full_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "department",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "department",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "role",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "role",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "manager_email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "manager_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "start_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "start_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_user_id",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "slack_user_id",
              "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/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "bd69ddd4-8639-4622-9604-83a2a1c115d6",
      "name": "Map Department + Attach Invite Link",
      "type": "n8n-nodes-base.code",
      "position": [
        3152,
        2176
      ],
      "parameters": {
        "jsCode": "const departmentChannelMap = {\n  'Engineering': ['all-testn8n', 'new-channel'],\n  'Sales': ['all-testn8n', 'social'],\n  'Marketing': ['all-testn8n', 'social'],\n  'HR': ['all-testn8n', 'new-channel'],\n  'Design': ['all-testn8n', 'social']\n};\n\nconst dept = $input.first().json.department;\nconst channels = departmentChannelMap[dept] || ['all-testn8n'];\n\nconst SLACK_INVITE_LINK = 'https://join.slack.com/t/testn8n-6i17414/shared_invite/zt-429tad5xx-6dmoOUMbNCJ_TmQpYUrUzA';\n\nreturn [{\n  json: {\n    ...$input.first().json,\n    target_channels: channels,\n    slack_invite_link: SLACK_INVITE_LINK\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "71679aa6-9c29-43de-9a3f-eae57b0131eb",
      "name": "Send Welcome Email with Slack Invite Link",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3504,
        2176
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=<h2>Welcome aboard, {{ $json.full_name }}!</h2><p>We're thrilled to have you join us as <strong>{{ $json.role }}</strong> in the <strong>{{ $json.department }}</strong> team, starting <strong>{{ $json.start_date }}</strong>.</p><p>Step 1: Click the link below to join our Slack workspace:</p><p><a href=\"{{ $json.slack_invite_link }}\">{{ $json.slack_invite_link }}</a></p><p>Once you join, you'll automatically be added to your team's channels and our bot will say hi!</p><p>See you soon!</p>",
        "options": {},
        "subject": "=Welcome to the team, {{ $json.full_name }}! \ud83c\udf89 Join us on Slack"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3bfbe1a8-b545-4fef-8f59-8a869af52b32",
      "name": "Notify Manager on Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        3856,
        2176
      ],
      "parameters": {
        "text": "=:bust_in_silhouette: Heads up! *{{ $('Map Department + Attach Invite Link').item.json.full_name }}* has been sent a Slack invite link.\n\nDepartment: {{ $('Map Department + Attach Invite Link').item.json.department }}\nRole: {{ $('Map Department + Attach Invite Link').item.json.role }}\nStart Date: {{ $('Map Department + Attach Invite Link').item.json.start_date }}\nManager: {{ $('Map Department + Attach Invite Link').item.json.manager_email }}\n\nThey'll be auto-added to: {{ $('Map Department + Attach Invite Link').item.json.target_channels.join(', ') }} once they join the workspace.",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U0BDTGNCMJQ",
          "cachedResultName": "umartkd989"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1766ac45-0bbc-4567-a1a6-d5bab01ef5b3",
      "name": "Update Status: Invite Sent",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4208,
        2176
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Map Department + Attach Invite Link').item.json.email }}",
            "status": "Invite Sent",
            "slack_invited_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_user_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_user_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "f5aa5ea6-1835-4513-b992-4a8b6bdd4003",
      "name": "Respond Success",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        4560,
        2176
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"success\": true, \"message\": \"Onboarding invite sent\", \"employee\": $json.full_name } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "3917c684-423c-4c39-9650-fabb544e7154",
      "name": "Sticky Note \u2014 WF2 Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        2976
      ],
      "parameters": {
        "width": 488,
        "height": 440,
        "content": "# \ud83d\udd17 Workflow 2 \u2014 Slack Team Join Listener\n\n**What this workflow does:**\nListens for Slack's `team_join` event (fired when anyone joins the workspace). When triggered:\n1. Verifies it's a real event (not URL verification challenge)\n2. Extracts new user's email + Slack user ID\n3. Looks up their record in Google Sheets\n4. Maps department to channels\n5. Adds user to each channel one by one\n6. Sends a welcome DM on Slack\n7. Updates sheet status to \"Joined\"\n\n**Setup Required:**\n- Slack App \u2192 Event Subscriptions \u2192 Enable\n- Request URL: `https://umarimran99999.app.n8n.cloud/webhook/slack-team-join`\n- Subscribe to bot event: `team_join`\n- This workflow must be **Active** (toggle ON)\n\n**Required Slack Scopes:**\n`users:read`, `users:read.email`, `channels:read`, `channels:manage`, `chat:write`"
      },
      "typeVersion": 1
    },
    {
      "id": "4659064d-1a52-44d3-a70e-6998e49ee25c",
      "name": "Sticky Note \u2014 Challenge",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        2976
      ],
      "parameters": {
        "color": 6,
        "width": 524,
        "height": 456,
        "content": "## \ud83e\udd1d URL Verification Challenge\n\nWhen you first save the Request URL in Slack's Event Subscriptions, Slack sends a one-time verification request:\n```json\n{ \"type\": \"url_verification\", \"challenge\": \"abc123\" }\n```\n\nThis IF node checks for that.\n\n**TRUE \u2192** Echo back the challenge (Slack marks URL as Verified \u2713)\n**FALSE \u2192** It's a real event, continue processing\n\n\u26a0\ufe0f This workflow must be **Active** and use the production `/webhook/` URL for Slack verification to work."
      },
      "typeVersion": 1
    },
    {
      "id": "2b62e2ce-cdc8-421e-b242-e803af0389d9",
      "name": "Sticky Note \u2014 Acknowledge",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5376,
        2976
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 392,
        "content": "## \u26a1 Acknowledge First, Process Later\n\nSlack requires a response within **3 seconds** or it retries the event (causing duplicate processing).\n\nSo we:\n1. Immediately respond `{ ok: true }` (this node)\n2. Then continue with the actual processing below\n\nThis is standard Slack Events API best practice."
      },
      "typeVersion": 1
    },
    {
      "id": "c5e88551-4348-4c73-96ba-ae7e5d409fd5",
      "name": "Sticky Note \u2014 Extract User",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2784,
        2976
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 412,
        "content": "## \ud83d\udc64 Extract User Info\n\nExtracts from the `team_join` Slack event payload:\n- `slack_user_id` \u2192 user.id (e.g. U0XXXXXXX)\n- `email` \u2192 user.profile.email\n- `real_name` \u2192 user's display name\n\nThese are used to look up the employee in Google Sheets and to send them a welcome DM."
      },
      "typeVersion": 1
    },
    {
      "id": "9d126926-7aab-47a2-b36f-134a2bfd5440",
      "name": "Sticky Note \u2014 Sheet Lookup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3184,
        2976
      ],
      "parameters": {
        "color": 4,
        "width": 276,
        "height": 516,
        "content": "## \ud83d\udd0d Lookup in Google Sheets\n\nSearches Sheet1 for a row where `email` matches the email from Slack's event.\n\nThis connects the Slack join event back to the original onboarding record created by Workflow 1.\n\nReturns: full_name, department, role, manager_email, start_date.\n\n\u26a0\ufe0f If no match found (employee joined via a different email than HR entered), the workflow will fail here. HR should ensure emails match."
      },
      "typeVersion": 1
    },
    {
      "id": "2101f212-0da8-45d5-972e-fdc73715d044",
      "name": "Sticky Note \u2014 Channel Resolution",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3552,
        2976
      ],
      "parameters": {
        "color": 4,
        "width": 284,
        "height": 536,
        "content": "## \ud83d\udd04 Split Channels + Get IDs\n\n**Split Out Channels:**\nBreaks the `target_channels` array into individual items so each channel is processed separately (Slack API accepts one channel per invite call).\n\n**Get Channel ID by Name:**\nCalls `conversations.list` to fetch all workspace channels with their IDs.\n\n**Match Channel Name to ID:**\nFinds the channel whose `name` matches our target, extracts its ID.\n\n\u26a0\ufe0f Channel names must exactly match Slack channel names (no `#` prefix, lowercase)."
      },
      "typeVersion": 1
    },
    {
      "id": "a9887f70-4059-4d27-9fe1-0286b87fe03c",
      "name": "Sticky Note \u2014 Add + DM",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3936,
        2976
      ],
      "parameters": {
        "color": 3,
        "width": 920,
        "height": 424,
        "content": "## \u2795 Add to Channel + Welcome DM\n\n**Add User to Channel:**\nCalls Slack's `conversations.invite` with the resolved channel ID and the new user's Slack ID.\n\n`continueOnFail: true` \u2014 if one channel fails (bot not in channel, wrong ID), it continues to the next instead of stopping.\n\n**Send Welcome DM:**\nSends a personalized direct message to the new employee on Slack with their role and department.\n\n\u26a0\ufe0f Bot must be manually invited to each target channel first:\n`/invite @YourBotName` in each channel"
      },
      "typeVersion": 1
    },
    {
      "id": "a2ed4fa2-7b5b-440a-9627-0a814fece47c",
      "name": "Sticky Note \u2014 Final Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4960,
        2976
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 220,
        "content": "## \u2705 Final Status Update\n\nUpdates the employee's row in Google Sheets:\n- `status` \u2192 \"Joined\"\n- `slack_invited_at` \u2192 current timestamp\n\nMatches by `email` column.\n\nHR can now see in the sheet:\n- **Invite Sent** = email sent, waiting for employee to join\n- **Joined** = employee has joined Slack and been added to channels \u2713"
      },
      "typeVersion": 1
    },
    {
      "id": "98c15458-258c-4d08-b0d1-cbfa3eb72a23",
      "name": "Slack Events Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        2096,
        3984
      ],
      "parameters": {
        "path": "slack-team-join",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "b85cd5c9-15cb-4c16-bab3-073d2b662c9a",
      "name": "Is URL Verification?",
      "type": "n8n-nodes-base.if",
      "position": [
        2448,
        3984
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "is-challenge",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.type }}",
              "rightValue": "url_verification"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2639b8e5-5b2a-432b-8a10-c66ef09553b1",
      "name": "Respond with Challenge",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2800,
        3824
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"challenge\": $json.body.challenge } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "f71938af-97cd-42bd-801a-b2426c8b61c3",
      "name": "Acknowledge Event",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        2800,
        4128
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"ok\": true } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "6d4ec863-5649-43fa-9ed2-5fc0cda5c71d",
      "name": "Extract New User Info",
      "type": "n8n-nodes-base.code",
      "position": [
        3152,
        4128
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json.body;\nconst user = body.event.user;\n\nreturn [{\n  json: {\n    slack_user_id: user.id,\n    email: user.profile.email,\n    real_name: user.profile.real_name || user.real_name\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9b11e812-6b86-4398-8b8b-c25d5e2185bd",
      "name": "Find Employee Row by Email",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3504,
        4128
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.email }}",
              "lookupColumn": "email"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "bc8df802-0a9e-4f15-b22c-51c5265fcabf",
      "name": "Map Department to Channels",
      "type": "n8n-nodes-base.code",
      "position": [
        3856,
        4128
      ],
      "parameters": {
        "jsCode": "const departmentChannelMap = {\n  'Engineering': ['all-testn8n', 'new-channel'],\n  'Sales': ['all-testn8n', 'social'],\n  'Marketing': ['all-testn8n', 'social'],\n  'HR': ['all-testn8n', 'new-channel'],\n  'Design': ['all-testn8n', 'social']\n};\n\nconst employee = $input.first().json;\nconst slackUser = $('Extract New User Info').first().json;\nconst channels = departmentChannelMap[employee.department] || ['all-testn8n'];\n\nreturn [{\n  json: {\n    ...employee,\n    slack_user_id: slackUser.slack_user_id,\n    target_channels: channels\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "180435af-e0f9-4a3a-a2e7-3286785a00b2",
      "name": "Split Out Channels",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        4208,
        4128
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "target_channels"
      },
      "typeVersion": 1
    },
    {
      "id": "5225f452-cdb3-4401-8d9e-bed004c05edc",
      "name": "Get Channel ID by Name",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4560,
        4128
      ],
      "parameters": {
        "url": "https://slack.com/api/conversations.list",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "200"
            }
          ]
        },
        "nodeCredentialType": "slackOAuth2Api"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "ce615af1-c4c4-401c-82c6-12fed79f8b95",
      "name": "Match Channel Name to ID",
      "type": "n8n-nodes-base.code",
      "position": [
        4896,
        4128
      ],
      "parameters": {
        "jsCode": "const channelName = $('Split Out Channels').first().json.target_channels.replace('#', '');\nconst channels = $input.first().json.channels;\n\nconst match = channels.find(c => c.name === channelName || c.name_normalized === channelName);\n\nif (!match) {\n  return [{\n    json: {\n      ...$('Split Out Channels').first().json,\n      channel_id: null,\n      error: `Channel '${channelName}' not found \u2014 check bot is in the channel and name matches exactly`\n    }\n  }];\n}\n\nreturn [{\n  json: {\n    ...$('Split Out Channels').first().json,\n    channel_id: match.id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "5070170a-4014-4e27-8620-e1215160a482",
      "name": "Add User to Channel",
      "type": "n8n-nodes-base.slack",
      "position": [
        5248,
        4128
      ],
      "parameters": {
        "userIds": "={{ $('Extract New User Info').item.json.slack_user_id }}",
        "resource": "channel",
        "channelId": "={{ $json.channel_id }}",
        "operation": "invite",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2,
      "continueOnFail": true
    },
    {
      "id": "04930277-8963-457b-8ec8-75e2e01c36d6",
      "name": "Send Welcome DM",
      "type": "n8n-nodes-base.slack",
      "position": [
        5600,
        4128
      ],
      "parameters": {
        "text": "=:wave: Welcome to the team, *{{ $('Find Employee Row by Email').item.json.full_name }}*! :tada:\n\nYou've been added to your team's channels. Glad to have you here as *{{ $('Find Employee Row by Email').item.json.role }}* in *{{ $('Find Employee Row by Email').item.json.department }}*!\n\nFeel free to say hi in your channels \u2014 the team is excited to meet you! :rocket:",
        "user": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Extract New User Info').item.json.slack_user_id }}"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c372f9a2-8b2a-4da0-9b3a-0b12175ae836",
      "name": "Update Status: Joined",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5952,
        4128
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Extract New User Info').item.json.email }}",
            "status": "Joined",
            "slack_invited_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "c5390541-0c1b-47fb-9f87-e9ef4a961a60",
      "name": "Sticky Note \u2014 Workflow Overview1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2528,
        -5168
      ],
      "parameters": {
        "width": 468,
        "height": 672,
        "content": "# \ud83c\udfe2 HR Onboarding Automation\n## Workflow 1 \u2014 Employee Invite Sender\n\n**What this workflow does:**\nWhen HR submits a new employee form, this workflow:\n1. Validates the submitted data\n2. Saves employee record to Google Sheets\n3. Maps department \u2192 Slack channels\n4. Sends a welcome email with Slack invite link\n5. Notifies the manager on Slack\n6. Updates employee status in the sheet\n\n**Trigger:** POST webhook from HR dashboard/form\n**Required fields:** full_name, email, department, role, manager_email, start_date\n\n**Tech Stack:**\n- n8n (automation engine)\n- Google Sheets (employee database)\n- Gmail (welcome email)\n- Slack (manager notification)"
      },
      "typeVersion": 1
    },
    {
      "id": "e6d7a04b-abaa-4b35-aac3-a681eb775409",
      "name": "Sticky Note \u2014 Webhook1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2304,
        -4496
      ],
      "parameters": {
        "color": 6,
        "width": 344,
        "height": 668,
        "content": "## \ud83d\udce5 Step 1 \u2014 Webhook Trigger\n\nThis node listens for POST requests from the HR form/dashboard.\n\n**Endpoint:**\n`POST /webhook/onboard-employee`\n\n**Expected JSON Body:**\n```json\n{\n  \"full_name\": \"Ali Raza\",\n  \"email\": \"ali@company.com\",\n  \"department\": \"Engineering\",\n  \"role\": \"Backend Developer\",\n  \"manager_email\": \"mgr@company.com\",\n  \"start_date\": \"2026-07-15\"\n}\n```\n\n\u26a0\ufe0f Use `/webhook-test/` URL while testing.\nUse `/webhook/` URL in production (workflow must be Active)."
      },
      "typeVersion": 1
    },
    {
      "id": "0a769790-d8ba-4bfc-a6e5-071e485b2908",
      "name": "Sticky Note \u2014 Validation1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3040,
        -4928
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 448,
        "content": "## \u2705 Step 2 \u2014 Validation\n\nChecks that these 3 fields are not empty:\n- `full_name`\n- `email`\n- `department`\n\n**TRUE branch \u2192** Continue onboarding\n**FALSE branch \u2192** Return 400 error response\n\nNote: Fields come from `$json.body.*` because n8n wraps webhook payloads in a `body` object."
      },
      "typeVersion": 1
    },
    {
      "id": "d259b0c1-e6c5-43ea-861d-491775248a79",
      "name": "Sticky Note \u2014 Google Sheets Save1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3392,
        -4928
      ],
      "parameters": {
        "color": 4,
        "width": 356,
        "height": 484,
        "content": "## \ud83d\udcbe Step 3 \u2014 Save to Google Sheets\n\nAppends a new row to the **Sheet1** tab.\n\n**Columns written:**\nfull_name, email, department, role, manager_email, start_date\n\n**Auto-filled later:**\n- `status` \u2192 updated by this workflow + WF2\n- `slack_invited_at` \u2192 timestamp when invite sent\n- `slack_user_id` \u2192 filled when employee joins Slack\n\n\ud83d\udccc Sheet ID: `1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo`"
      },
      "typeVersion": 1
    },
    {
      "id": "5e79d7e5-395f-41a3-9e5f-e4c81caa6244",
      "name": "Sticky Note \u2014 Channel Mapping1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3792,
        -4928
      ],
      "parameters": {
        "color": 4,
        "width": 392,
        "height": 520,
        "content": "## \ud83d\uddc2\ufe0f Step 4 \u2014 Department \u2192 Channel Mapping\n\nMaps each department to relevant Slack channels.\n\n**Current Mapping:**\n- Engineering \u2192 all-testn8n, new-channel\n- Sales \u2192 all-testn8n, social\n- Marketing \u2192 all-testn8n, social\n- HR \u2192 all-testn8n, new-channel\n- Design \u2192 all-testn8n, social\n\nAlso attaches the static **Slack Workspace Invite Link**.\n\n\u26a0\ufe0f Update `SLACK_INVITE_LINK` with a fresh link from:\nSlack \u2192 Workspace name \u2192 Invite people \u2192 Get invite link"
      },
      "typeVersion": 1
    },
    {
      "id": "81686501-347b-42d9-9d26-a85df2329785",
      "name": "Sticky Note \u2014 Welcome Email1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4208,
        -4928
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 580,
        "content": "## \ud83d\udce7 Step 5 \u2014 Welcome Email\n\nSends a welcome email to the new employee.\n\n**Contains:**\n- Personalized greeting with name, role, department\n- Start date\n- Slack workspace invite link (static link)\n- Instructions to click and join\n\n**Gmail credential required.**\n\n\u26a0\ufe0f Non-Enterprise Slack limitation:\nWe cannot auto-create Slack accounts via API.\nEmployee must click the invite link themselves.\nWorkflow 2 handles the rest once they join."
      },
      "typeVersion": 1
    },
    {
      "id": "ff108019-87bc-42b7-a705-d40049994f1d",
      "name": "Sticky Note \u2014 Manager Notify1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4576,
        -4928
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 468,
        "content": "## \ud83d\udd14 Step 6 \u2014 Notify Manager\n\nSends a Slack DM to the employee's manager.\n\n**Message includes:**\n- Employee name, department, role\n- Start date\n- Channels they'll be added to\n- Confirmation that invite email was sent\n\n**Slack OAuth2 credential required.**\n\nCurrently set to user ID `U0BDTGNCMJQ` for testing.\nIn production: resolve manager's Slack user ID dynamically from their email."
      },
      "typeVersion": 1
    },
    {
      "id": "176bc57a-9041-43b6-b29a-34219bcc2083",
      "name": "Sticky Note \u2014 Status Update1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4944,
        -4928
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 432,
        "content": "## \ud83d\udcdd Step 7 \u2014 Update Sheet Status\n\nUpdates the employee row in Google Sheets:\n- `status` \u2192 \"Invite Sent\"\n- `slack_invited_at` \u2192 current timestamp\n\nMatches row by `email` column (must be unique).\n\nHR can see in real-time:\n- **Invite Sent** = email sent, waiting to join\n- **Joined** = added to channels \u2713 (set by WF2)"
      },
      "typeVersion": 1
    },
    {
      "id": "e433099b-615d-4446-84c4-e59643211ccc",
      "name": "Sticky Note \u2014 Setup Checklist1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5328,
        -4928
      ],
      "parameters": {
        "color": 2,
        "width": 436,
        "height": 712,
        "content": "## \u2699\ufe0f Setup Checklist\n\n**Before going live, make sure:**\n\n\u2705 Google Sheets has columns:\nfull_name, email, department, role, manager_email, start_date, status, slack_invited_at, slack_user_id\n\n\u2705 Slack App has scopes:\nusers:read, users:read.email, channels:read, channels:manage, chat:write\n\n\u2705 Slack App \u2192 Event Subscriptions \u2192 team_join subscribed\n\n\u2705 Workflow 2 is **Active** (toggle ON in n8n)\n\n\u2705 Bot invited to all target channels (`/invite @DemoApp`)\n\n\u2705 Static Slack invite link updated in 'Map Department + Attach Invite Link' node\n\n\u2705 Department names match exactly:\nEngineering, Sales, Marketing, HR, Design"
      },
      "typeVersion": 1
    },
    {
      "id": "75c34ff8-a3bb-462b-a62e-58f763990ac1",
      "name": "Webhook - New Employee Form1",
      "type": "n8n-nodes-base.webhook",
      "notes": "POST /webhook/onboard-employee \u2014 HR form trigger",
      "position": [
        2880,
        -4192
      ],
      "parameters": {
        "path": "onboard-employee",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "83f307fa-3ee1-4b87-8449-040c9c419ce8",
      "name": "Validate Required Fields1",
      "type": "n8n-nodes-base.if",
      "position": [
        3104,
        -4192
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-001",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.full_name }}",
              "rightValue": ""
            },
            {
              "id": "cond-002",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.email }}",
              "rightValue": ""
            },
            {
              "id": "cond-003",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.department }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "1e110181-6850-449d-82fc-f01b0d0d5f0a",
      "name": "Respond Validation Error1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3328,
        -4096
      ],
      "parameters": {
        "options": {
          "responseCode": 400
        },
        "respondWith": "json",
        "responseBody": "={{ { \"success\": false, \"message\": \"Missing required fields: full_name, email, or department\" } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "24067974-454f-4615-915c-8b72c6290430",
      "name": "Save Employee to Google Sheet1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3328,
        -4288
      ],
      "parameters": {
        "columns": {
          "value": {
            "role": "={{ $json.body.role }}",
            "email": "={{ $json.body.email }}",
            "full_name": "={{ $json.body.full_name }}",
            "department": "={{ $json.body.department }}",
            "start_date": "={{ $json.body.start_date }}",
            "manager_email": "={{ $json.body.manager_email }}"
          },
          "schema": [
            {
              "id": "full_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "full_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "department",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "department",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "role",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "role",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "manager_email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "manager_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "start_date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "start_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_user_id",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "slack_user_id",
              "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/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "d0c0f242-cb56-4112-8812-fb8b973e6598",
      "name": "Map Department + Attach Invite Link1",
      "type": "n8n-nodes-base.code",
      "position": [
        3552,
        -4288
      ],
      "parameters": {
        "jsCode": "const departmentChannelMap = {\n  'Engineering': ['all-testn8n', 'new-channel'],\n  'Sales': ['all-testn8n', 'social'],\n  'Marketing': ['all-testn8n', 'social'],\n  'HR': ['all-testn8n', 'new-channel'],\n  'Design': ['all-testn8n', 'social']\n};\n\nconst dept = $input.first().json.department;\nconst channels = departmentChannelMap[dept] || ['all-testn8n'];\n\nconst SLACK_INVITE_LINK = 'https://join.slack.com/t/testn8n-6i17414/shared_invite/zt-429tad5xx-6dmoOUMbNCJ_TmQpYUrUzA';\n\nreturn [{\n  json: {\n    ...$input.first().json,\n    target_channels: channels,\n    slack_invite_link: SLACK_INVITE_LINK\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1f8db531-7af7-4f30-b897-63473ba902ee",
      "name": "Send Welcome Email with Slack Invite Link1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3776,
        -4288
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=<h2>Welcome aboard, {{ $json.full_name }}!</h2><p>We're thrilled to have you join us as <strong>{{ $json.role }}</strong> in the <strong>{{ $json.department }}</strong> team, starting <strong>{{ $json.start_date }}</strong>.</p><p>Step 1: Click the link below to join our Slack workspace:</p><p><a href=\"{{ $json.slack_invite_link }}\">{{ $json.slack_invite_link }}</a></p><p>Once you join, you'll automatically be added to your team's channels and our bot will say hi!</p><p>See you soon!</p>",
        "options": {},
        "subject": "=Welcome to the team, {{ $json.full_name }}! \ud83c\udf89 Join us on Slack"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "48db0793-cf8f-4650-b147-78f6c1d42c0d",
      "name": "Notify Manager on Slack1",
      "type": "n8n-nodes-base.slack",
      "position": [
        4000,
        -4288
      ],
      "parameters": {
        "text": "=:bust_in_silhouette: Heads up! *{{ $('Map Department + Attach Invite Link1').item.json.full_name }}* has been sent a Slack invite link.\n\nDepartment: {{ $('Map Department + Attach Invite Link1').item.json.department }}\nRole: {{ $('Map Department + Attach Invite Link1').item.json.role }}\nStart Date: {{ $('Map Department + Attach Invite Link1').item.json.start_date }}\nManager: {{ $('Map Department + Attach Invite Link1').item.json.manager_email }}\n\nThey'll be auto-added to: {{ $('Map Department + Attach Invite Link1').item.json.target_channels.join(', ') }} once they join the workspace.",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U0BDTGNCMJQ",
          "cachedResultName": "umartkd989"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3a8d3a62-a318-41b1-9848-e9d36a12e8a4",
      "name": "Update Status: Invite Sent1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        4224,
        -4288
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Map Department + Attach Invite Link1').item.json.email }}",
            "status": "Invite Sent",
            "slack_invited_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_user_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_user_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "a0c74732-1a6e-4545-b561-005d4695d4a6",
      "name": "Respond Success1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        4448,
        -4288
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"success\": true, \"message\": \"Onboarding invite sent\", \"employee\": $json.full_name } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "7c8b381d-70ff-4600-a0e3-39182c7d7080",
      "name": "Sticky Note \u2014 WF2 Overview1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        -3664
      ],
      "parameters": {
        "width": 488,
        "height": 680,
        "content": "# \ud83d\udd17 Workflow 2 \u2014 Slack Team Join Listener\n\n**What this workflow does:**\nListens for Slack's `team_join` event (fired when anyone joins the workspace). When triggered:\n1. Verifies it's a real event (not URL verification challenge)\n2. Extracts new user's email + Slack user ID\n3. Looks up their record in Google Sheets\n4. Maps department to channels\n5. Adds user to each channel one by one\n6. Sends a welcome DM on Slack\n7. Updates sheet status to \"Joined\"\n\n**Setup Required:**\n- Slack App \u2192 Event Subscriptions \u2192 Enable\n- Request URL: `https://umarimran99999.app.n8n.cloud/webhook/slack-team-join`\n- Subscribe to bot event: `team_join`\n- This workflow must be **Active** (toggle ON)\n\n**Required Slack Scopes:**\n`users:read`, `users:read.email`, `channels:read`, `channels:manage`, `chat:write`"
      },
      "typeVersion": 1
    },
    {
      "id": "3a20c7ce-fb08-4acb-8c65-721cbec6d538",
      "name": "Sticky Note \u2014 Challenge1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2832,
        -3840
      ],
      "parameters": {
        "color": 6,
        "width": 524,
        "height": 456,
        "content": "## \ud83e\udd1d URL Verification Challenge\n\nWhen you first save the Request URL in Slack's Event Subscriptions, Slack sends a one-time verification request:\n```json\n{ \"type\": \"url_verification\", \"challenge\": \"abc123\" }\n```\n\nThis IF node checks for that.\n\n**TRUE \u2192** Echo back the challenge (Slack marks URL as Verified \u2713)\n**FALSE \u2192** It's a real event, continue processing\n\n\u26a0\ufe0f This workflow must be **Active** and use the production `/webhook/` URL for Slack verification to work."
      },
      "typeVersion": 1
    },
    {
      "id": "41cdcd07-c6f0-4633-a510-15be3c3192a4",
      "name": "Sticky Note \u2014 Acknowledge1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3264,
        -3056
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 408,
        "content": "## \u26a1 Acknowledge First, Process Later\n\nSlack requires a response within **3 seconds** or it retries the event (causing duplicate processing).\n\nSo we:\n1. Immediately respond `{ ok: true }` (this node)\n2. Then continue with the actual processing below\n\nThis is standard Slack Events API best practice."
      },
      "typeVersion": 1
    },
    {
      "id": "ddb7899e-b51e-4ba1-8570-6d1d4872c8cb",
      "name": "Sticky Note \u2014 Extract User1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3376,
        -3824
      ],
      "parameters": {
        "color": 6,
        "width": 300,
        "height": 412,
        "content": "## \ud83d\udc64 Extract User Info\n\nExtracts from the `team_join` Slack event payload:\n- `slack_user_id` \u2192 user.id (e.g. U0XXXXXXX)\n- `email` \u2192 user.profile.email\n- `real_name` \u2192 user's display name\n\nThese are used to look up the employee in Google Sheets and to send them a welcome DM."
      },
      "typeVersion": 1
    },
    {
      "id": "fc1beeff-a15a-4395-b940-3ffacd40156e",
      "name": "Sticky Note \u2014 Sheet Lookup1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3696,
        -3952
      ],
      "parameters": {
        "color": 4,
        "width": 276,
        "height": 548,
        "content": "## \ud83d\udd0d Lookup in Google Sheets\n\nSearches Sheet1 for a row where `email` matches the email from Slack's event.\n\nThis connects the Slack join event back to the original onboarding record created by Workflow 1.\n\nReturns: full_name, department, role, manager_email, start_date.\n\n\u26a0\ufe0f If no match found (employee joined via a different email than HR entered), the workflow will fail here. HR should ensure emails match."
      },
      "typeVersion": 1
    },
    {
      "id": "57a7426f-9657-4633-b85e-5f50643a7fed",
      "name": "Sticky Note \u2014 Channel Resolution1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4016,
        -4016
      ],
      "parameters": {
        "color": 4,
        "width": 284,
        "height": 568,
        "content": "## \ud83d\udd04 Split Channels + Get IDs\n\n**Split Out Channels:**\nBreaks the `target_channels` array into individual items so each channel is processed separately (Slack API accepts one channel per invite call).\n\n**Get Channel ID by Name:**\nCalls `conversations.list` to fetch all workspace channels with their IDs.\n\n**Match Channel Name to ID:**\nFinds the channel whose `name` matches our target, extracts its ID.\n\n\u26a0\ufe0f Channel names must exactly match Slack channel names (no `#` prefix, lowercase)."
      },
      "typeVersion": 1
    },
    {
      "id": "da8c71da-d6b4-470c-bcc0-e93c27c6eeba",
      "name": "Sticky Note \u2014 Add + DM1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4384,
        -4048
      ],
      "parameters": {
        "color": 3,
        "width": 920,
        "height": 424,
        "content": "## \u2795 Add to Channel + Welcome DM\n\n**Add User to Channel:**\nCalls Slack's `conversations.invite` with the resolved channel ID and the new user's Slack ID.\n\n`continueOnFail: true` \u2014 if one channel fails (bot not in channel, wrong ID), it continues to the next instead of stopping.\n\n**Send Welcome DM:**\nSends a personalized direct message to the new employee on Slack with their role and department.\n\n\u26a0\ufe0f Bot must be manually invited to each target channel first:\n`/invite @YourBotName` in each channel"
      },
      "typeVersion": 1
    },
    {
      "id": "53cd21e5-d55b-4145-8014-b9d9113e9a83",
      "name": "Sticky Note \u2014 Final Update1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5616,
        -3840
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 396,
        "content": "## \u2705 Final Status Update\n\nUpdates the employee's row in Google Sheets:\n- `status` \u2192 \"Joined\"\n- `slack_invited_at` \u2192 current timestamp\n\nMatches by `email` column.\n\nHR can now see in the sheet:\n- **Invite Sent** = email sent, waiting for employee to join\n- **Joined** = employee has joined Slack and been added to channels \u2713"
      },
      "typeVersion": 1
    },
    {
      "id": "1cb50fff-3c64-4a93-b11e-d67f4ae05350",
      "name": "Slack Events Webhook1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        2720,
        -3328
      ],
      "parameters": {
        "path": "slack-team-join",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "4d0ea14b-9952-47f3-a4b5-f154dc116d15",
      "name": "Is URL Verification?1",
      "type": "n8n-nodes-base.if",
      "position": [
        3040,
        -3296
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "is-challenge",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.type }}",
              "rightValue": "url_verification"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "82b880ba-2731-47cd-8614-f14eeaa85ed9",
      "name": "Respond with Challenge1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3264,
        -3344
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"challenge\": $json.body.challenge } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "951ee0d7-bdca-4aee-94fd-5d1571da91b3",
      "name": "Acknowledge Event1",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3264,
        -3200
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ { \"ok\": true } }}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "e34f0e41-34df-4e7b-a0b8-503ec0e962f4",
      "name": "Extract New User Info1",
      "type": "n8n-nodes-base.code",
      "position": [
        3472,
        -3344
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json.body;\nconst user = body.event.user;\n\nreturn [{\n  json: {\n    slack_user_id: user.id,\n    email: user.profile.email,\n    real_name: user.profile.real_name || user.real_name\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0398eba3-0ce0-472d-bb60-8171e3fb5643",
      "name": "Find Employee Row by Email1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3808,
        -3360
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.email }}",
              "lookupColumn": "email"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "9fea5522-3884-4ebc-987f-7a4545b8d681",
      "name": "Map Department to Channels1",
      "type": "n8n-nodes-base.code",
      "position": [
        4048,
        -3360
      ],
      "parameters": {
        "jsCode": "const departmentChannelMap = {\n  'Engineering': ['all-testn8n', 'new-channel'],\n  'Sales': ['all-testn8n', 'social'],\n  'Marketing': ['all-testn8n', 'social'],\n  'HR': ['all-testn8n', 'new-channel'],\n  'Design': ['all-testn8n', 'social']\n};\n\nconst employee = $input.first().json;\nconst slackUser = $('Extract New User Info1').first().json;\nconst channels = departmentChannelMap[employee.department] || ['all-testn8n'];\n\nreturn [{\n  json: {\n    ...employee,\n    slack_user_id: slackUser.slack_user_id,\n    target_channels: channels\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "53df4999-69a2-49f8-8140-2d42b3562045",
      "name": "Split Out Channels1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        4272,
        -3392
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "target_channels"
      },
      "typeVersion": 1
    },
    {
      "id": "616938e6-4666-4d54-8c25-7fe662fb4e19",
      "name": "Get Channel ID by Name1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4448,
        -3536
      ],
      "parameters": {
        "url": "https://slack.com/api/conversations.list",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "200"
            }
          ]
        },
        "nodeCredentialType": "slackOAuth2Api"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b231dab2-c3ad-40a5-b896-a52a138cb978",
      "name": "Match Channel Name to ID1",
      "type": "n8n-nodes-base.code",
      "position": [
        4672,
        -3536
      ],
      "parameters": {
        "jsCode": "const channelName = $('Split Out Channels1').first().json.target_channels.replace('#', '');\nconst channels = $input.first().json.channels;\n\nconst match = channels.find(c => c.name === channelName || c.name_normalized === channelName);\n\nif (!match) {\n  return [{\n    json: {\n      ...$('Split Out Channels1').first().json,\n      channel_id: null,\n      error: `Channel '${channelName}' not found \u2014 check bot is in the channel and name matches exactly`\n    }\n  }];\n}\n\nreturn [{\n  json: {\n    ...$('Split Out Channels1').first().json,\n    channel_id: match.id\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "3b360d3f-64ea-4b5e-aeaa-fb49c33cc142",
      "name": "Add User to Channel1",
      "type": "n8n-nodes-base.slack",
      "position": [
        4976,
        -3552
      ],
      "parameters": {
        "userIds": "={{ $('Extract New User Info1').item.json.slack_user_id }}",
        "resource": "channel",
        "channelId": "={{ $json.channel_id }}",
        "operation": "invite",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2,
      "continueOnFail": true
    },
    {
      "id": "061cfe58-b406-42c4-8b5f-82f6c9a0aed4",
      "name": "Send Welcome DM1",
      "type": "n8n-nodes-base.slack",
      "position": [
        5200,
        -3552
      ],
      "parameters": {
        "text": "=:wave: Welcome to the team, *{{ $('Find Employee Row by Email1').item.json.full_name }}*! :tada:\n\nYou've been added to your team's channels. Glad to have you here as *{{ $('Find Employee Row by Email1').item.json.role }}* in *{{ $('Find Employee Row by Email1').item.json.department }}*!\n\nFeel free to say hi in your channels \u2014 the team is excited to meet you! :rocket:",
        "user": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Extract New User Info1').item.json.slack_user_id }}"
        },
        "select": "user",
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "153b1f85-b3d1-4b48-970f-5e6359b78516",
      "name": "Update Status: Joined1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5424,
        -3552
      ],
      "parameters": {
        "columns": {
          "value": {
            "email": "={{ $('Extract New User Info1').item.json.email }}",
            "status": "Joined",
            "slack_invited_at": "={{ $now.toISO() }}"
          },
          "schema": [
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "slack_invited_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "slack_invited_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1kGaxbKg-6SZTWqWFXL2GZz0WvUaC8PTsOpZ8tySKpLo/edit?usp=drivesdk",
          "cachedResultName": "employ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "a3c7e5a9-012a-474d-a605-997084fee98c",
  "nodeGroups": [],
  "connections": {
    "Send Welcome DM": {
      "main": [
        [
          {
            "node": "Update Status: Joined",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Welcome DM1": {
      "main": [
        [
          {
            "node": "Update Status: Joined1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Acknowledge Event": {
      "main": [
        [
          {
            "node": "Extract New User Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Acknowledge Event1": {
      "main": [
        [
          {
            "node": "Extract New User Info1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Channels": {
      "main": [
        [
          {
            "node": "Get Channel ID by Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add User to Channel": {
      "main": [
        [
          {
            "node": "Send Welcome DM",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Channels1": {
      "main": [
        [
          {
            "node": "Get Channel ID by Name1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add User to Channel1": {
      "main": [
        [
          {
            "node": "Send Welcome DM1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is URL Verification?": {
      "main": [
        [
          {
            "node": "Respond with Challenge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Acknowledge Event",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Events Webhook": {
      "main": [
        [
          {
            "node": "Is URL Verification?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract New User Info": {
      "main": [
        [
          {
            "node": "Find Employee Row by Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is URL Verification?1": {
      "main": [
        [
          {
            "node": "Respond with Challenge1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Acknowledge Event1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Events Webhook1": {
      "main": [
        [
          {
            "node": "Is URL Verification?1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract New User Info1": {
      "main": [
        [
          {
            "node": "Find Employee Row by Email1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Channel ID by Name": {
      "main": [
        [
          {
            "node": "Match Channel Name to ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Channel ID by Name1": {
      "main": [
        [
          {
            "node": "Match Channel Name to ID1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Manager on Slack": {
      "main": [
        [
          {
            "node": "Update Status: Invite Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Channel Name to ID": {
      "main": [
        [
          {
            "node": "Add User to Channel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify Manager on Slack1": {
      "main": [
        [
          {
            "node": "Update Status: Invite Sent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Required Fields": {
      "main": [
        [
          {
            "node": "Save Employee to Google Sheet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Validation Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Channel Name to ID1": {
      "main": [
        [
          {
            "node": "Add User to Channel1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Required Fields1": {
      "main": [
        [
          {
            "node": "Save Employee to Google Sheet1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Validation Error1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Employee Row by Email": {
      "main": [
        [
          {
            "node": "Map Department to Channels",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Department to Channels": {
      "main": [
        [
          {
            "node": "Split Out Channels",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Status: Invite Sent": {
      "main": [
        [
          {
            "node": "Respond Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Employee Row by Email1": {
      "main": [
        [
          {
            "node": "Map Department to Channels1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Department to Channels1": {
      "main": [
        [
          {
            "node": "Split Out Channels1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Status: Invite Sent1": {
      "main": [
        [
          {
            "node": "Respond Success1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - New Employee Form": {
      "main": [
        [
          {
            "node": "Validate Required Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - New Employee Form1": {
      "main": [
        [
          {
            "node": "Validate Required Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Employee to Google Sheet": {
      "main": [
        [
          {
            "node": "Map Department + Attach Invite Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Employee to Google Sheet1": {
      "main": [
        [
          {
            "node": "Map Department + Attach Invite Link1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Department + Attach Invite Link": {
      "main": [
        [
          {
            "node": "Send Welcome Email with Slack Invite Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Department + Attach Invite Link1": {
      "main": [
        [
          {
            "node": "Send Welcome Email with Slack Invite Link1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Welcome Email with Slack Invite Link": {
      "main": [
        [
          {
            "node": "Notify Manager on Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Welcome Email with Slack Invite Link1": {
      "main": [
        [
          {
            "node": "Notify Manager on Slack1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}