This workflow corresponds to n8n.io template #7065 — 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": "3cc80b37-988e-4111-b9b4-8712a31fe400",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2320,
-16
],
"parameters": {
"rule": {
"interval": [
{
"field": "seconds"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "f93e671e-f82d-453c-a734-fb144af0c090",
"name": "contacts",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1872,
80
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1877973285,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1VPUd7xbigvW4dIjyvsSRn3Y3jpITjyZneCIEU0HK_Hw/edit#gid=1877973285",
"cachedResultName": "contacts"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.googlesheetid }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "bed36d9b-defc-46ce-a6cc-aa8efdddfcc4",
"name": "template",
"type": "n8n-nodes-base.googleDocs",
"position": [
-1760,
-96
],
"parameters": {
"operation": "get",
"documentURL": "={{ $json.googledocid }}"
},
"credentials": {
"googleDocsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 2
},
{
"id": "2fb0d6e9-2692-4c4d-b6a7-4d27ba467ef2",
"name": "updatebody",
"type": "n8n-nodes-base.set",
"position": [
-1184,
-16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e9ac9b39-f81e-4754-b978-bb8126c2c846",
"name": "email",
"type": "string",
"value": "={{ $json.email }}"
},
{
"id": "c9f391a2-4017-40f3-9222-cfd79135ecfd",
"name": "template",
"type": "string",
"value": "={{ $json.content\n.replaceAll(/\\{\\{ ?email ?\\}\\}/gm, $json[\"email\"])\n.replaceAll(/\\{\\{ ?company ?\\}\\}/gm, $json[\"company\"])\n.replaceAll(/\\{\\{ ?firstname ?\\}\\}/gm, $json[\"firstname\"])\n.replaceAll(/\\{\\{ ?lastname ?\\}\\}/gm, $json[\"lastname\"]); }}\n\n\n"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "4453d3d8-65d3-4b5c-8083-9c686be44678",
"name": "settings",
"type": "n8n-nodes-base.set",
"position": [
-2096,
-16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0cc310e3-f3bb-4347-9d4f-275c00f0f9ac",
"name": "emailsubject",
"type": "string",
"value": "Emailing Template - Email Subject"
},
{
"id": "c17d8bb6-c29f-48c6-830f-acd350617810",
"name": "googledocid",
"type": "string",
"value": "enter_your_googledocID_here"
},
{
"id": "4b74909d-6a40-422f-9d5a-1d72f5577f3f",
"name": "googlesheetid",
"type": "string",
"value": "enter_your_googlesheetID_here"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "806753db-3de0-41e2-b43b-aca9dc5f548c",
"name": "sendemail",
"type": "n8n-nodes-base.emailSend",
"notes": "OVHCloud",
"position": [
-720,
0
],
"parameters": {
"text": "={{ $json.template }}",
"options": {
"appendAttribution": false
},
"subject": "={{ $('settings').item.json.emailsubject }}",
"toEmail": "={{ $json.email }}",
"fromEmail": "myfirstname / mycompany<user@example.com>",
"emailFormat": "text"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"notesInFlow": true,
"typeVersion": 2.1
},
{
"id": "bd58504e-6a1e-46fd-b892-03853b0ab89b",
"name": "notemailed",
"type": "n8n-nodes-base.filter",
"position": [
-1648,
80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "4b68ad20-a8f8-4d5c-91fe-d4009455bcb3",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.process }}",
"rightValue": ""
},
{
"id": "fc31006b-9dbe-43a9-ae8a-5389b8379f34",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.err }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "fe137938-de01-4542-bbe1-7d605c4ca372",
"name": "updatecontacts",
"type": "n8n-nodes-base.googleSheets",
"notes": "row_number (using to match)\n{{ $('contacts').item.json.row_number }}\n\nprocess\n{{ $now.format('yyyy-MM-dd, hh:mm:ss a') }}",
"position": [
-496,
0
],
"parameters": {
"columns": {
"value": {
"process": "={{ $now.format('yyyy-MM-dd, hh:mm:ss a') }}",
"row_number": "={{ $('contacts').item.json.row_number }}"
},
"schema": [
{
"id": "email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "firstname",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "firstname",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lastname",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lastname",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "company",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "company",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "process",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "process",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "err",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "err",
"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": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "contacts"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('settings').item.json.googlesheetid }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "10b636a0-63b8-4215-956f-d66606ae51eb",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-960,
-16
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "c1a3e48d-3447-400f-a366-447fb126fb08",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
-272,
80
],
"parameters": {
"amount": 20
},
"typeVersion": 1.1
},
{
"id": "463a82ed-2515-4e29-98c8-a091ec62abdf",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
-736,
-208
],
"parameters": {},
"typeVersion": 1
},
{
"id": "bc87d9fe-f2d8-4488-b513-9d54d45b989f",
"name": "merge",
"type": "n8n-nodes-base.merge",
"position": [
-1424,
-16
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineAll"
},
"typeVersion": 3
},
{
"id": "706fec26-39d6-4517-849c-bd7ff52c735e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-304,
272
],
"parameters": {
"color": 7,
"width": 176,
"height": 188,
"content": "SMTP providers (like OVHcloud) have quota. \nEx: 200 emails / hour means you can send 3 emails per minute maximum. So, a Wait Amount of 20 seconds is suggested\n"
},
"typeVersion": 1
},
{
"id": "982f0c8d-1cf1-49bf-9a93-0076312c8747",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-528,
272
],
"parameters": {
"color": 7,
"width": 192,
"height": 188,
"content": "*row_number* is used for the matching and should contain {{ $('contacts').item.json.row_number }}\n\n*process* is set with {{ $now.format('yyyy-MM-dd, hh:mm:ss a') }}"
},
"typeVersion": 1
},
{
"id": "ed4175e8-5d53-4520-83dc-83f098b4678b",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-752,
272
],
"parameters": {
"color": 7,
"width": 192,
"height": 188,
"content": "Update with your own SMTP details and adapt the \"From Email\" field"
},
"typeVersion": 1
},
{
"id": "ac803816-b96d-4d3f-b5e9-ab90c0f6f361",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1232,
-96
],
"parameters": {
"color": 7,
"width": 208,
"height": 444,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nReplace Google Docs template\n{{firstname}}\n{{lastname}} {{company}}\n{{email}}\nwith real content from the Google Sheet\n\n"
},
"typeVersion": 1
},
{
"id": "1aa209a1-6e65-43e8-a8e3-bb5f539b6702",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1696,
208
],
"parameters": {
"color": 7,
"width": 192,
"height": 144,
"content": "We only select rows with *process* and *err* columns = empty"
},
"typeVersion": 1
},
{
"id": "6b7d9070-e448-437c-9ae0-e52b2a18dcd0",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1808,
-352
],
"parameters": {
"color": 7,
"width": 192,
"height": 412,
"content": "Your Google Docs template containing the message with the \n{{firstname}}\n{{lastname}} {{company}}\n{{email}}\nvariables\n\n[Google Docs Template](https://docs.google.com/document/d/1sR1Mjee0heur6CgEV_ssYzOUbFNaDnyEnPSt1CFEMWI/edit?usp=sharing)\n\n"
},
"typeVersion": 1
},
{
"id": "93ed8856-43da-447c-a85b-a24553468361",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2128,
160
],
"parameters": {
"color": 7,
"width": 192,
"height": 192,
"content": "Set the Subject of your emailing campaign, define the Google Docs & Sheet ID you want to use"
},
"typeVersion": 1
},
{
"id": "1213bc1e-1ce4-4ec0-af5e-53875f2684d9",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1920,
272
],
"parameters": {
"color": 7,
"width": 192,
"height": 80,
"content": "\n[Google Sheet Template](https://docs.google.com/spreadsheets/d/1mFKp3wmbV9qp2tpGGsN72zdiC32y8H1nhjdgP885y-U/edit?usp=sharing)\n\n"
},
"typeVersion": 1
},
{
"id": "87eddad8-8c0a-41a0-8f5d-1d2d323382ee",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2368,
400
],
"parameters": {
"color": 7,
"width": 1376,
"height": 288,
"content": "# Emailing using Google Sheet, Google Docs and SMTP\nThis is a simple system to automatise an emailing.\n\n## How it works\n\n- The Google Docs template is your email to be sent and contains the message and variables (firstname, lastname, company, email).\n- The Google Sheet is your list of contacts.\n- For each contact, we create the final email, we send it using SMTP protocol (with a Batch Size of 1) and we manage the SMTP quota.\n- The **process** column of the Google Sheet is updated with date/time after email is sent.\n\n\n## How to use\n1. Download the [Google Docs Template](https://docs.google.com/document/d/1sR1Mjee0heur6CgEV_ssYzOUbFNaDnyEnPSt1CFEMWI/edit?usp=sharing) and [Google Sheet Template](https://docs.google.com/spreadsheets/d/1mFKp3wmbV9qp2tpGGsN72zdiC32y8H1nhjdgP885y-U/edit?usp=sharing). Identify the ID of both documents in your own environment.\n - The ID is the `string` between d/ and /edit ... spreadsheets/d/`1mFKp3wmba1b2c3N72zdiC32y8H1nhjdgP85y-U`/edit?gid=1234\n\n2. Define the Subject of your emailing campaing and setup the Google Sheet & Docs ID in the `settings` node\n\n3. Configure your Google credentials and SMTP parameters\n\n4. Update both Google Docs & Sheet with your own message and list of contacts\n - The Google Docs template can contain the following variables `{{firstname}}` `{{lastname}}` `{{company}}` `{{email}}`\n - The header of the Google Sheet should contain the following columns **email**, **firstname**, **lastname**, **company**, **process**, **err**\n\n## Requirements\n- **Google credentials** to access your documents\n- **SMTP** server, up and running. Update the `Wait` node with what works for you\n- **n8n version** this workflow was tested on 1.105.2 (Ubuntu)\n\n## Need Help?\n\nContact me on [LinkedIn](https://www.linkedin.com/in/stephaneheckel/) or ask in the [Forum](https://community.n8n.io/)!\n\n\n"
},
"typeVersion": 1
}
],
"connections": {
"Wait": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"merge": {
"main": [
[
{
"node": "updatebody",
"type": "main",
"index": 0
}
]
]
},
"contacts": {
"main": [
[
{
"node": "notemailed",
"type": "main",
"index": 0
}
]
]
},
"settings": {
"main": [
[
{
"node": "template",
"type": "main",
"index": 0
},
{
"node": "contacts",
"type": "main",
"index": 0
}
]
]
},
"template": {
"main": [
[
{
"node": "merge",
"type": "main",
"index": 0
}
]
]
},
"sendemail": {
"main": [
[
{
"node": "updatecontacts",
"type": "main",
"index": 0
}
]
]
},
"notemailed": {
"main": [
[
{
"node": "merge",
"type": "main",
"index": 1
}
]
]
},
"updatebody": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"updatecontacts": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
],
[
{
"node": "sendemail",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "settings",
"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.
googleDocsOAuth2ApigoogleSheetsOAuth2Apismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automate personalized email campaigns using a Google Sheets contact list, a Google Docs template, and SMTP delivery. Google Docs is used as the email template with variables: , , , . Google Sheet contains your list of recipients (one per row). For each contact, the workflow…
Source: https://n8n.io/workflows/7065/ — 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.
Automatización de Email Marketing. Uses googleSheets, emailSend. Scheduled trigger; 4 nodes.
Workflow-Lead-Summary. Uses googleSheets, emailSend. Scheduled trigger; 3 nodes.
This workflow runs on scheduled weekly and monthly triggers to generate unified marketing performance reports. It processes multiple websites by collecting analytics data, paid ads performance, and CR
Goal: Get Reddit posts from specific subreddits, filter those mentioning freelance/gigs and n8n, extract top-level comments, remove mod replies, and store everything into Google Sheets.
This workflow is designed to manage the assignment and validation of unique QR code coupons within a lead generation system with SuiteCRM.