This workflow corresponds to n8n.io template #12982 — we link there as the canonical source.
This workflow follows the Emailsend → 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "8e00238e-9ea1-44f0-bd3d-f79061e5ddef",
"name": "Start email automation",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
8944,
3168
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
6
],
"triggerAtHour": 15
}
]
}
},
"typeVersion": 1.3
},
{
"id": "94c954b2-a74c-4e81-8de6-9f36fe1d9e04",
"name": "Fetch contacts from Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
9200,
3168
],
"parameters": {
"range": "leads!A:Z",
"options": {},
"sheetId": "1x2gLnN8gbhG6upC76dL17K1e-XfK4wUPjeS3xg8Wdgk"
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "fbbb05af-2dc0-4bf4-a181-d4fcd018e5d6",
"name": "Process contacts one by one",
"type": "n8n-nodes-base.splitInBatches",
"position": [
9520,
3040
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "58aa8ad1-0d63-4f12-9532-29ae1efbb983",
"name": "Check no-show status",
"type": "n8n-nodes-base.if",
"position": [
10016,
3120
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json['Showed Up'] }}",
"value2": "No-Show"
}
]
}
},
"typeVersion": 1
},
{
"id": "43042d6e-0bd2-477e-bbb8-9b083e2543a0",
"name": "Check if email already sent",
"type": "n8n-nodes-base.if",
"position": [
10416,
3104
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0b59b8ba-61e6-41fb-860f-d1e8d955ef39",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ ($json.Mail || \"0\").toString().trim() }}",
"rightValue": "=0"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "726f7ba5-c24d-414c-9832-f99e375ad4d2",
"name": "Prepare email content",
"type": "n8n-nodes-base.set",
"position": [
10864,
3072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6163df91-a487-47bf-9b13-036f32d288f3",
"name": "Subject",
"type": "string",
"value": "={{ ($json.Subject_1 || '').replace(/\\{\\{\\s*name\\s*\\}\\}/gi, $json.name || 'there') }}"
},
{
"id": "b137e3b0-7cfd-4ca6-b951-fa3143b9c907",
"name": "Body",
"type": "string",
"value": "={{ ($json.Body_1 || '').replace(/\\{\\{\\s*name\\s*\\}\\}/gi, $json.name || 'there') }}"
},
{
"id": "0b47820f-2e71-4157-868a-92cbafe34102",
"name": "Email",
"type": "string",
"value": "={{ $json.Email }}"
},
{
"id": "fbb458d0-c9db-457d-9011-ea57d9cb3c31",
"name": "name",
"type": "string",
"value": "={{ $json.name }}"
}
]
}
},
"typeVersion": 3.4,
"alwaysOutputData": false
},
{
"id": "6b5bb72f-c6f7-42d8-9451-72151a72e614",
"name": "Send email via SMTP",
"type": "n8n-nodes-base.emailSend",
"position": [
11232,
3008
],
"parameters": {
"html": "={{\n 'Hey ' + $json.name + ',<br><br>' +\n\n 'You didn\u2019t attend the last workshop....everything okay at your home?<br><br>' +\n\n 'I genuinely hope all is well. I was looking forward to helping you move closer to your career goals, so I wanted to check in personally.<br><br>' +\n\n 'I\u2019m planning another live session, and I\u2019d love to have you join this time so you don\u2019t miss the important steps.<br><br>' +\n\n '\ud83d\udc49 Would you like me to reserve a seat for you in the next session?<br>' +\n 'Just reply <b>Yes</b> and I\u2019ll share the details.<br><br>' +\n\n 'And if anything held you back earlier, feel free to share - I\u2019m here to support you.<br><br>' +\n\n 'Let\u2019s go win together \ud83d\udcaa<br><br>' +\n\n 'Warm regards,<br>' +\n '<b>Lakshit Bhayana</b><br><br>' +\n\n '<b>Connect with me:</b><br>' +\n '<a href=https://www.instagram.com/lakshitbhayana?igsh=MTA3bnR3ZXg3M2ZhOQ==\">Instagram</a> | ' +\n '<a href=\"https://www.youtube.com/@Lakshit-Bhayana\">YouTube</a> | ' +\n '<a href=\"https://www.linkedin.com/in/lakshit-bhayana?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=ios_app\">LinkedIn</a> | '\n}}",
"options": {
"appendAttribution": false
},
"subject": "={{ 'Hi ' + $json.name + ', quick follow-up after the workshop' }}",
"toEmail": "={{ $json.Email }}",
"fromEmail": "Shivam Gandhi <user@example.com>"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "4b1d4d9c-c1a2-4269-9a6f-eef37b8a33ee",
"name": "Delay between emails",
"type": "n8n-nodes-base.wait",
"position": [
11504,
3104
],
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "c837bd44-9742-4ebf-83b0-a70b61ecb11c",
"name": "Mark email as sent in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
11856,
3296
],
"parameters": {
"columns": {
"value": {
"Mail": "1",
"Email": "={{ $('Fetch contacts from Google Sheets').item.json.Email }}"
},
"schema": [
{
"id": "Sr. No.",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Sr. No.",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Phone number",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Phone number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Registration Date",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Registration Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Showed Up",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Showed Up",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Mail",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Mail",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Job Title",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Job Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "CTC",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "CTC",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "CITY",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "CITY",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Join Group",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Join Group",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Payment",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Payment",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Source with",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Source with",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Conversation Owner",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Conversation Owner",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Source",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Source",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Campaign",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Campaign",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Medium",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Medium",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Content",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Content",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Term",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Term",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Assign for call booking",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Assign for call booking",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status of leads",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Status of leads",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subject_1",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Subject_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Body_1",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Body_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subject_2",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Subject_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Body_2",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Body_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subject_1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Subject_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Body_1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Body_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subject_2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Subject_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Body_2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Body_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"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": 641246547,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1x2gLnN8gbhG6upC76dL17K1e-XfK4wUPjeS3xg8Wdgk/edit#gid=641246547",
"cachedResultName": "Paid Workshop-registeration"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1x2gLnN8gbhG6upC76dL17K1e-XfK4wUPjeS3xg8Wdgk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1x2gLnN8gbhG6upC76dL17K1e-XfK4wUPjeS3xg8Wdgk/edit?usp=drivesdk",
"cachedResultName": "Data Management CRM"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "bf02a25c-b987-4ebb-a4f4-0a10e559d491",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
10800,
3520
],
"parameters": {
"color": 4,
"width": 512,
"height": 224,
"content": "## What to test before running the campaign\n\n\u2705 Send 2\u20133 test emails to your own email address\n\u2705 Verify personalization works (Name is replaced correctly)\n\u2705 Check that emails do not land in the spam folder\n\u2705 Confirm the Google Sheet updates Email Sent = Yes after sending\n\u2705 Run the workflow again to ensure already-sent contacts are skipped\n\u2705 Verify email formatting (line breaks, links, signatures)\n\u2705 Test with an empty Name field (use a generic greeting like \u201cHi there\u201d)"
},
"typeVersion": 1
},
{
"id": "37701129-7824-4a7f-b2fc-0084022a8b16",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
8848,
2512
],
"parameters": {
"width": 720,
"height": 464,
"content": "## Email outreach setup\n\n## How it works\n- Reads contacts from Google Sheets\n- Filters contacts based on no-show or custom status\n- Skips contacts already emailed\n- Sends personalized emails via SMTP\n- Updates the sheet after sending\n\n## Setup steps\n- Connect Google Sheets and SMTP credentials\n- Prepare a sheet with Email, Name, Status, Email Sent columns\n- Test the workflow\n- Activate the schedule trigger"
},
"typeVersion": 1
},
{
"id": "1e7db455-7f1d-4922-8925-59aeb5ef5e85",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
12080,
3088
],
"parameters": {
"color": 2,
"width": 528,
"height": 464,
"content": "## \ud83d\udeab SMTP provider requirements (important)\n\nSome consumer email providers restrict or block SMTP usage for automated workflows.\n\n## \u2705 Recommended SMTP providers\n\nThese services are designed for automated and transactional emails:\n\t\u2022\tSendGrid (free tier available)\n\t\u2022\tWebmail\n\t\u2022\tCustom domain SMTP (cPanel / Plesk hosting)\n\n## \u26a0\ufe0f Not recommended for automation\n\nThese providers may fail or block automated SMTP usage:\n\t\u2022\tGmail SMTP\n\t\u2022\tYahoo SMTP\n\t\u2022\tOutlook / Hotmail SMTP\n"
},
"typeVersion": 1
},
{
"id": "00ea7c80-4790-4b39-86a5-2407c3d4be88",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
9088,
3056
],
"parameters": {
"color": 7,
"width": 336,
"height": 128,
"content": "Fetches contacts from Google Sheets.\nEnsure column names match\nthe workflow configuration."
},
"typeVersion": 1
},
{
"id": "974e7435-45f5-4ac5-a2b7-2b4e12e13d61",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
10096,
3008
],
"parameters": {
"color": 7,
"width": 336,
"height": 112,
"content": "Filters contacts based on\nno-show or custom status\nand skips already emailed leads."
},
"typeVersion": 1
},
{
"id": "597ffb53-335d-4e91-8c56-d1bb6da9bd14",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
10912,
2944
],
"parameters": {
"color": 7,
"width": 336,
"height": 96,
"content": "Prepares personalized email\ncontent and sends emails\nusing an SMTP provider."
},
"typeVersion": 1
},
{
"id": "4cebbe82-58a6-4752-9317-2482dc81ec96",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
11680,
3104
],
"parameters": {
"color": 7,
"width": 336,
"height": 96,
"content": "Adds a delay between emails\nand updates Google Sheets\nto prevent duplicate sends."
},
"typeVersion": 1
},
{
"id": "7a53220a-a2f5-4af1-8729-f1c54f939d19",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
9600,
3536
],
"parameters": {
"color": 3,
"width": 544,
"height": 192,
"content": "## Common first-time issues\n\n\u274c No emails sent \u2192 Check SMTP credentials and From Email address\n\u274c Sheet not updating \u2192 Confirm the Mark email as sent in sheet node points to the correct spreadsheet and tab\n\u274c Workflow keeps looping \u2192 Ensure Process contacts one by one batch size is set to 1\n"
},
"typeVersion": 1
}
],
"connections": {
"Send email via SMTP": {
"main": [
[
{
"node": "Delay between emails",
"type": "main",
"index": 0
}
]
]
},
"Check no-show status": {
"main": [
[
{
"node": "Check if email already sent",
"type": "main",
"index": 0
}
],
[
{
"node": "Process contacts one by one",
"type": "main",
"index": 0
}
]
]
},
"Delay between emails": {
"main": [
[
{
"node": "Mark email as sent in sheet",
"type": "main",
"index": 0
}
]
]
},
"Prepare email content": {
"main": [
[
{
"node": "Send email via SMTP",
"type": "main",
"index": 0
}
]
]
},
"Start email automation": {
"main": [
[
{
"node": "Fetch contacts from Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Check if email already sent": {
"main": [
[
{
"node": "Prepare email content",
"type": "main",
"index": 0
}
],
[
{
"node": "Process contacts one by one",
"type": "main",
"index": 0
}
]
]
},
"Mark email as sent in sheet": {
"main": [
[
{
"node": "Process contacts one by one",
"type": "main",
"index": 0
}
]
]
},
"Process contacts one by one": {
"main": [
[],
[
{
"node": "Check no-show status",
"type": "main",
"index": 0
}
]
]
},
"Fetch contacts from Google Sheets": {
"main": [
[
{
"node": "Process contacts one by one",
"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.
googleSheetsOAuth2Apismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates sending personalized emails using a contact list stored in Google Sheets and a professional SMTP email account.
Source: https://n8n.io/workflows/12982/ — 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.
Security teams, DevOps engineers, vulnerability analysts, and automation builders who want to eliminate repetitive Nessus scan parsing, AI-based risk triage, and manual reporting. Designed for orgs fo
This workflow fully automates the reconciliation process between your Local Database transactions and Payment Gateway transactions. It compares both data sources, identifies mismatches, categorizes di
This n8n workflow automatically finds apartments for rent in Germany, filters them by your city, rent budget, and number of rooms, and applies to them via email. Each application includes: A personali
👤 Who it’s for Blue Team leads, CISOs, and SOC managers who want automated visibility into threat metrics, endpoint alerts, and response actions — without needing a full SIEM or BI platform.
Workflow Overview Zoom Attendance Evaluator with Follow-up is an n8n automation workflow that automatically evaluates Zoom meeting attendance and sends follow-up emails to no-shows and early leavers w