This workflow follows the Gmail → Telegram 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 →
{
"name": "OTP Generator",
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "0317bc72-dd3e-4387-982c-9fae227d2193",
"name": "otp",
"value": "={{ Math.floor(1000 + Math.random() * 9000) }}",
"type": "number"
},
{
"id": "f721a705-349b-4395-96c3-a2775e6bf08c",
"name": "user",
"value": "={{ $json.message.from.id }}",
"type": "string"
},
{
"id": "6cb94d01-0e89-41b4-9832-55ed9558dcec",
"name": "phone",
"value": "={{ $json.message.text }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
580,
360
],
"id": "e2099438-bc55-4377-b105-b2cf9fe3d4a9",
"name": "Phone OTP"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "ca34a7ef-6256-4ca1-bdea-5e17c22aa90e",
"name": "otp",
"value": "={{ [...Array(8)].map(() => String.fromCharCode(65 + Math.floor(Math.random()*26))).join('') }}",
"type": "string"
},
{
"id": "4855a64a-e1ea-43bf-8199-ad96ceb673e5",
"name": "user",
"value": "={{ $json.message.from.id }}",
"type": "string"
},
{
"id": "26590413-913b-4583-8ba9-a1eca44ecc1b",
"name": "email",
"value": "={{ $json.message.text }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
400,
-660
],
"id": "2a570afa-3833-4524-9e27-deb3a664e9b4",
"name": "Email OTP"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "a6923f53-4346-4b4b-a739-7027d6484506",
"leftValue": "={{ $json.message.text }}",
"rightValue": "123",
"operator": {
"type": "string",
"operation": "notStartsWith"
}
},
{
"id": "4e25f4f4-0274-4e96-a87c-91a7443d4bea",
"leftValue": "={{ $json.message.text }}",
"rightValue": "+123",
"operator": {
"type": "string",
"operation": "notStartsWith"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
320,
360
],
"id": "b37417ea-d519-4cd8-8f41-61175c99e1bb",
"name": "Skip specific numbers"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "8c7e91c2-450c-48c6-942d-49b12cdba2d1",
"leftValue": "={{ $json.message.text }}",
"rightValue": "^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$",
"operator": {
"type": "string",
"operation": "regex"
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.message.text }}",
"rightValue": "^\\+?[1-9]\\d{7,14}$",
"operator": {
"type": "string",
"operation": "regex"
},
"id": "f2da7ed3-6438-4fa2-b201-d28fdc307ac9"
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
100,
60
],
"id": "bf1bcd5a-43f0-45b1-b7c5-7e908f6e1510",
"name": "Phone or Email"
},
{
"parameters": {
"sendTo": "={{ $json.email }}",
"subject": "OTP",
"message": "=Hi\n\nHere\u2019s your single-use code:\n\n<h2 style=\"margin:0;font-size:28px;letter-spacing:4px;\">{{ $json.otp }}</h2>\nThis code is valid for the next 10 minutes.\nPlease do not share it with anyone\u2014our team will never ask for it.\n\nIf you didn\u2019t request this code, you can safely ignore this email.\n\nThanks for keeping your account secure!\nThe Bobr team",
"options": {
"appendAttribution": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
900,
-660
],
"id": "a8fce791-5838-4530-8e6b-2c6fa181d3e5",
"name": "Send email"
},
{
"parameters": {
"operation": "push",
"list": "={{ $json.user + '' }}",
"messageData": "={{ $json.otp + '' }}"
},
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
960,
-140
],
"id": "6237a77c-f155-436e-a134-d79b93687869",
"name": "Save OTP to cache"
},
{
"parameters": {
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-420,
60
],
"id": "f5811b09-59cd-4855-bfe2-8f4b5473823e",
"name": "On TG message received"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "dee61407-9a45-4d09-9dee-22f07e464e97",
"leftValue": "={{ $json.message.chat.id }}",
"rightValue": 10101010101,
"operator": {
"type": "number",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
-160,
60
],
"id": "d202cc40-01da-4cf8-b6ff-d6b2b6f74a85",
"name": "Allow only specific chat"
},
{
"parameters": {
"resource": "call",
"from": "+000000000",
"to": "={{ $json.phone }}",
"message": "=Your one time password is: {{ $json.otp }}",
"options": {}
},
"type": "n8n-nodes-base.twilio",
"typeVersion": 1,
"position": [
1160,
360
],
"id": "3690b1ad-8ed2-47e3-9376-ba45bf7e3774",
"name": "Make call",
"retryOnFail": false,
"onError": "continueRegularOutput"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.error }}",
"rightValue": "Bad request - please check your parameters",
"operator": {
"type": "string",
"operation": "equals"
},
"id": "97193168-0b48-42ad-9d71-d3b94062814e"
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "288e2c61-179c-4332-8016-321498820f8b",
"leftValue": "={{ $json.error }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "notExists",
"singleValue": true
}
}
],
"combinator": "and"
}
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "2fc605c6-6ee2-4730-ad2e-1689bcb3cb4f",
"leftValue": "={{ $json.error }}",
"rightValue": "Something went wrong...",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
1520,
380
],
"id": "401343ef-967b-4467-9319-0715804e650c",
"name": "Switch"
},
{
"parameters": {
"tableId": "success_log",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "user",
"fieldValue": "={{ $('On TG message received').item.json.message.from.username }}"
},
{
"fieldId": "json",
"fieldValue": "={\n \"userMessage\": \"{{ $node['On TG message received'].json.message.text }}\",\n \"emailOtp\": \"{{ $('Email OTP')?.item.json.otp }}\",\n \"phoneOtp\": \"{{ $('Phone OTP').item.json.otp }}\"\n}"
}
]
}
},
"type": "n8n-nodes-base.supabase",
"typeVersion": 1,
"position": [
2160,
-660
],
"id": "b56b1e41-948f-4bb8-a529-815d93abec94",
"name": "Log success"
},
{
"parameters": {
"errorMessage": "=user: {{ $('On TG message received').item.json.message.from.username }}\nerror: {{ $json.error }}"
},
"type": "n8n-nodes-base.stopAndError",
"typeVersion": 1,
"position": [
1880,
240
],
"id": "2ef5c796-915b-47c2-b73c-84cda2b636f1",
"name": "Twilio Non-Retriable Error"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "af80ceb5-4490-4982-86a0-5093d0048cc5",
"leftValue": "={{ $('Make call').item.json.error }}",
"rightValue": "Bad request - please check your parameters",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
},
{
"id": "ff808d00-f61c-4c78-80a7-0ebd8c6c1426",
"leftValue": "={{ Number($('Merge').item.json.attempt ?? 1) }}",
"rightValue": 3,
"operator": {
"type": "number",
"operation": "lt"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1880,
400
],
"id": "ee4f49ff-52a4-450d-a60a-3428618a4b44",
"name": "If"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "22397f68-90bc-41c1-8dc8-4d97b46affdb",
"name": "attempt",
"value": "={{ Number($('Merge').item.json.attempt ?? 0) + 1 }}",
"type": "number"
}
]
},
"includeOtherFields": true,
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2440,
680
],
"id": "bf47f006-4d33-4f80-bb17-2ecbe0cb4c8b",
"name": "Increase Attempts"
},
{
"parameters": {
"amount": 10
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
2160,
680
],
"id": "1ef8ed83-5220-4cc9-ba9b-6d31483dd103",
"name": "Wait"
},
{
"parameters": {},
"type": "n8n-nodes-base.merge",
"typeVersion": 3.1,
"position": [
880,
360
],
"id": "67671214-9fdd-4249-8b9a-4aa0fd422d8d",
"name": "Merge"
},
{
"parameters": {
"from": "+00000000000",
"to": "+00000000001",
"message": "test",
"options": {}
},
"type": "n8n-nodes-base.sms77",
"typeVersion": 1,
"position": [
2160,
420
],
"id": "4c534120-17a1-4fa6-aad2-e90aeec51b49",
"name": "seven"
}
],
"connections": {
"Phone OTP": {
"main": [
[
{
"node": "Save OTP to cache",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Email OTP": {
"main": [
[
{
"node": "Send email",
"type": "main",
"index": 0
},
{
"node": "Save OTP to cache",
"type": "main",
"index": 0
}
]
]
},
"Skip specific numbers": {
"main": [
[
{
"node": "Phone OTP",
"type": "main",
"index": 0
}
]
]
},
"Phone or Email": {
"main": [
[
{
"node": "Email OTP",
"type": "main",
"index": 0
}
],
[
{
"node": "Skip specific numbers",
"type": "main",
"index": 0
}
]
]
},
"On TG message received": {
"main": [
[
{
"node": "Allow only specific chat",
"type": "main",
"index": 0
}
]
]
},
"Allow only specific chat": {
"main": [
[
{
"node": "Phone or Email",
"type": "main",
"index": 0
}
]
]
},
"Make call": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
],
[
{
"node": "Log success",
"type": "main",
"index": 0
}
],
[
{
"node": "Twilio Non-Retriable Error",
"type": "main",
"index": 0
}
]
]
},
"Send email": {
"main": [
[
{
"node": "Log success",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
],
[
{
"node": "seven",
"type": "main",
"index": 0
}
]
]
},
"Increase Attempts": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Increase Attempts",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Make call",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": ""
},
"versionId": "",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "FFfivEbOtaxzdQ79",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
OTP Generator. Uses gmail, redis, telegramTrigger, twilio. Event-driven trigger; 17 nodes.
Source: https://gist.github.com/dmytrotaranov12/dfec7efe4dc8b234db202202c7956f9b — 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.
Telegram Code. Uses stickyNote, telegramTrigger, telegram, googleDrive. Event-driven trigger; 37 nodes.
Memory sessions with FlowiseAI and Zep. Uses telegram, redis, telegramTrigger, httpRequest. Event-driven trigger; 37 nodes.
Categories: Payments, Project Operations, Client Onboarding
Instant enquiry/booking system. Uses telegramTrigger, googleSheets, telegram, gmail. Event-driven trigger; 28 nodes.
Construction and renovation businesses that need to generate detailed quotes from customer inquiries—plasterers, painters, contractors, renovation specialists, or any construction service provider han