This workflow corresponds to n8n.io template #11759 — we link there as the canonical source.
This workflow follows the Google Sheets → Telegram 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "741dae62-be44-4cd8-9639-65bc91e8931e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
752,
-448
],
"parameters": {
"color": 7,
"width": 704,
"height": 784,
"content": "## 2. Check if user has used up the 5 free email limit daily. Send error message if exceeded"
},
"typeVersion": 1
},
{
"id": "f8443dd0-cc38-4be6-922d-2cde7fbd1e79",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1472,
-304
],
"parameters": {
"color": 7,
"width": 688,
"height": 752,
"content": "## 3. Update database, send email and notification to self"
},
"typeVersion": 1
},
{
"id": "ccbb2d36-3adf-4c93-bc9b-3ab0b1f5df19",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
-288
],
"parameters": {
"color": 7,
"width": 816,
"height": 528,
"content": "## 1. Receive data from newsletter page, validate if free or pro user. Process free user and send pro user's message"
},
"typeVersion": 1
},
{
"id": "a2934194-5a52-4097-b508-1d45c5204aa4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-864,
-432
],
"parameters": {
"width": 720,
"height": 816,
"content": "## Email Newsletter Builder with Rate Limiting and User Tracking\n\n## How it works\n- **Webhook1** receives the data from the email newsletter page - attached below\n- **Check mode1** if the user is a pro or demo\n- **Google Sheet Read** checks if the user already exists in the database or has previously used the newsletter builder\n- **Check User Exists2** code node check if the user exists and display the data, if not, then pass to **Check User Exists1** if node to filter\n- **Check Limit Logic** code node, read the data and validate if it has run not more than 5 times in a day\n- **Limit Reached Response** and **Success Response** to respond to the newsletter builder\n- **Google Sheet** creates new users and also updates them\n- **SendGrid** email node, to send email\n- **Telegram** to send notification to self \n\n## Setup\n1. Get the webform and Google Sheet template attached below\n2. Match the webhook in the webform to send data\n3. Match template to Google Sheet Credential\n4. Register on [SendGrid](https://login.sendgrid.com/login/) and link to SendGrid node credential\n5. Make a [telegram](https://web.telegram.org/a/) bot and insert credentials to the Telegram node\n\n## [Get the Email Newsletter Builder Webform](https://drive.google.com/file/d/1ZipYXImNi8JbwnekzphqHoFKf5Qbhu6g/view?usp=sharing)\n## [Get the Google Sheet Template](https://docs.google.com/spreadsheets/d/1JvsOzkCaJzJN8-x1hldFA-H6iPc0A9MH-mVYBCEWtJw/edit?usp=sharing)"
},
"typeVersion": 1
},
{
"id": "76e322ad-897b-4317-bbd0-9150ab41af36",
"name": "Check Limit Logic",
"type": "n8n-nodes-base.code",
"position": [
1104,
-176
],
"parameters": {
"jsCode": "// Use JavaScript Date object\nconst today = new Date().toISOString().split('T')[0]; // Gets 'yyyy-MM-dd'\nconst userDate = $input.item.json.Last_Send_Date;\nconst sendCount = parseInt($input.item.json.Send_Count) || 0;\n\nlet newCount1 = sendCount;\nlet newCount = $input.item.json.Total_Sent;\nlet canSend = false;\n\nif (userDate === today) {\n // Same day - check limit\n if (sendCount < 5) {\n canSend = true;\n newCount1 = sendCount + 1;\n }\n} else {\n // New day - reset counter\n canSend = true;\n newCount1 = 1;\n}\n\nreturn {\n canSend: canSend,\n Total_Sent: newCount,\n Send_Count: newCount1,\n Email: $input.item.json.Email,\n rowNumber: $input.item.json.row_number,\n Last_Send_Date: today\n};"
},
"typeVersion": 2
},
{
"id": "f2088732-d7b7-430b-9194-0a3d1a9c350b",
"name": "Google Sheets Read",
"type": "n8n-nodes-base.googleSheets",
"position": [
352,
-160
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.body.from }}",
"lookupColumn": "=Email"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit?usp=drivesdk",
"cachedResultName": "Email_Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5,
"alwaysOutputData": true
},
{
"id": "f12ded09-2154-4c7a-9bdd-df9833bd9038",
"name": "Send Email (Pro)",
"type": "n8n-nodes-base.sendGrid",
"position": [
96,
64
],
"parameters": {
"subject": "={{ $json.body.subject }}",
"toEmail": "={{ $json.body.to }}",
"fromName": "Pro User",
"resource": "mail",
"fromEmail": "your_email_address",
"contentType": "text/html",
"contentValue": "={{ $json.body.html }}",
"additionalFields": {}
},
"credentials": {
"sendGridApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "195d91d2-f052-4594-8bc7-327ea919b662",
"name": "Webhook1",
"type": "n8n-nodes-base.webhook",
"position": [
-80,
-144
],
"parameters": {
"path": "236f9261-dd76-47e7-b09a-2667a0f315bf",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1
},
{
"id": "dd8de3a3-85c7-4f88-9c4c-105a3928b80f",
"name": "Check Mode1",
"type": "n8n-nodes-base.if",
"position": [
112,
-144
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.body.mode}}",
"value2": "demo",
"operation": "contains"
}
]
}
},
"typeVersion": 1
},
{
"id": "d0503c3a-1b59-4771-bea2-c3fbc73eb8ea",
"name": "Check User Exists1",
"type": "n8n-nodes-base.if",
"position": [
832,
-160
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "user-exists",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.exists }}",
"rightValue": "true"
}
]
}
},
"typeVersion": 2
},
{
"id": "491d70ea-b8e2-41cb-a3a2-d2721ef2df21",
"name": "Create New User1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1520,
208
],
"parameters": {
"columns": {
"value": {
"Email": "={{ $('Webhook1').item.json.body.from }}",
"Send_Count": 1,
"Total_Sent": 1,
"Last_Send_Date": "={{ $now.format('yyyy-MM-dd') }}"
},
"schema": [
{
"id": "Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Send_Count",
"type": "string",
"display": true,
"required": false,
"displayName": "Send_Count",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last_Send_Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Last_Send_Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total_Sent",
"type": "string",
"display": true,
"required": false,
"displayName": "Total_Sent",
"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/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit?usp=drivesdk",
"cachedResultName": "Email_Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "8ca68822-b69f-485d-9a69-6582b2ef4e56",
"name": "Can Send?1",
"type": "n8n-nodes-base.if",
"position": [
1296,
-176
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "can-send",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.canSend }}",
"rightValue": "true"
}
]
}
},
"typeVersion": 2
},
{
"id": "d341ce13-b80a-41ff-8a6a-9b300c215555",
"name": "Update User Count1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1520,
-192
],
"parameters": {
"columns": {
"value": {
"Email": "={{ $json.Email }}",
"Send_Count": "={{ $json.Send_Count }}",
"Total_Sent": "={{ $json.Total_Sent + 1 }}",
"row_number": 0,
"Last_Send_Date": "={{ $json.Last_Send_Date }}"
},
"schema": [
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Send_Count",
"type": "string",
"display": true,
"required": false,
"displayName": "Send_Count",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last_Send_Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Last_Send_Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total_Sent",
"type": "string",
"display": true,
"required": false,
"displayName": "Total_Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"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/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1OLIz-oxje6O-RjhVv0NXyNOrgd3hALTYnBKjo27sj9Q/edit?usp=drivesdk",
"cachedResultName": "Email_Tracker"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "11b470ce-97a3-4f64-8474-f9693193361e",
"name": "Send Email (Demo)1",
"type": "n8n-nodes-base.sendGrid",
"position": [
1776,
0
],
"parameters": {
"subject": "={{ $('Webhook1').item.json.body.subject }}",
"toEmail": "={{ $('Webhook1').item.json.body.to }}",
"fromName": "={{ $('Webhook1').item.json.body.from }}",
"resource": "mail",
"fromEmail": "your_email_address",
"contentType": "text/html",
"contentValue": "={{ $('Webhook1').item.json.body.html }}",
"additionalFields": {}
},
"credentials": {
"sendGridApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "6f68ad76-39de-4eee-9205-26ce321c34ba",
"name": "Success Response (Demo)1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1984,
0
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ { \"success\": true, \"message\": \"Email sent successfully!\", \"mode\": \"demo\", \"remaining\": 5 - $json.newCount } }}"
},
"typeVersion": 1
},
{
"id": "904b1aed-c33f-4dd7-847b-26f0ef727cc9",
"name": "Limit Reached Response1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1296,
-352
],
"parameters": {
"options": {
"responseCode": 429
},
"respondWith": "json",
"responseBody": "={{ { \"success\": false, \"error\": \"Daily limit reached (5 emails/day)\", \"message\": \"You've reached your daily limit. Upgrade to Pro for unlimited sends!\", \"current_count\": $json.currentCount } }}"
},
"typeVersion": 1
},
{
"id": "834e8273-61ed-4959-83da-aec736a3297c",
"name": "Success Response (Pro)1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
336,
64
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ { \"success\": true, \"message\": \"Email sent successfully!\", \"mode\": \"pro\" } }}"
},
"typeVersion": 1
},
{
"id": "f8182866-68ae-49cf-81d8-b2ac8bd3add4",
"name": "Telegram Notification1",
"type": "n8n-nodes-base.telegram",
"position": [
1792,
-192
],
"parameters": {
"text": "=\ud83d\udce7 Demo email sent from: {{ $('Webhook1').item.json.body.from }}\n\u2709\ufe0f To: {{ $('Webhook1').item.json.body.to }}\n\ud83d\udcca Remaining today: {{ 5 - $json.Send_Count }}",
"chatId": "Your_telegram_chat_id",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "f08a3491-0e66-40a3-8f9a-44b299f638fc",
"name": "Check User Exists2",
"type": "n8n-nodes-base.code",
"position": [
576,
-160
],
"parameters": {
"jsCode": "const email = $node[\"Webhook1\"].json.body.from.toLowerCase();\n\n// Detect real rows (not empty placeholder)\nconst realRows = items.filter(\n item => item.json.Email && item.json.Email.trim() !== ''\n);\n\nif (realRows.length > 0) {\n return realRows.map(item => ({\n json: {\n ...item.json, // Google Sheets row\n email,\n exists: true\n }\n }));\n}\n\n// No match in sheet\nreturn [{\n json: {\n email,\n exists: false,\n matches: 0\n }\n}];"
},
"typeVersion": 2
}
],
"connections": {
"Webhook1": {
"main": [
[
{
"node": "Check Mode1",
"type": "main",
"index": 0
}
]
]
},
"Can Send?1": {
"main": [
[
{
"node": "Update User Count1",
"type": "main",
"index": 0
}
],
[
{
"node": "Limit Reached Response1",
"type": "main",
"index": 0
}
]
]
},
"Check Mode1": {
"main": [
[
{
"node": "Google Sheets Read",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Email (Pro)",
"type": "main",
"index": 0
}
]
]
},
"Create New User1": {
"main": [
[
{
"node": "Telegram Notification1",
"type": "main",
"index": 0
},
{
"node": "Send Email (Demo)1",
"type": "main",
"index": 0
}
]
]
},
"Send Email (Pro)": {
"main": [
[
{
"node": "Success Response (Pro)1",
"type": "main",
"index": 0
}
]
]
},
"Check Limit Logic": {
"main": [
[
{
"node": "Can Send?1",
"type": "main",
"index": 0
}
]
]
},
"Check User Exists1": {
"main": [
[
{
"node": "Check Limit Logic",
"type": "main",
"index": 0
}
],
[
{
"node": "Create New User1",
"type": "main",
"index": 0
}
]
]
},
"Check User Exists2": {
"main": [
[
{
"node": "Check User Exists1",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Read": {
"main": [
[
{
"node": "Check User Exists2",
"type": "main",
"index": 0
}
]
]
},
"Send Email (Demo)1": {
"main": [
[
{
"node": "Success Response (Demo)1",
"type": "main",
"index": 0
}
]
]
},
"Update User Count1": {
"main": [
[
{
"node": "Send Email (Demo)1",
"type": "main",
"index": 0
},
{
"node": "Telegram Notification1",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
googleSheetsOAuth2ApisendGridApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
A complete email campaign automation system featuring dual-mode access control (Demo/Pro), usage tracking, and professional email delivery. Perfect for SaaS products, marketing agencies, or anyone building newsletter tools with freemium models.
Source: https://n8n.io/workflows/11759/ — 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, httpRequest, googleSheets. Webhook trigger; 54 nodes.
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
AI Document Processor - Intelligent Data Extraction. Uses httpRequest, readPDF, googleSheets, slack. Webhook trigger; 20 nodes.
Stop sending sensitive agency drafts as permanent email attachments. This workflow creates a "self-destructing" delivery system that hosts files via UploadToURL, sends branded previews via SendGrid, a
Invoice_Workflow. Uses googleSheets, googleDrive, googleDocs, gmail. Webhook trigger; 19 nodes.