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.
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.
✨🔪 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
Code. Uses googleSheets, gmail, supabase, stickyNote. Webhook trigger; 51 nodes.