This workflow follows the Gmail → Google Sheets 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": "email-sender",
"nodes": [
{
"parameters": {
"batchSize": "=1",
"options": {}
},
"id": "45018fbc-0787-42d5-be30-b0f2a6a66ed8",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1024,
192
],
"typeVersion": 3
},
{
"parameters": {
"maxItems": 10
},
"id": "aaf70090-324a-43a7-8450-553f650c608f",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
800,
192
],
"typeVersion": 1
},
{
"parameters": {
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8dc5b028-6f5d-4d76-8852-99180bfb4591",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json['Email Address '] }}",
"rightValue": ""
}
]
},
"options": {}
},
"id": "97cc9d26-00eb-4335-9f0b-58e64a9bbcf8",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
1248,
112
],
"typeVersion": 2.2
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk",
"mode": "list",
"cachedResultName": "customer-base",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Email Address ": "={{ $('Get Emails').item.json['Email Address '] }}",
"row_number": 0,
"Interaction Count": "={{ $('Increment Interaction Count').item.json.newCount }}",
"Last Interaction": "={{ $json.executionDate }}",
"Last Sent Template ID": "={{ $('Get Template to Send').item.json.template_id }}"
},
"matchingColumns": [
"Email Address "
],
"schema": [
{
"id": "Name",
"displayName": "Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Email Address ",
"displayName": "Email Address ",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Sender Email",
"displayName": "Sender Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Interaction Count",
"displayName": "Interaction Count",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Last Interaction",
"displayName": "Last Interaction",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Last Sent Template ID",
"displayName": "Last Sent Template ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Got Return?",
"displayName": "Got Return?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "TODAY",
"displayName": "TODAY",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "DAYS PASSED",
"displayName": "DAYS PASSED",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "row_number",
"displayName": "row_number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"readOnly": true,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"id": "04b2b9a5-707f-4acf-bfd9-5cff3f99ea61",
"name": "Update Records",
"type": "n8n-nodes-base.googleSheets",
"position": [
3008,
112
],
"typeVersion": 4.6,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"sendTo": "={{ $('Get Emails').item.json['Email Address '] }}",
"subject": "={{ $('Get Template to Send').item.json.email_subject }}",
"message": "={{ $('Replace Variables and Generate Signatured Body').item.json.fullBody }}",
"options": {
"appendAttribution": false,
"bccList": "={{ $json.BCC }}",
"ccList": "={{ $json.CC }}"
}
},
"id": "d17ec6b5-8c38-48db-91a9-7a5c818bf743",
"name": "Send Email",
"type": "n8n-nodes-base.gmail",
"position": [
2336,
112
],
"typeVersion": 2.1,
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk",
"mode": "list",
"cachedResultName": "customer-base",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit#gid=0"
},
"filtersUI": {
"values": [
{
"lookupColumn": "Got Return?",
"lookupValue": "NO"
},
{
"lookupColumn": "DAYS PASSED",
"lookupValue": "={{ $('Get Settings').item.json.auto_sending_day_interval }}"
}
]
},
"options": {}
},
"id": "5c8f731e-6000-47fa-b763-763d16def6e2",
"name": "Get Emails",
"type": "n8n-nodes-base.googleSheets",
"position": [
576,
192
],
"typeVersion": 4.5,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {},
"id": "89f2d6bd-87b2-4589-8329-8512627bb232",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
3232,
192
],
"typeVersion": 1.1
},
{
"parameters": {
"jsCode": "// \"Get Emails\" node'undaki Interaction Count de\u011ferini al\nlet interactionCount = $('Get Emails').item.json['Interaction Count'];\n\n// Say\u0131ya d\u00f6n\u00fc\u015ft\u00fcr\ninteractionCount = parseInt(interactionCount, 10);\n\n// E\u011fer ge\u00e7erli bir say\u0131 de\u011filse 0 yap\nif (isNaN(interactionCount)) {\n interactionCount = 0;\n}\n\nlet templateId = 0;\n\n// Switch\u2013case yap\u0131s\u0131\nswitch (true) {\n case (interactionCount === 0):\n templateId = 1;\n break;\n case (interactionCount === 1):\n templateId = 2;\n break;\n case (interactionCount === 2):\n templateId = 3;\n break;\n case (interactionCount > 2):\n templateId = 4;\n break;\n default:\n templateId = 1;\n}\n\nreturn [\n {\n json: {\n interactionCount,\n templateId\n }\n }\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1472,
112
],
"id": "5dc74ff4-8bc3-4973-beed-1d189454c52d",
"name": "Select Template by Interaction Count"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk",
"mode": "list",
"cachedResultName": "customer-base",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 1164818231,
"mode": "list",
"cachedResultName": "templates",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit#gid=1164818231"
},
"filtersUI": {
"values": [
{
"lookupColumn": "template_id",
"lookupValue": "={{ $json.templateId }}"
}
]
},
"options": {}
},
"id": "4a842f87-0b82-4bf6-b403-f1e911dec9c1",
"name": "Get Template to Send",
"type": "n8n-nodes-base.googleSheets",
"position": [
1696,
112
],
"typeVersion": 4.5,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// \u015eu anki tarih ve saati al (execution zaman\u0131)\nconst now = new Date();\n\n// Ay, g\u00fcn ve y\u0131l\u0131 al\nconst month = String(now.getMonth() + 1).padStart(2, '0'); // getMonth() 0-11 d\u00f6ner\nconst day = String(now.getDate()).padStart(2, '0');\nconst year = now.getFullYear();\n\n// \u0130stedi\u011fin formata d\u00f6n\u00fc\u015ft\u00fcr\nconst formattedDate = `${month}/${day}/${year}`;\n\nreturn [\n {\n json: {\n executionDate: formattedDate\n }\n }\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2784,
112
],
"id": "d2167af1-0487-481e-a19e-f76a764b2c52",
"name": "Get Execution Date"
},
{
"parameters": {
"jsCode": "// \"Get Emails\" node'undan Interaction Count de\u011ferini al\nconst interactionCount = $('Get Emails').item.json['Interaction Count'] || 0;\n\n// +1 art\u0131r\nconst newCount = interactionCount + 1;\n\n// Yeni de\u011feri d\u00f6nd\u00fcr\nreturn [\n {\n json: {\n oldCount: interactionCount,\n newCount\n }\n }\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2560,
112
],
"id": "dd814fd1-8a11-4ddf-aae6-0850a6d6a7b2",
"name": "Increment Interaction Count"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk",
"mode": "list",
"cachedResultName": "customer-base",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 17128778,
"mode": "list",
"cachedResultName": "settings",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1H8SuYExdx9eGFWRwrIpEXKQGCScKghq-ttLeSkSssYk/edit#gid=17128778"
},
"options": {}
},
"id": "1911ebfa-b77c-4cad-b161-058f84cd70a8",
"name": "Get Settings",
"type": "n8n-nodes-base.googleSheets",
"position": [
112,
208
],
"typeVersion": 4.5,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "7a36baa7-f3ea-4964-8340-80510248fa2c",
"leftValue": "={{ $json.is_auto_mailing_active }}",
"rightValue": "YES",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
320,
208
],
"id": "eb72264c-2dbd-4fae-bc85-5d2d75cc12ee",
"name": "If1"
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 3
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-80,
208
],
"id": "90cd264c-d073-4533-a80a-7e3870e46161",
"name": "Schedule Trigger"
},
{
"parameters": {
"jsCode": "// De\u011ferleri bir \u00f6nceki node'dan al (\u00f6rnek node ad\u0131: \"Get Data\")\nconst name = $('Get Emails').first().json.Name || \"\";\n\n// Mail g\u00f6vdesi (\u00f6rnek)\nlet mailBody = $input.first().json.email_body;\n\n// \u0130mza (\u00f6rnek)\nlet signature = $input.first().json.email_signature;\n\n// De\u011fi\u015fkenleri mailBody'de de\u011fi\u015ftir\nmailBody = mailBody\n .replace(/{{name}}/g, name);\n\n// G\u00f6vde ve imzay\u0131 alt alta birle\u015ftir\nconst fullBody = `${mailBody}\\n\\n${signature}`;\n\nreturn [\n {\n json: {\n name,\n fullBody\n }\n }\n];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1904,
112
],
"id": "7ee20c14-63c8-43b0-b818-78ab9c92dfc1",
"name": "Replace Variables and Generate Signatured Body"
},
{
"parameters": {
"jsCode": "// \"Get Settings\" node'undan al\nconst CC_raw = $('Get Settings').first().json.CC;\nconst BCC_raw = $('Get Settings').first().json.BCC;\n\nfunction toCommaString(input) {\n let arr = [];\n\n // 1) Dizi ise direkt kullan\n if (Array.isArray(input)) {\n arr = input;\n } else if (typeof input === 'string') {\n const s = input.trim();\n\n // 2) Stringle\u015ftirilmi\u015f JSON dizi mi? => parse et\n if ((s.startsWith('[') && s.endsWith(']')) || (s.startsWith('[\"') && s.endsWith('\"]'))) {\n try {\n const parsed = JSON.parse(s);\n if (Array.isArray(parsed)) arr = parsed;\n else arr = [s];\n } catch {\n // JSON parse ba\u015far\u0131s\u0131zsa CSV gibi b\u00f6l\n arr = s.split(/[,\\s;]+/);\n }\n } else {\n // 3) Normal CSV / bo\u015fluk / ; ile b\u00f6l\n arr = s.split(/[,\\s;]+/);\n }\n } else if (input == null) {\n arr = [];\n } else {\n arr = [String(input)];\n }\n\n // 4) Her bir girdiden email'i \u00e7\u0131kar (Name <mail@host> format\u0131n\u0131 da destekler)\n const emails = arr\n .map(v => String(v).trim())\n .map(v => {\n // <mail@host> varsa i\u00e7ini al\n const mAngle = v.match(/<([^>]+)>/);\n if (mAngle) return mAngle[1].trim();\n return v.replace(/^\"+|\"+$/g, ''); // \u00e7evredeki \u00e7ift t\u0131rnaklar\u0131 temizle\n })\n // basit e-posta regex do\u011frulamas\u0131\n .map(v => {\n const m = v.match(/([A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,})/i);\n return m ? m[1] : '';\n })\n .filter(Boolean);\n\n // 5) Tekrars\u0131zla\u015ft\u0131r + virg\u00fcl ile ve BO\u015eLUKSUZ birle\u015ftir\n const unique = Array.from(new Set(emails));\n return unique.join(',');\n}\n\nconst CC = toCommaString(CC_raw);\nconst BCC = toCommaString(BCC_raw);\n\nreturn [{ json: { CC, BCC } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2112,
112
],
"id": "798419f7-7d70-4aca-87d2-a75b76034479",
"name": "Include CC and BCC Emails"
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Select Template by Interaction Count",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Get Emails": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Send Email": {
"main": [
[
{
"node": "Increment Interaction Count",
"type": "main",
"index": 0
}
]
]
},
"Update Records": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Select Template by Interaction Count": {
"main": [
[
{
"node": "Get Template to Send",
"type": "main",
"index": 0
}
]
]
},
"Get Template to Send": {
"main": [
[
{
"node": "Replace Variables and Generate Signatured Body",
"type": "main",
"index": 0
}
]
]
},
"Get Execution Date": {
"main": [
[
{
"node": "Update Records",
"type": "main",
"index": 0
}
]
]
},
"Increment Interaction Count": {
"main": [
[
{
"node": "Get Execution Date",
"type": "main",
"index": 0
}
]
]
},
"Get Settings": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"If1": {
"main": [
[
{
"node": "Get Emails",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get Settings",
"type": "main",
"index": 0
}
]
]
},
"Replace Variables and Generate Signatured Body": {
"main": [
[
{
"node": "Include CC and BCC Emails",
"type": "main",
"index": 0
}
]
]
},
"Include CC and BCC Emails": {
"main": [
[
{
"node": "Send Email",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "9e15b45b-b47d-41db-b4b7-6f0b7666a650",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "ftK17Jgq1TS5yzI8",
"tags": []
}
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.
gmailOAuth2googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
email-sender. Uses googleSheets, gmail. Scheduled trigger; 16 nodes.
Source: https://github.com/octaworksofficial/n8n/blob/20a248338297da94c67a12b0db3035f88d91a82f/TEYMUR/email-sender.json — 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.
YOUR_ID 4. Uses gmail, googleDrive, googleSheets, httpRequest. Scheduled trigger; 53 nodes.
Looking for a way to track GitHub bounty issues automatically and get notified in real time? This GitHub Bounty Tracker workflow monitors repositories for issues labeled 💎 Bounty, logs them in Google
This workflow automatically sends a beautifully designed HTML newsletter every Sunday at 8 AM, featuring products currently on sale from your Algolia-powered e-commerce store.
This n8n template demonstrates how to build a Auto Lead Gen & Outreach System for Local Businesses specifically designed to help businesses that don’t have a website yet.
The workflow is triggered automatically every day at 12:00 PM using a Cron node.