This workflow corresponds to n8n.io template #16080 — we link there as the canonical source.
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 →
{
"id": "mt0kNrGX5m9-KtepDaQ-l",
"name": "Automate lawyer appointment booking with Stripe payments and Google Calendar",
"tags": [],
"nodes": [
{
"id": "980df30f-fa2e-4f67-a91e-6c3fc4e4b3d4",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Automate lawyer appointment booking with Stripe payments and Google Calendar\n\n### How it works\n\nThis workflow automates lawyer appointment booking from an incoming client request through payment, calendar confirmation, notifications, logging, and reminders. It first checks Google Calendar availability, sends an unavailable response when needed, or creates and distributes a Stripe payment link when the slot is open. A separate Stripe confirmation webhook then finalizes the booking by creating the calendar event, notifying the client and lawyer, logging the booking, and sending a timed reminder.\n\n### Setup steps\n\n- Configure the booking request webhook URL in the client-facing booking form or application.\n- Connect Google Calendar credentials and select the lawyer calendar used for availability checks and confirmed appointment creation.\n- Configure Stripe API authentication for creating payment links, and set the Stripe payment confirmation webhook to call the workflow\u2019s payment-confirmed webhook.\n- Connect Gmail credentials for client emails, unavailable-slot messages, lawyer notifications, and reminders.\n- Connect Telegram bot credentials and configure the client/lawyer chat IDs or routing fields used by the Telegram nodes.\n- Connect Google Sheets credentials and select the spreadsheet/table used to log confirmed bookings.\n- Verify field mappings for client name, email, appointment date/time, lawyer details, payment link, and booking ID across the Set, email, calendar, Stripe, Telegram, and Sheets nodes.\n\n### Customization\n\nAdjust the consultation price, Stripe product/price IDs, appointment duration, email and Telegram message templates, calendar availability rules, Google Sheets columns, and reminder timing to match the law firm\u2019s booking policies."
},
"typeVersion": 1
},
{
"id": "45201f70-e8b3-449c-b99e-4b7dcd95e44b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
0
],
"parameters": {
"color": 7,
"width": 416,
"height": 336,
"content": "## Capture booking request\n\nReceives a new appointment request through a webhook and normalizes the submitted booking details into fields used by the rest of the workflow."
},
"typeVersion": 1
},
{
"id": "746f7dd1-19cd-43e2-89c8-f4c7da7c6f54",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1104,
16
],
"parameters": {
"color": 7,
"width": 640,
"height": 528,
"content": "## Check requested slot\n\nChecks the requested appointment time against Google Calendar, branches based on availability, and sends an unavailable-slot email when the requested time cannot be booked."
},
"typeVersion": 1
},
{
"id": "94363ba2-b841-490d-9c8f-79a2b9c63b9c",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
16
],
"parameters": {
"color": 7,
"width": 624,
"height": 512,
"content": "## Create payment link\n\nFor available slots, creates a Stripe payment link, stores the returned payment-link details, and sends the payment link to the client by email and Telegram."
},
"typeVersion": 1
},
{
"id": "6858dc43-2da7-448f-a88c-ba97f2fefa4f",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2448,
16
],
"parameters": {
"color": 7,
"width": 624,
"height": 320,
"content": "## Confirm paid booking\n\nStarts from the Stripe payment confirmation webhook, generates an internal booking ID, and creates the confirmed appointment event in Google Calendar."
},
"typeVersion": 1
},
{
"id": "326a4af8-74cc-4351-bcbc-9b54912a0fa2",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
3104,
48
],
"parameters": {
"color": 7,
"width": 640,
"height": 304,
"content": "## Notify client and lawyer\n\nSends the booking confirmation to the client, then notifies the lawyer by email and Telegram about the confirmed appointment."
},
"typeVersion": 1
},
{
"id": "9de1bf7b-b007-463d-a32d-3cdffc2f9551",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
3776,
0
],
"parameters": {
"color": 7,
"height": 336,
"content": "## Log booking record\n\nWrites the confirmed booking details to Google Sheets for tracking and reporting."
},
"typeVersion": 1
},
{
"id": "da6b9143-8a96-4f49-bb98-38ae9df4c6a6",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
4048,
16
],
"parameters": {
"color": 7,
"width": 400,
"height": 320,
"content": "## Schedule client reminder\n\nWaits until the reminder window and sends the client a 24-hour appointment reminder email."
},
"typeVersion": 1
},
{
"id": "b3a6e47d-417d-4183-8c5a-0dde3fbc4a19",
"name": "When Booking Requested",
"type": "n8n-nodes-base.webhook",
"position": [
608,
176
],
"parameters": {
"path": "lawyer-booking",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "d9199a14-e71b-45e1-8b04-ef3d3a6d40b6",
"name": "Set Booking Details",
"type": "n8n-nodes-base.set",
"position": [
832,
176
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "c3cbe5e0-3db2-4609-9b34-2f5b30149c74",
"name": "Check Calendar for Open Slot",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1152,
176
],
"parameters": {
"calendar": {
"__rl": true,
"mode": "id",
"value": "YOUR_LAWYER_CALENDAR_ID"
},
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "a9e07b42-05e3-497f-8129-27a71888e5d5",
"name": "If Slot is Available",
"type": "n8n-nodes-base.if",
"position": [
1376,
176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "condition-available",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ $json.items.length }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "56055c89-7ff6-4334-aba0-924a28840bd4",
"name": "Email Slot Unavailability",
"type": "n8n-nodes-base.gmail",
"position": [
1600,
384
],
"parameters": {
"sendTo": "={{ $('Set Booking Details').item.json.client_email }}",
"message": "=Dear {{ $('Set Booking Details').item.json.client_name }},\n\nThank you for reaching out. Unfortunately the requested time slot ({{ $('Set Booking Details').item.json.appointment_date }} at {{ $('Set Booking Details').item.json.appointment_time }}) is not available.\n\nPlease reply with an alternative date and time.\n\nBest regards,\nThe Legal Team",
"options": {},
"subject": "Appointment Request \u2014 Slot Not Available"
},
"typeVersion": 2
},
{
"id": "76290f56-b004-49cf-bfa9-8a3cebdee619",
"name": "Post to Stripe Payment API",
"type": "n8n-nodes-base.httpRequest",
"position": [
1824,
176
],
"parameters": {
"url": "https://api.stripe.com/v1/payment_links",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "line_items[0][price_data][currency]",
"value": "usd"
},
{
"name": "line_items[0][price_data][product_data][name]",
"value": "={{ $('Set Booking Details').item.json.service_type }}"
},
{
"name": "line_items[0][price_data][unit_amount]",
"value": "={{ $('Set Booking Details').item.json.amount * 100 }}"
},
{
"name": "line_items[0][quantity]",
"value": "1"
},
{
"name": "metadata[client_name]",
"value": "={{ $('Set Booking Details').item.json.client_name }}"
},
{
"name": "metadata[client_email]",
"value": "={{ $('Set Booking Details').item.json.client_email }}"
},
{
"name": "metadata[client_phone]",
"value": "={{ $('Set Booking Details').item.json.client_phone }}"
},
{
"name": "metadata[appointment_date]",
"value": "={{ $('Set Booking Details').item.json.appointment_date }}"
},
{
"name": "metadata[appointment_time]",
"value": "={{ $('Set Booking Details').item.json.appointment_time }}"
},
{
"name": "metadata[service_type]",
"value": "={{ $('Set Booking Details').item.json.service_type }}"
},
{
"name": "metadata[amount]",
"value": "={{ $('Set Booking Details').item.json.amount }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
},
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded"
}
]
}
},
"typeVersion": 4
},
{
"id": "dfdabd94-3f03-4b90-bd58-17cd8a739dc2",
"name": "Build Payment Link Info",
"type": "n8n-nodes-base.set",
"position": [
2048,
176
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "94b0ac1f-023c-41c4-851f-0f9af4dc1b85",
"name": "Email Payment Link to Client",
"type": "n8n-nodes-base.gmail",
"position": [
2256,
176
],
"parameters": {
"sendTo": "={{ $json.client_email }}",
"message": "=Dear {{ $json.client_name }},\n\nYour requested slot is available! Complete payment to confirm your appointment.\n\n\ud83d\udcc5 Service: {{ $json.service_type }}\n\ud83d\uddd3\ufe0f Date: {{ $json.appointment_date }}\n\u23f0 Time: {{ $json.appointment_time }}\n\ud83d\udcb0 Fee: ${{ $json.amount }}\n\n\ud83d\udc49 Pay here: {{ $json.payment_url }}\n\nThis link expires in 24 hours.\n\nBest regards,\nThe Legal Team",
"options": {},
"subject": "=Complete Your Booking \u2014 {{ $json.service_type }} on {{ $json.appointment_date }}"
},
"typeVersion": 2
},
{
"id": "b1e813cc-fe3f-4a25-b17c-aaafc8cb9c7e",
"name": "Telegram Payment Link",
"type": "n8n-nodes-base.telegram",
"position": [
2256,
368
],
"parameters": {
"text": "=\ud83d\udc4b Hi {{ $('Build Payment Link Info').item.json.client_name }}!\n\nYour slot is available. Complete payment to confirm:\n\n\ud83d\udcc5 {{ $('Build Payment Link Info').item.json.service_type }}\n\ud83d\uddd3\ufe0f {{ $('Build Payment Link Info').item.json.appointment_date }} at {{ $('Build Payment Link Info').item.json.appointment_time }}\n\ud83d\udcb0 ${{ $('Build Payment Link Info').item.json.amount }}\n\n\ud83d\udc49 {{ $('Build Payment Link Info').item.json.payment_url }}\n\nLink expires in 24 hours.",
"chatId": "YOUR_TELEGRAM_CHAT_ID_CLIENT",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "7cfd20b7-0f41-4351-89e7-f519e2cab6c8",
"name": "When Stripe Payment Confirmed",
"type": "n8n-nodes-base.webhook",
"position": [
2496,
176
],
"parameters": {
"path": "stripe-payment-confirmed",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "0684dba3-422c-4d84-849c-0d41d554087e",
"name": "Set Booking Identifier",
"type": "n8n-nodes-base.set",
"position": [
2720,
176
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8f8d1d7d-ee04-4455-b312-254066838ca7",
"name": "Add Event to Calendar",
"type": "n8n-nodes-base.googleCalendar",
"position": [
2928,
176
],
"parameters": {
"end": "={{ DateTime.fromISO($json.appointment_datetime).plus({hours: 1}).toISO() }}",
"start": "={{ $json.appointment_datetime }}",
"calendar": {
"__rl": true,
"mode": "id",
"value": "YOUR_LAWYER_CALENDAR_ID"
},
"additionalFields": {
"summary": "=\u2696\ufe0f {{ $json.service_type }} \u2014 {{ $json.client_name }}",
"attendees": "={{ $json.client_email }}",
"description": "=Booking ID: {{ $json.booking_id }}\nClient: {{ $json.client_name }}\nPhone: {{ $json.client_phone }}\nService: {{ $json.service_type }}\nAmount Paid: ${{ $json.amount_paid }}"
}
},
"typeVersion": 1
},
{
"id": "6284bccb-3aca-4b6f-b18a-d290744aebab",
"name": "Email Booking Confirmation",
"type": "n8n-nodes-base.gmail",
"position": [
3152,
176
],
"parameters": {
"sendTo": "={{ $('Set Booking Identifier').item.json.client_email }}",
"message": "=Dear {{ $('Set Booking Identifier').item.json.client_name }},\n\nYour appointment is confirmed!\n\n\ud83d\udccb Booking ID: {{ $('Set Booking Identifier').item.json.booking_id }}\n\ud83d\udcc5 Service: {{ $('Set Booking Identifier').item.json.service_type }}\n\ud83d\uddd3\ufe0f Date: {{ $('Set Booking Identifier').item.json.appointment_date }}\n\u23f0 Time: {{ $('Set Booking Identifier').item.json.appointment_time }}\n\ud83d\udcb0 Amount Paid: ${{ $('Set Booking Identifier').item.json.amount_paid }}\n\nYou will receive a reminder 24 hours before your appointment.\n\nBest regards,\nThe Legal Team",
"options": {},
"subject": "=\u2705 Appointment Confirmed \u2014 Booking ID: {{ $('Set Booking Identifier').item.json.booking_id }}"
},
"typeVersion": 2
},
{
"id": "e6935e47-f33f-4ed3-9f42-6f19d80f7533",
"name": "Email Lawyer Notification",
"type": "n8n-nodes-base.gmail",
"position": [
3376,
176
],
"parameters": {
"sendTo": "YOUR_LAWYER_EMAIL",
"message": "=New confirmed appointment:\n\n\ud83d\udccb Booking ID: {{ $('Set Booking Identifier').item.json.booking_id }}\n\ud83d\udc64 Client: {{ $('Set Booking Identifier').item.json.client_name }}\n\ud83d\udce7 Email: {{ $('Set Booking Identifier').item.json.client_email }}\n\ud83d\udcde Phone: {{ $('Set Booking Identifier').item.json.client_phone }}\n\ud83d\udcc5 Service: {{ $('Set Booking Identifier').item.json.service_type }}\n\ud83d\uddd3\ufe0f Date: {{ $('Set Booking Identifier').item.json.appointment_date }}\n\u23f0 Time: {{ $('Set Booking Identifier').item.json.appointment_time }}\n\ud83d\udcb0 Paid: ${{ $('Set Booking Identifier').item.json.amount_paid }}\n\nCalendar event created automatically.",
"options": {},
"subject": "=\ud83d\udcc5 New Appointment \u2014 {{ $('Set Booking Identifier').item.json.client_name }}"
},
"typeVersion": 2
},
{
"id": "a4e1bcc4-d4af-4c85-8aa6-c74ab552dfdd",
"name": "Telegram Lawyer Notification",
"type": "n8n-nodes-base.telegram",
"position": [
3600,
176
],
"parameters": {
"text": "=\u2696\ufe0f New Appointment Confirmed!\n\n\ud83d\udccb {{ $('Set Booking Identifier').item.json.booking_id }}\n\ud83d\udc64 {{ $('Set Booking Identifier').item.json.client_name }}\n\ud83d\udce7 {{ $('Set Booking Identifier').item.json.client_email }}\n\ud83d\udcde {{ $('Set Booking Identifier').item.json.client_phone }}\n\ud83d\udcc5 {{ $('Set Booking Identifier').item.json.service_type }}\n\ud83d\uddd3\ufe0f {{ $('Set Booking Identifier').item.json.appointment_date }} at {{ $('Set Booking Identifier').item.json.appointment_time }}\n\ud83d\udcb0 ${{ $('Set Booking Identifier').item.json.amount_paid }} received\n\n\u2705 Calendar event created.",
"chatId": "YOUR_TELEGRAM_CHAT_ID_LAWYER",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "17fa18ef-048a-45de-ac56-b387e3c486d8",
"name": "Append Booking to Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
3824,
176
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $('Set Booking Identifier').item.json.appointment_date }}",
"Time": "={{ $('Set Booking Identifier').item.json.appointment_time }}",
"Status": "Confirmed",
"Service": "={{ $('Set Booking Identifier').item.json.service_type }}",
"Timestamp": "={{ $now.toISO() }}",
"Booking ID": "={{ $('Set Booking Identifier').item.json.booking_id }}",
"Amount Paid": "={{ $('Set Booking Identifier').item.json.amount_paid }}",
"Client Name": "={{ $('Set Booking Identifier').item.json.client_name }}",
"Client Email": "={{ $('Set Booking Identifier').item.json.client_email }}"
},
"schema": [
{
"id": "Booking ID",
"type": "string",
"display": true,
"required": false,
"displayName": "Booking ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"display": true,
"required": false,
"displayName": "Service",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Time",
"type": "string",
"display": true,
"required": false,
"displayName": "Time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount Paid",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount Paid",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": []
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"typeVersion": 4
},
{
"id": "ecb805d7-dd1d-4bf0-9fbf-667cb5134313",
"name": "Wait 23 Hours",
"type": "n8n-nodes-base.wait",
"position": [
4096,
176
],
"parameters": {
"amount": 23
},
"typeVersion": 1
},
{
"id": "f2d487c3-c58e-4bfd-9894-1a98ce6dfa19",
"name": "Email 24hr Reminder to Client",
"type": "n8n-nodes-base.gmail",
"position": [
4304,
176
],
"parameters": {
"sendTo": "={{ $('Set Booking Identifier').item.json.client_email }}",
"message": "=Dear {{ $('Set Booking Identifier').item.json.client_name }},\n\nThis is a reminder that your appointment is tomorrow.\n\n\ud83d\udccb Booking ID: {{ $('Set Booking Identifier').item.json.booking_id }}\n\ud83d\udcc5 Service: {{ $('Set Booking Identifier').item.json.service_type }}\n\ud83d\uddd3\ufe0f Date: {{ $('Set Booking Identifier').item.json.appointment_date }}\n\u23f0 Time: {{ $('Set Booking Identifier').item.json.appointment_time }}\n\nPlease be available at the scheduled time. To reschedule, reply to this email.\n\nBest regards,\nThe Legal Team",
"options": {},
"subject": "=\u23f0 Reminder \u2014 Appointment Tomorrow: {{ $('Set Booking Identifier').item.json.service_type }}"
},
"typeVersion": 2
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"connections": {
"Wait 23 Hours": {
"main": [
[
{
"node": "Email 24hr Reminder to Client",
"type": "main",
"index": 0
}
]
]
},
"Set Booking Details": {
"main": [
[
{
"node": "Check Calendar for Open Slot",
"type": "main",
"index": 0
}
]
]
},
"If Slot is Available": {
"main": [
[
{
"node": "Post to Stripe Payment API",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Slot Unavailability",
"type": "main",
"index": 0
}
]
]
},
"Add Event to Calendar": {
"main": [
[
{
"node": "Email Booking Confirmation",
"type": "main",
"index": 0
}
]
]
},
"Set Booking Identifier": {
"main": [
[
{
"node": "Add Event to Calendar",
"type": "main",
"index": 0
}
]
]
},
"When Booking Requested": {
"main": [
[
{
"node": "Set Booking Details",
"type": "main",
"index": 0
}
]
]
},
"Build Payment Link Info": {
"main": [
[
{
"node": "Email Payment Link to Client",
"type": "main",
"index": 0
}
]
]
},
"Append Booking to Sheets": {
"main": [
[
{
"node": "Wait 23 Hours",
"type": "main",
"index": 0
}
]
]
},
"Email Lawyer Notification": {
"main": [
[
{
"node": "Telegram Lawyer Notification",
"type": "main",
"index": 0
}
]
]
},
"Email Booking Confirmation": {
"main": [
[
{
"node": "Email Lawyer Notification",
"type": "main",
"index": 0
}
]
]
},
"Post to Stripe Payment API": {
"main": [
[
{
"node": "Build Payment Link Info",
"type": "main",
"index": 0
}
]
]
},
"Check Calendar for Open Slot": {
"main": [
[
{
"node": "If Slot is Available",
"type": "main",
"index": 0
}
]
]
},
"Email Payment Link to Client": {
"main": [
[
{
"node": "Telegram Payment Link",
"type": "main",
"index": 0
}
]
]
},
"Telegram Lawyer Notification": {
"main": [
[
{
"node": "Append Booking to Sheets",
"type": "main",
"index": 0
}
]
]
},
"When Stripe Payment Confirmed": {
"main": [
[
{
"node": "Set Booking Identifier",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
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. The lawyer gets notified via Gmail and Telegram with a 24-hour reminder sent…
Source: https://n8n.io/workflows/16080/ — 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.
✨🔪 Advanced AI Powered Document Parsing & Text Extraction with Llama Parse. Uses gmail, gmailTrigger, limit, stickyNote. Webhook trigger; 54 nodes.
Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu
This template turns Podium's conversation inbox into a full sales CRM with a custom funnel, AI message classification, automated drip follow-ups, daily admin reports, and a live Kanban dashboard. Six
Ticketing Backend automates registration, QR-ticket generation, email delivery, and check-in validation using Google Sheets, Gmail, and a webhook scanner — reducing manual ticket prep from ~3 hours to
Workflow1-2-3. Uses httpRequest, gmail, telegram, postgres. Webhook trigger; 34 nodes.