AutomationFlowsEmail & Gmail › Tg Leaves Workflow

Tg Leaves Workflow

Tg Leaves Workflow. Uses formTrigger, notion, form, gmail. Event-driven trigger; 26 nodes.

Event trigger★★★★☆ complexity26 nodesForm TriggerNotionFormGmail
Email & Gmail Trigger: Event Nodes: 26 Complexity: ★★★★☆ Added:

This workflow follows the Form → Form Trigger 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
{
  "nodes": [
    {
      "parameters": {
        "content": "# Collect and validate user form data",
        "height": 460,
        "width": 700,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1820,
        820
      ],
      "id": "9f721dba-56e0-4bed-a129-72372048759c",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "formTitle": "TG Leave Request",
        "formDescription": "<body style=\"text-align: left!important;\">\n<div style=\"text-align: left!important;\">\n<p>Please submit the times you need to take off work and the type of leave you are taking.</p>\n<strong>\n<p><strong>Notes:</strong></p>\n<ul>\n<li>If your leave includes full day and partial day both, please request in two phases. One for full day portal and one for partial day portion.</li>\n<li>If your leave includes only full day or only partial day leaves then request it in one form submission.</li>\n</ul>\n</div>\n<body>",
        "formFields": {
          "values": [
            {
              "fieldLabel": "LeaveDurationType",
              "fieldType": "dropdown",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Partial (<1 day)"
                  },
                  {
                    "option": "=Full (>= 1 day)"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.2,
      "position": [
        1120,
        520
      ],
      "id": "2bae12bb-b50b-480c-96b7-88ef920894f0",
      "name": "User starts leave form"
    },
    {
      "parameters": {
        "content": "# Get records from notion",
        "height": 340,
        "width": 1360,
        "color": 2
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1820,
        420
      ],
      "id": "df70945a-4774-4d4f-8805-bc3279cbfa39",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        2180,
        500
      ],
      "id": "092e955d-f3ae-4725-a731-b47347a382ed",
      "name": "Requestors into List"
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        2540,
        500
      ],
      "id": "51425497-0ae3-4812-91d8-c610b19f95ba",
      "name": "Leave Types into List"
    },
    {
      "parameters": {
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "value": "1e5f97e5-205a-804c-868b-eb5364cd870d",
          "mode": "list",
          "cachedResultName": "Requestors",
          "cachedResultUrl": "https://www.notion.so/1e5f97e5205a804c868beb5364cd870d"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        2000,
        500
      ],
      "id": "5efb49a3-ef3a-4642-ba43-d9aa1784b67b",
      "name": "Get Requestors",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "value": "1e5f97e5-205a-808d-bca2-e80af575b0b6",
          "mode": "list",
          "cachedResultName": "Leave Types",
          "cachedResultUrl": "https://www.notion.so/1e5f97e5205a808dbca2e80af575b0b6"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        2360,
        500
      ],
      "id": "49a22a01-ae35-4b44-b098-1e87e01d9b9e",
      "name": "Get Leave Types",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "value": "1edf97e5-205a-8004-b036-cb11f964b919",
          "mode": "list",
          "cachedResultName": "Approvers",
          "cachedResultUrl": "https://www.notion.so/1edf97e5205a8004b036cb11f964b919"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        2740,
        500
      ],
      "id": "a976dec9-f56a-4b54-b167-812474243cfd",
      "name": "Get Approvers",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        2920,
        500
      ],
      "id": "f28ff2f5-b93b-4b29-82de-1fef7ec7deb5",
      "name": "Approvers into List"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "285a32ec-e6f4-487f-a472-0cc79736dfd4",
              "name": "durationType",
              "value": "={{ $('User starts leave form').last().json.LeaveDurationType.includes('Partial') ? 'partial' : 'full' }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1340,
        520
      ],
      "id": "dff5153a-272a-4715-adcf-16d9cc62a9c9",
      "name": "Set Duration Type"
    },
    {
      "parameters": {
        "content": "# User starts leave request form",
        "height": 300,
        "width": 580,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1000,
        440
      ],
      "id": "f82f730d-ba4f-4210-84ce-4fbecc89f09a",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "defineForm": "json",
        "jsonOutput": "=[\n   {\n      \"fieldLabel\":\"Name\",\n      \"placeholder\":\"enter you name\",\n      \"requiredField\":true,\n      \"fieldType\": \"dropdown\",\n      \"fieldOptions\": {\n        \"values\": {{ $('Requestors into List').first().json.data.map(item => ({option: `${item.property_name} (${item.property_contact_email})`})) }}\n      }\n   },   \n  {\n      \"fieldLabel\":\"Leave Type\",\n      \"placeholder\":\"Select Leave Type\",\n      \"requiredField\":true,\n      \"fieldType\": \"dropdown\",\n      \"fieldOptions\": {\n        \"values\": {{ $('Leave Types into List').first().json.data.filter(item => item.property_partial === 'full').map(item => ({option: item.property_name})) }}\n      }\n   },\n  {\n      \"fieldLabel\":\"Remarks\",\n      \"placeholder\":\"Leave Details / Remarks\",\n      \"requiredField\":true,\n      \"fieldType\": \"text\"\n   },\n  {\n      \"fieldLabel\":\"Start Date\",\n      \"formatDate\":\"yyyy-mm-dd\",\n      \"requiredField\":true,\n      \"fieldType\": \"date\"\n   },\n  {\n      \"fieldLabel\":\"End Date\",\n      \"formatDate\":\"yyyy-mm-dd\",\n      \"requiredField\":true,\n      \"fieldType\": \"date\"\n  }\n\n]",
        "options": {
          "formTitle": "TG Leave Request P2"
        }
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        2140,
        900
      ],
      "id": "666234bf-f66f-4a4b-a897-0efd154725da",
      "name": "Leave Request Form: Full"
    },
    {
      "parameters": {
        "defineForm": "json",
        "jsonOutput": "=[\n   {\n      \"fieldLabel\":\"Name\",\n      \"placeholder\":\"enter you name\",\n      \"requiredField\":true,\n      \"fieldType\": \"dropdown\",\n      \"fieldOptions\": {\n        \"values\": {{ $('Requestors into List').first().json.data.map(item => ({option: `${item.property_name} (${item.property_contact_email})`})) }}\n      }\n   },   \n  {\n      \"fieldLabel\":\"Leave Type\",\n      \"placeholder\":\"Select Leave Type\",\n      \"requiredField\":true,\n      \"fieldType\": \"dropdown\",\n      \"fieldOptions\": {\n        \"values\": {{ $('Leave Types into List').first().json.data.filter(item => item.property_partial === 'partial').map(item => ({option: item.property_name})) }}\n      }\n   },\n  {\n      \"fieldLabel\":\"Remarks\",\n      \"placeholder\":\"Leave Details / Remarks\",\n      \"requiredField\":true,\n      \"fieldType\": \"text\"\n   },\n  {\n      \"fieldLabel\":\"Start Date\",\n      \"formatDate\":\"yyyy-mm-dd\",\n      \"requiredField\":true,\n      \"fieldType\": \"date\"\n   }\n\n]",
        "options": {}
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        2140,
        1080
      ],
      "id": "2570f7a9-1aff-4d44-bf18-90566da081ed",
      "name": "Leave Request Form: Partial"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "fcea9051-fbe8-4a66-aa1c-bd0da874cf6f",
              "leftValue": "={{ $('Set Duration Type').item.json.durationType }}",
              "rightValue": "full",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1880,
        1000
      ],
      "id": "948f5681-8d5d-4082-9054-c5d126eb4474",
      "name": "Partial or Full?"
    },
    {
      "parameters": {
        "jsCode": "function getProcessedData() {\n  // get correct form data\n  let formNode = $('Leave Request Form: Full');\n  if ($('Leave Request Form: Partial').isExecuted) {\n    formNode = $(\"Leave Request Form: Partial\");\n    formNode.last().json[\"End Date\"] = formNode.last().json[\"Start Date\"]\n  }\n  const formData = formNode.last().json;\n  \n  // get correct leave record\n  const requestedLeave = formData['Leave Type'];\n  const leave = $('Leave Types into List').last().json.data.filter(item => item.name == requestedLeave)[0];\n  \n  // get correct requestor\n  const requestorEmail = /\\((?<email>.*)\\)/.exec(formData.Name).groups.email.trim();\n  const requestor = $('Requestors into List').last().json.data.filter(item => item.property_contact_email === requestorEmail)[0];\n  \n  // get all approvers\n  const approvers = $('Approvers into List').last().json.data.filter(approverItem => requestor.property_approvers.includes(approverItem.id));\n  \n  // leave duration\n  // const leaveDuration = new Date(formData['End Date']).getDate() - new Date(formData['Start Date']).getDate() + 1;\n  const leaveDuration = DateTime.fromJSDate(new Date(formData['End Date'])).diff(\n    DateTime.fromJSDate(new Date(formData['Start Date']))\n  ).as(\"day\") + 1;\n  \n  return {formData, leave, requestor, approvers, leaveDuration};\n}\n\nfunction validateNotice(processedData) {\n  // validate notice period\n  const hasNotice = processedData.leave.property_notice_limits && processedData.leave.property_valid_advanced_notice;\n  const noticeGiven = Math.ceil(DateTime.fromJSDate(new Date(processedData.formData['Start Date'])).diff($now).as(\"day\"));\n\n  const noticePattern = processedData.leave.property_notice_limits.split(/,\\s*/)\n    .map(item => item.split(/:\\s*/).map(numStr => parseInt(numStr)));\n  const applicableNotice = noticePattern.filter(validationItem => validationItem[0] >= processedData.leaveDuration)[0][1];\n  const noticeIsValid = noticeGiven >= applicableNotice;\n  let noticeMessage = '';\n  if (!noticeIsValid) {\n    noticeMessage = `Insufficient notice period: ${applicableNotice} days required but only ${noticeGiven} given`;\n  }\n  \n  return {hasNotice, isValid: noticeIsValid, noticeMessage};\n}\n\nfunction validateLeaveCredits(processedData) {\n  const requestor = processedData.requestor;\n  const leaveDuration = processedData.leaveDuration;\n  let totalCreditsLeft, hasSufficientCredits = true, creditMessage = '';\n  \n  \n  if (processedData.leave.property_category === \"Annual Leave\") {\n    totalCreditsLeft = requestor.property_py_current + requestor.property_al_current;\n    if (totalCreditsLeft < leaveDuration) {\n      hasSufficientCredits = false;\n    }\n  } else if (processedData.leave.property_category === \"Sick Leave\") {\n    totalCreditsLeft = requestor.property_sl_current\n    if (totalCreditsLeft < leaveDuration) {\n      hasSufficientCredits = false;\n    }\n  }\n  if (!hasSufficientCredits) {\n    creditMessage = `Insufficient credits: ${leaveDuration} required but ${totalCreditsLeft} left`;\n  }\n  return {hasSufficientCredits, isValid: hasSufficientCredits, creditMessage};\n}\n\n\nconst processedData = getProcessedData();\nconst noticeValidation = validateNotice(processedData);\nconst creditValidation = validateLeaveCredits(processedData);\nlet validationIsValid = true, validationMessage = '';\nif (!noticeValidation.isValid) {\n  validationIsValid = false;\n  validationMessage = noticeValidation.noticeMessage;\n} else if (!creditValidation.isValid) {\n  validationIsValid = false;\n  validationMessage = creditValidation.creditMessage;\n}\n\nreturn {\n  validation: {\n    isValid: validationIsValid,\n    message: validationMessage\n  },\n  ...processedData,\n}\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2360,
        1000
      ],
      "id": "2fb6a26f-60a4-47e0-9b45-66a8cadf39f8",
      "name": "Run Validations"
    },
    {
      "parameters": {
        "content": "# Complete Form",
        "height": 540,
        "width": 700,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2620,
        820
      ],
      "id": "adde3a8e-689b-431a-9fc3-3cdfbd7384e3",
      "name": "Sticky Note9"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "c85e0b83-11b7-474d-b2b4-f2547ab22158",
              "leftValue": "={{ $json.validation.isValid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2700,
        1020
      ],
      "id": "852ed479-bbe5-4573-acb5-7442594c412a",
      "name": "Leave Request Is Valid",
      "notesInFlow": true,
      "notes": "If sufficient advanced notice period and leave credits\n"
    },
    {
      "parameters": {
        "operation": "completion",
        "completionTitle": "Submission Successful",
        "completionMessage": "=Your leave request has been successfully submitted.\n\nYou'll receive a confirmation email upon approval by your supervisor.",
        "options": {
          "customCss": ":root {\n\t--font-family: 'Open Sans', sans-serif;\n\t--font-weight-normal: 400;\n\t--font-weight-bold: 600;\n\t--font-size-body: 12px;\n\t--font-size-label: 14px;\n\t--font-size-test-notice: 12px;\n\t--font-size-input: 14px;\n\t--font-size-header: 20px;\n\t--font-size-paragraph: 14px;\n\t--font-size-link: 12px;\n\t--font-size-error: 12px;\n\t--font-size-html-h1: 28px;\n\t--font-size-html-h2: 20px;\n\t--font-size-html-h3: 16px;\n\t--font-size-html-h4: 14px;\n\t--font-size-html-h5: 12px;\n\t--font-size-html-h6: 10px;\n\t--font-size-subheader: 14px;\n\n\t/* Colors */\n\t--color-background: #fbfcfe;\n\t--color-test-notice-text: #e6a23d;\n\t--color-test-notice-bg: #fefaf6;\n\t--color-test-notice-border: #f6dcb7;\n\t--color-card-bg: #ffffff;\n\t--color-card-border: #dbdfe7;\n\t--color-card-shadow: rgba(0, 255, 0, 0.25);\n\t--color-link: #7e8186;\n\t--color-header: #429136;\n\t--color-label: #555555;\n\t--color-input-border: #dbdfe7;\n\t--color-input-text: #71747A;\n\t--color-focus-border: rgb(90, 76, 194);\n\t--color-submit-btn-bg: #ff6d5a;\n\t--color-submit-btn-text: #ffffff;\n\t--color-error: #ea1f30;\n\t--color-required: #ff6d5a;\n\t--color-clear-button-bg: #7e8186;\n\t--color-html-text: #555;\n\t--color-html-link: #ff6d5a;\n\t--color-header-subtext: #7e8186;\n\n\t/* Border Radii */\n\t--border-radius-card: 8px;\n\t--border-radius-input: 6px;\n\t--border-radius-clear-btn: 50%;\n\t--card-border-radius: 8px;\n\n\t/* Spacing */\n\t--padding-container-top: 24px;\n\t--padding-card: 24px;\n\t--padding-test-notice-vertical: 12px;\n\t--padding-test-notice-horizontal: 24px;\n\t--margin-bottom-card: 16px;\n\t--padding-form-input: 12px;\n\t--card-padding: 24px;\n\t--card-margin-bottom: 16px;\n\n\t/* Dimensions */\n\t--container-width: 448px;\n\t--submit-btn-height: 48px;\n\t--checkbox-size: 18px;\n\n\t/* Others */\n\t--box-shadow-card: 0px 4px 16px 0px var(--color-card-shadow);\n\t--opacity-placeholder: 0.5;\n}"
        }
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        3000,
        920
      ],
      "id": "07779e76-e54f-4408-9e2f-ef4932fdf238",
      "name": "Submission Succes"
    },
    {
      "parameters": {
        "operation": "completion",
        "completionTitle": "Submission Failed",
        "completionMessage": "=Leave request is not valid.\n{{ $json.validation.message }}\n\nPlease reach out to your supervisor or HR for further queries.",
        "options": {
          "customCss": ":root {\n\t--font-family: 'Open Sans', sans-serif;\n\t--font-weight-normal: 400;\n\t--font-weight-bold: 600;\n\t--font-size-body: 12px;\n\t--font-size-label: 14px;\n\t--font-size-test-notice: 12px;\n\t--font-size-input: 14px;\n\t--font-size-header: 20px;\n\t--font-size-paragraph: 14px;\n\t--font-size-link: 12px;\n\t--font-size-error: 12px;\n\t--font-size-html-h1: 28px;\n\t--font-size-html-h2: 20px;\n\t--font-size-html-h3: 16px;\n\t--font-size-html-h4: 14px;\n\t--font-size-html-h5: 12px;\n\t--font-size-html-h6: 10px;\n\t--font-size-subheader: 14px;\n\n\t/* Colors */\n\t--color-background: #fbfcfe;\n\t--color-test-notice-text: #e6a23d;\n\t--color-test-notice-bg: #fefaf6;\n\t--color-test-notice-border: #f6dcb7;\n\t--color-card-bg: #ffffff;\n\t--color-card-border: #dbdfe7;\n\t--color-card-shadow: rgba(255, 0, 0, 0.25);\n\t--color-link: #7e8186;\n\t--color-header: #b03230;\n\t--color-label: #555555;\n\t--color-input-border: #dbdfe7;\n\t--color-input-text: #71747A;\n\t--color-focus-border: rgb(90, 76, 194);\n\t--color-submit-btn-bg: #ff6d5a;\n\t--color-submit-btn-text: #ffffff;\n\t--color-error: #ea1f30;\n\t--color-required: #ff6d5a;\n\t--color-clear-button-bg: #7e8186;\n\t--color-html-text: #555;\n\t--color-html-link: #ff6d5a;\n\t--color-header-subtext: #7e8186;\n\n\t/* Border Radii */\n\t--border-radius-card: 8px;\n\t--border-radius-input: 6px;\n\t--border-radius-clear-btn: 50%;\n\t--card-border-radius: 8px;\n\n\t/* Spacing */\n\t--padding-container-top: 24px;\n\t--padding-card: 24px;\n\t--padding-test-notice-vertical: 12px;\n\t--padding-test-notice-horizontal: 24px;\n\t--margin-bottom-card: 16px;\n\t--padding-form-input: 12px;\n\t--card-padding: 24px;\n\t--card-margin-bottom: 16px;\n\n\t/* Dimensions */\n\t--container-width: 448px;\n\t--submit-btn-height: 48px;\n\t--checkbox-size: 18px;\n\n\t/* Others */\n\t--box-shadow-card: 0px 4px 16px 0px var(--color-card-shadow);\n\t--opacity-placeholder: 0.5;\n}"
        }
      },
      "type": "n8n-nodes-base.form",
      "typeVersion": 1,
      "position": [
        3000,
        1120
      ],
      "id": "3ba23142-d181-4808-8995-ab0d8e81748f",
      "name": "Submission Failure1"
    },
    {
      "parameters": {
        "sendTo": "={{ $('Run Validations').item.json.requestor.property_contact_email }}, lavee+hr@thetripguru.com",
        "subject": "Leave request successfully submitted",
        "message": "=<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Leave Request</title>\n  </head>\n  <body style=\"margin:0; padding:0; background-color:#f4f4f4;\">\n    <!-- Outer wrapper to center content -->\n    <table\n      width=\"100%\"\n      cellpadding=\"0\"\n      cellspacing=\"0\"\n      role=\"presentation\"\n      style=\"background-color:#f4f4f4; padding: 40px 0;\"\n    >\n      <tr>\n        <td align=\"center\">\n          <!-- Card container -->\n          <table\n            width=\"600\"\n            cellpadding=\"0\"\n            cellspacing=\"0\"\n            role=\"presentation\"\n            style=\"background-color:#ffffff; border-radius:8px; overflow:hidden; font-family:Arial, sans-serif;\"\n          >\n            <!-- Spacer top -->\n            <tr>\n              <td style=\"padding:32px 24px 0 24px;\"></td>\n            </tr>\n            <!-- Message -->\n            <tr>\n              <td\n                style=\"padding:0 24px 32px 24px; color:#333333; font-size:16px; line-height:24px; text-align:center;\"\n              >\n                Hi <em>{{ $('Run Validations').item.json.requestor.name }}</em>, your <em>{{ $('Run Validations').item.json.leave.name }}</em> request with the following data: <br />\n                Start date: {{ $('Run Validations').item.json.formData['Start Date'] }} <br />\n                End date: {{ $('Run Validations').item.json.formData['End Date'] }} <br />\n                Remarks: {{ $('Run Validations').item.json.formData.Remarks }} <br />\n                \n                has been successfully submitted. You'll receive a confirmation once it is approved.\n\n              </td>\n            </tr>\n          </table>\n          <!-- End card container -->\n        </td>\n      </tr>\n    </table>\n  </body>\n</html>\n",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        4340,
        940
      ],
      "id": "0e9e74d2-277c-4c5e-80f0-c6eaf5121c7c",
      "name": "Send confirmation to requestor & HR",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "value": "1e5f97e5-205a-80e4-83dc-f9d14cd49ce7",
          "mode": "list",
          "cachedResultName": "Leave Ledger",
          "cachedResultUrl": "https://www.notion.so/1e5f97e5205a80e483dcf9d14cd49ce7"
        },
        "title": "={{ $execution.id }}",
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "N8N Request Id|title",
              "title": "={{ $execution.id }}"
            },
            {
              "key": "requestor|relation",
              "relationValue": [
                "={{ $('Run Validations').item.json.requestor.id }}"
              ]
            },
            {
              "key": "Leave Type|relation",
              "relationValue": [
                "={{ $('Run Validations').item.json.leave.id }}"
              ]
            },
            {
              "key": "Description|rich_text",
              "textContent": "={{ $('Run Validations').item.json.formData.Remarks }}"
            },
            {
              "key": "approver|relation",
              "relationValue": [
                "={{ $('Run Validations').item.json.approvers.map(approver => approver.id).join(',') }}"
              ]
            },
            {
              "key": "Start Date|date",
              "includeTime": false,
              "date": "={{ $('Run Validations').item.json.formData['Start Date'] }}"
            },
            {
              "key": "End Date|date",
              "includeTime": false,
              "date": "={{ $('Run Validations').item.json.formData['End Date'] }}"
            },
            {
              "key": "Submitted At|date",
              "date": "={{ $('Run Validations').item.json.formData.submittedAt }}"
            },
            {
              "key": "Approver gmail thread|rich_text",
              "textContent": "={{ $('Approval Emails Aggregate').item.json.data.map(thread => thread.gmailThreadMap).join(',') }}"
            },
            {
              "key": "Requestor gmail thread|rich_text",
              "textContent": "={{ $json.threadId }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        4560,
        940
      ],
      "id": "854b3897-fe3a-4951-b61e-54fdac1128d3",
      "name": "Create Leave Ledger Record",
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "fieldToSplitOut": "approvers",
        "options": {}
      },
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        3560,
        940
      ],
      "id": "67b520ae-16c1-4f4b-ba45-5e9bca302749",
      "name": "For all approvers"
    },
    {
      "parameters": {
        "sendTo": "={{ $json.property_email }}",
        "subject": "=Leave request from  {{ $('Run Validations').last().json.requestor.name }}",
        "message": "=<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Leave Request</title>\n  </head>\n  <body style=\"margin:0; padding:0; background-color:#f4f4f4;\">\n    <!-- Outer wrapper to center content -->\n    <table\n      width=\"100%\"\n      cellpadding=\"0\"\n      cellspacing=\"0\"\n      role=\"presentation\"\n      style=\"background-color:#f4f4f4; padding: 40px 0;\"\n    >\n      <tr>\n        <td align=\"center\">\n          <!-- Card container -->\n          <table\n            width=\"600\"\n            cellpadding=\"0\"\n            cellspacing=\"0\"\n            role=\"presentation\"\n            style=\"background-color:#ffffff; border-radius:8px; overflow:hidden; font-family:Arial, sans-serif;\"\n          >\n            <!-- Spacer top -->\n            <tr>\n              <td style=\"padding:32px 24px 0 24px;\"></td>\n            </tr>\n            <!-- Message -->\n            <tr>\n              <td\n                style=\"padding:0 24px 32px 24px; color:#333333; font-size:16px; line-height:24px; text-align:center;\"\n              >\n                <strong>{{ $('Run Validations').item.json.requestor.name }} has requested {{ $('Run Validations').item.json.leave.name }}<br/>\n                  from <em>\n                        {{ $('Run Validations').item.json.formData['Start Date'] }}\n                      </em> to <em>\n                      {{ $('Run Validations').item.json.formData['End Date'] }}\n                      </em> for <em>\n                      {{ $('Run Validations').item.json.formData.Remarks }}\n                      </em>.</strong><br/>\n                Please review and approve or reject his request in the Leave Ledger.\n              </td>\n            </tr>\n            <!-- Buttons row -->\n            <tr>\n              <td align=\"center\" style=\"padding:0 24px 32px 24px;\">\n                <!-- Button container -->\n                <table\n                  cellpadding=\"0\"\n                  cellspacing=\"0\"\n                  role=\"presentation\"\n                  style=\"margin:auto;\"\n                >\n                  <tr>\n                    <!-- Decline button -->\n                    <td>\n                      <a\n                        href=\"https://ai.thetripguru.com/webhook/b014a163-3022-416d-a94d-8231eb564659?approved=false&approverId={{ $('For all approvers').item.json.id }}&requestId={{ $execution.id }}\"\n                        style=\"\n                          display:inline-block;\n                          padding:12px 24px;\n                          font-size:14px;\n                          color:#555555;\n                          text-decoration:none;\n                          border:1px solid #cccccc;\n                          border-radius:4px;\n                          background-color:#ffffff;\n                          margin-right:12px;\n                        \"\n                      >\n                        Decline\n                      </a>\n                    </td>\n                    <!-- Approve button -->\n                    <td>\n                      <a\n                        href=\"https://ai.thetripguru.com/webhook/b014a163-3022-416d-a94d-8231eb564659?approved=true&approverId={{ $('For all approvers').item.json.id }}&requestId={{ $execution.id }}\"\n                        style=\"\n                          display:inline-block;\n                          padding:12px 24px;\n                          font-size:14px;\n                          color:#ffffff;\n                          text-decoration:none;\n                          background-color:#ff6b5d;\n                          border-radius:4px;\n                        \"\n                      >\n                        Approve\n                      </a>\n                    </td>\n                  </tr>\n                </table>\n              </td>\n            </tr>\n          </table>\n          <!-- End card container -->\n        </td>\n      </tr>\n    </table>\n  </body>\n</html>\n",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        3740,
        940
      ],
      "id": "611a884d-e51b-410e-9817-e92438a33a01",
      "name": "Send Approval Email",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        4160,
        940
      ],
      "id": "6420984c-ecfc-4b10-9927-5a26c8e338fa",
      "name": "Approval Emails Aggregate"
    },
    {
      "parameters": {
        "content": "# Send emails and create ledger",
        "height": 380,
        "width": 1340,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        3440,
        840
      ],
      "id": "58dd2e80-7e7d-415d-8454-5993d9a88abe",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9f751e6d-feae-4d1f-9b14-cafdd688c286",
              "name": "gmailThreadMap",
              "value": "={{ $('For all approvers').item.json.id }}:{{ $json.threadId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3960,
        940
      ],
      "id": "1fd2bab0-5905-46f3-abe3-58cac844b277",
      "name": "Approver Gmail Thread Map"
    }
  ],
  "connections": {
    "User starts leave form": {
      "main": [
        [
          {
            "node": "Set Duration Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Requestors into List": {
      "main": [
        [
          {
            "node": "Get Leave Types",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leave Types into List": {
      "main": [
        [
          {
            "node": "Get Approvers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Requestors": {
      "main": [
        [
          {
            "node": "Requestors into List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Leave Types": {
      "main": [
        [
          {
            "node": "Leave Types into List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Approvers": {
      "main": [
        [
          {
            "node": "Approvers into List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approvers into List": {
      "main": [
        [
          {
            "node": "Partial or Full?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Duration Type": {
      "main": [
        [
          {
            "node": "Get Requestors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leave Request Form: Full": {
      "main": [
        [
          {
            "node": "Run Validations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leave Request Form: Partial": {
      "main": [
        [
          {
            "node": "Run Validations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Partial or Full?": {
      "main": [
        [
          {
            "node": "Leave Request Form: Full",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Leave Request Form: Partial",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Validations": {
      "main": [
        [
          {
            "node": "Leave Request Is Valid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leave Request Is Valid": {
      "main": [
        [
          {
            "node": "Submission Succes",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Submission Failure1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submission Succes": {
      "main": [
        [
          {
            "node": "For all approvers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send confirmation to requestor & HR": {
      "main": [
        [
          {
            "node": "Create Leave Ledger Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "For all approvers": {
      "main": [
        [
          {
            "node": "Send Approval Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Approval Email": {
      "main": [
        [
          {
            "node": "Approver Gmail Thread Map",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approval Emails Aggregate": {
      "main": [
        [
          {
            "node": "Send confirmation to requestor & HR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approver Gmail Thread Map": {
      "main": [
        [
          {
            "node": "Approval Emails Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

Tg Leaves Workflow. Uses formTrigger, notion, form, gmail. Event-driven trigger; 26 nodes.

Source: https://gist.github.com/laveesingh/319338f1d34ed7a7cebb19a19425981b — 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

🎥 Analyze YouTube Video for Summaries, Transcripts & Content + Google Gemini AI. Uses stickyNote, httpRequest, googleDrive, gmail. Event-driven trigger; 33 nodes.

HTTP Request, Google Drive, Gmail +2
Email & Gmail

This n8n workflow enables teams to automate and standardize multi-step onboarding or messaging workflows using Google Sheets, Forms, Gmail, and dynamic logic powered by Code and Switch nodes. It ensur

Google Sheets, Form, Execute Workflow Trigger +2
Email & Gmail

Splitout Extractfromfile. Uses splitOut, httpRequest, formTrigger, form. Event-driven trigger; 21 nodes.

HTTP Request, Form Trigger, Form +1
Email & Gmail

With this template, users will be able to automate design and marketing tasks such as creating variants of existing designs, remixing existing assets to validate different styles and explore a range o

HTTP Request, Form Trigger, Form +1
Email & Gmail

3954. Uses httpRequest, formTrigger, form, gmail. Event-driven trigger; 21 nodes.

HTTP Request, Form Trigger, Form +1