This workflow follows the Gmail → Google Calendar 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 →
{
"nodes": [
{
"parameters": {
"path": "b014a163-3022-416d-a94d-8231eb564659",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
100,
280
],
"id": "1b010711-6b83-48a1-955f-8ceaaf30892e",
"name": "On Leave Approval Email Response"
},
{
"parameters": {
"resource": "databasePage",
"operation": "getAll",
"databaseId": {
"__rl": true,
"value": "1e5f97e5-205a-80e4-83dc-f9d14cd49ce7",
"mode": "list",
"cachedResultName": "Leave Ledger",
"cachedResultUrl": "https://www.notion.so/1e5f97e5205a80e483dcf9d14cd49ce7"
},
"limit": 1,
"filterType": "manual",
"filters": {
"conditions": [
{
"key": "N8N Request Id|title",
"condition": "equals",
"titleValue": "={{ $json.query.requestId }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
300,
280
],
"id": "6b5d4372-5a46-4567-8398-bda6e379674c",
"name": "Get Leave Request Record",
"notesInFlow": true,
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"notes": "Find leave ledger record corresponding to this request approval."
},
{
"parameters": {
"resource": "databasePage",
"operation": "update",
"pageId": {
"__rl": true,
"value": "={{ $('Get Leave Request Record').item.json.id }}",
"mode": "id"
},
"propertiesUi": {
"propertyValues": [
{
"key": "Approval Status|status",
"statusValue": "Rejected"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
1240,
540
],
"id": "fec78b11-19eb-494b-9401-40bace0e7dcf",
"name": "Update Record to Rejected",
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "databasePage",
"operation": "update",
"pageId": {
"__rl": true,
"value": "={{ $('Get Leave Request Record').item.json.id }}",
"mode": "id"
},
"propertiesUi": {
"propertyValues": [
{
"key": "Approval Status|status",
"statusValue": "Approved"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
1240,
0
],
"id": "24e743e6-2a16-4d14-b0ff-6bd19a981407",
"name": "Update Record to Approved",
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"calendar": {
"__rl": true,
"value": "lavee@thetripguru.com",
"mode": "list",
"cachedResultName": "lavee@thetripguru.com"
},
"start": "={{ $('Update Record to Approved').item.json.property_start_date.start }}",
"end": "={{ $('Update Record to Approved').item.json.property_end_date.start.toDateTime().plus(1, \"days\") }}",
"additionalFields": {
"allday": "yes",
"description": "={{ $('Get Leave Request Record').item.json.property_description }}",
"sendUpdates": "none",
"summary": "={{ $json.property_contact_email }} - {{ $('Get Leave Type Record').item.json.name }}"
}
},
"type": "n8n-nodes-base.googleCalendar",
"typeVersion": 1.3,
"position": [
1780,
0
],
"id": "76863ce6-2d62-43fd-885a-56341482a420",
"name": "Google Calendar",
"credentials": {
"googleCalendarOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "databasePage",
"operation": "get",
"pageId": {
"__rl": true,
"value": "={{ $('Get Leave Request Record').item.json.property_requestor[0] }}",
"mode": "id"
}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
460,
280
],
"id": "6a5418ef-de34-45f3-9f61-2f37ad67fe02",
"name": "Get Requestor Record",
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "databasePage",
"operation": "get",
"pageId": {
"__rl": true,
"value": "={{ $('Get Leave Request Record').item.json.property_leave_type[0] }}",
"mode": "id"
}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
640,
280
],
"id": "8d109850-2a64-4cdd-b67d-748145d7068a",
"name": "Get Leave Type Record",
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "# If rejected",
"height": 360,
"width": 1200,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1160,
440
],
"id": "9aa61662-7eb4-424f-bc1a-da16ab543d1e",
"name": "Sticky Note8"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "7ea0b120-199b-4443-9cd8-75400cdf7f2d",
"leftValue": "={{ $('On Leave Approval Email Response').item.json.query.approved }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"looseTypeValidation": true,
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
780,
280
],
"id": "ba87c5de-370e-491b-8d1e-5410dece897d",
"name": "Approved?"
},
{
"parameters": {
"resource": "databasePage",
"operation": "update",
"pageId": {
"__rl": true,
"value": "={{ $('Get Requestor Record').item.json.id }}",
"mode": "id"
},
"propertiesUi": {
"propertyValues": [
{
"key": "PY - Used|number",
"numberValue": "={{ $json.PY }}"
},
{
"key": "AL - Used|number",
"numberValue": "={{ $json.AL }}"
},
{
"key": "SL - Used|number",
"numberValue": "={{ $json.SL }}"
},
{
"key": "BL - Used|number",
"numberValue": "={{ $json.BL }}"
},
{
"key": "Others - Used|number",
"numberValue": "={{ $json.Others }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.notion",
"typeVersion": 2.2,
"position": [
1600,
0
],
"id": "6ab02ecf-a4d2-455c-8445-78520c0201ac",
"name": "Update Leave Credits",
"credentials": {
"notionApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "30250769-625d-4c0a-b72e-879fc7b66da0",
"name": "PY",
"value": "={{ \n$('Get Leave Type Record').item.json.property_category == \"Annual Leave\" \n ? $('Get Requestor Record').item.json.property_py_current <= 0 \n ? $('Get Requestor Record').item.json.property_py_used \n : $('Get Requestor Record').item.json.property_py_used + Math.min($('Get Leave Request Record').item.json.property_leave_duration, $('Get Requestor Record').item.json.property_py_current)\n : $('Get Requestor Record').item.json.property_py_used\n}}",
"type": "number"
},
{
"id": "2bfc85f5-c64d-42cb-ae9d-1881845690ac",
"name": "AL",
"value": "={{ \n$('Get Leave Type Record').item.json.property_category == \"Annual Leave\"\n ? $('Get Requestor Record').item.json.property_py_current <= 0 \n ? $('Get Requestor Record').item.json.property_al_used + $('Get Leave Request Record').item.json.property_leave_duration \n : (\n $('Get Requestor Record').item.json.property_al_used + ($('Get Leave Request Record').item.json.property_leave_duration > $('Get Requestor Record').item.json.property_py_current )\n ? $('Get Leave Request Record').item.json.property_leave_duration - $('Get Requestor Record').item.json.property_py_current\n : 0\n )\n : $('Get Requestor Record').item.json.property_al_used\n}}\n",
"type": "number"
},
{
"id": "66f6d42b-4878-4761-a1a6-902f9dc0ca96",
"name": "SL",
"value": "={{ \n$('Get Leave Type Record').item.json.property_category == \"Sick Leave\"\n ? $('Get Requestor Record').item.json.property_sl_used + $('Get Leave Request Record').item.json.property_leave_duration\n : $('Get Requestor Record').item.json.property_sl_used\n}}\n",
"type": "number"
},
{
"id": "bbf55360-1bb0-42c1-a481-07584094da6d",
"name": "BL",
"value": "={{ \n$('Get Leave Type Record').item.json.property_category == \"Bereavement Leave\"\n ? $('Get Requestor Record').item.json.property_bl_used + $('Get Leave Request Record').item.json.property_leave_duration\n : $('Get Requestor Record').item.json.property_bl_used\n}}\n",
"type": "number"
},
{
"id": "86b65b1a-1de9-4fcd-a358-06d4b31f12fe",
"name": "Others",
"value": "={{ \n![\"Annual Leave\", \"Sick Leave\", \"Bereavement Leave\"].includes($('Get Leave Type Record').item.json.property_category)\n ? $('Get Requestor Record').item.json.property_others_used + $('Get Leave Request Record').item.json.property_leave_duration\n : $('Get Requestor Record').item.json.property_others_used\n}}\n",
"type": "number"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1420,
0
],
"id": "17e60693-caca-4e8b-bc34-d98535603a7f",
"name": "Updated Leave Credits"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $('Get Leave Request Record').item.json.property_requestor_gmail_thread }}",
"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 Your <em>{{ $('Get Leave Type Record').item.json.name }}</em> request with the following data: <br />\n Start date: {{ $('Get Leave Request Record').item.json.property_start_date.start }} <br />\n End date: {{ $('Get Leave Request Record').item.json.property_end_date.start }} <br />\n Remarks: {{ $('Get Leave Request Record').item.json.property_description }} <br />\n \n has been successfully approved.\n\n </td>\n </tr>\n </table>\n <!-- End card container -->\n </td>\n </tr>\n </table>\n </body>\n</html>\n",
"options": {
"appendAttribution": false,
"ccList": "lavee+hr@thetripguru.com"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1980,
0
],
"id": "7c61c0cb-14fc-424b-9403-bc5c991f6fcb",
"name": "Approval confirmation to requestor",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "8d62f175-05a9-4ee7-997b-c089b92de9e6",
"name": "approvers",
"value": "={{ $('Get Leave Request Record').item.json.property_approver_gmail_thread.split(',') }}",
"type": "array"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2180,
0
],
"id": "05379698-3e1f-4a84-bd25-85b5e07a80cc",
"name": "Set approvers to split"
},
{
"parameters": {
"fieldToSplitOut": "approvers",
"options": {}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
2360,
0
],
"id": "4d96b84f-8e62-406b-bf6f-8c77055f7932",
"name": "Split Out"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.approvers.split(':')[1] }}",
"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 Approval was successful for the <em>{{ $('Get Leave Type Record').item.json.name }}</em> request with the following data: <br />\n Start date: {{ $('Get Leave Request Record').item.json.property_start_date.start }} <br />\n End date: {{ $('Get Leave Request Record').item.json.property_end_date.start }} <br />\n Remarks: {{ $('Get Leave Request Record').item.json.property_description }} <br />\n\n </td>\n </tr>\n </table>\n <!-- End card container -->\n </td>\n </tr>\n </table>\n </body>\n</html>\n",
"options": {
"appendAttribution": false,
"ccList": "lavee+hr@thetripguru.com"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2560,
0
],
"id": "ba78abab-1ab7-454a-a2bb-c5b63a9ea560",
"name": "Approval confirmation to approvers",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "8d62f175-05a9-4ee7-997b-c089b92de9e6",
"name": "approvers",
"value": "={{ $('Get Leave Request Record').item.json.property_approver_gmail_thread.split(',') }}",
"type": "array"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1640,
540
],
"id": "0a714136-ab7d-49b3-98da-5f68831c2c52",
"name": "Set approvers to split1"
},
{
"parameters": {
"fieldToSplitOut": "approvers",
"options": {}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
1820,
540
],
"id": "05ecb9b8-e139-405c-8177-d407c9a2c6aa",
"name": "Split Out1"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.approvers.split(':')[1] }}",
"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;\"><h2 style=\"color: red;\">Leave request rejected.</h2></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 Rejection was successful for the <em>{{ $('Get Leave Type Record').item.json.name }}</em> request with the following data: <br />\n Start date: {{ $('Get Leave Request Record').item.json.property_start_date.start }} <br />\n End date: {{ $('Get Leave Request Record').item.json.property_end_date.start }} <br />\n Remarks: {{ $('Get Leave Request Record').item.json.property_description }} <br />\n\n </td>\n </tr>\n </table>\n <!-- End card container -->\n </td>\n </tr>\n </table>\n </body>\n</html>\n",
"options": {
"appendAttribution": false,
"ccList": "lavee+hr@thetripguru.com"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2020,
540
],
"id": "6167e38c-239e-4d77-8134-3851a87d13dc",
"name": "Approval confirmation to approvers1",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $('Get Leave Request Record').item.json.property_requestor_gmail_thread }}",
"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:12px 24px;\">\n <h2 style=\"color: red;\">Leave request rejected</h2><br />\n\n </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; background-color: #ebafab;\"\n >\n Your <em>{{ $('Get Leave Type Record').item.json.name }}</em> request with the following data: <br />\n Start date: {{ $('Get Leave Request Record').item.json.property_start_date.start }} <br />\n End date: {{ $('Get Leave Request Record').item.json.property_end_date.start }} <br />\n Remarks: {{ $('Get Leave Request Record').item.json.property_description }} <br />\n \n has been rejected. Please contact your supervisor for more info.\n\n </td>\n </tr>\n </table>\n <!-- End card container -->\n </td>\n </tr>\n </table>\n </body>\n</html>\n",
"options": {
"appendAttribution": false,
"ccList": "lavee+hr@thetripguru.com"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1440,
540
],
"id": "807bcd69-6b76-4148-a134-dbbdc118ea06",
"name": "Rejection confirmation to requestor",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "# Gather post approval data",
"height": 360,
"width": 900,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
40,
160
],
"id": "7a6f1ca7-7745-47bf-a4ae-54a8977a2ce7",
"name": "Sticky Note"
},
{
"parameters": {
"content": "# If approved",
"height": 320,
"width": 1680,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1160,
-80
],
"id": "dd9e4fd8-cb32-415e-b35d-cfe70467430e",
"name": "Sticky Note9"
}
],
"connections": {
"On Leave Approval Email Response": {
"main": [
[
{
"node": "Get Leave Request Record",
"type": "main",
"index": 0
}
]
]
},
"Get Leave Request Record": {
"main": [
[
{
"node": "Get Requestor Record",
"type": "main",
"index": 0
}
]
]
},
"Update Record to Rejected": {
"main": [
[
{
"node": "Rejection confirmation to requestor",
"type": "main",
"index": 0
}
]
]
},
"Update Record to Approved": {
"main": [
[
{
"node": "Updated Leave Credits",
"type": "main",
"index": 0
}
]
]
},
"Google Calendar": {
"main": [
[
{
"node": "Approval confirmation to requestor",
"type": "main",
"index": 0
}
]
]
},
"Get Requestor Record": {
"main": [
[
{
"node": "Get Leave Type Record",
"type": "main",
"index": 0
}
]
]
},
"Get Leave Type Record": {
"main": [
[
{
"node": "Approved?",
"type": "main",
"index": 0
}
]
]
},
"Approved?": {
"main": [
[
{
"node": "Update Record to Approved",
"type": "main",
"index": 0
}
],
[
{
"node": "Update Record to Rejected",
"type": "main",
"index": 0
}
]
]
},
"Update Leave Credits": {
"main": [
[
{
"node": "Google Calendar",
"type": "main",
"index": 0
}
]
]
},
"Updated Leave Credits": {
"main": [
[
{
"node": "Update Leave Credits",
"type": "main",
"index": 0
}
]
]
},
"Approval confirmation to requestor": {
"main": [
[
{
"node": "Set approvers to split",
"type": "main",
"index": 0
}
]
]
},
"Set approvers to split": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Approval confirmation to approvers",
"type": "main",
"index": 0
}
]
]
},
"Set approvers to split1": {
"main": [
[
{
"node": "Split Out1",
"type": "main",
"index": 0
}
]
]
},
"Split Out1": {
"main": [
[
{
"node": "Approval confirmation to approvers1",
"type": "main",
"index": 0
}
]
]
},
"Rejection confirmation to requestor": {
"main": [
[
{
"node": "Set approvers to split1",
"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.
gmailOAuth2googleCalendarOAuth2ApinotionApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Tg Leaves Webhook. Uses notion, googleCalendar, gmail. Webhook trigger; 21 nodes.
Source: https://gist.github.com/laveesingh/e6147341d1080a4b7110bb5f8566bbb9 — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Proceeding. Uses gmail, googleTasks, googleCalendar, notion. Webhook trigger; 11 nodes.
Complete Calendly automation that handles confirmations, cancellations and reschedules in a single workflow. WHAT IT DOES:
Automate legal appointment booking end-to-end. Clients request a slot via webhook, Google Calendar checks availability, Stripe collects payment, and a confirmed calendar event is created automatically
Automate your GoHighLevel (GHL) client onboarding process from the moment a deal is marked as “Won.” This workflow seamlessly generates client folders in Google Drive, duplicates contract and kickoff
Fully automates your Day 0–30 employee onboarding sequence the moment HR submits a webhook. No manual steps, no missed tasks. 🔐 Provisions Google Workspace account via Admin API 💬 Posts a personalised