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": "Staff Scheduling Automation (Publish + Confirm)",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtHour": 23
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
0,
0
],
"id": "ecadba47-fa95-4503-971c-9449b95ce22c",
"name": "Sunday Auto-Publish"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc",
"mode": "list",
"cachedResultName": "Local biz autopilot ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 447491474,
"mode": "list",
"cachedResultName": "Weekly Schedule",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit#gid=447491474"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
208,
0
],
"id": "4076d14c-0653-44b8-a4e7-c8abeab8ce37",
"name": "Read Weekly Schedule",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fieldsToSummarize": {
"values": [
{
"aggregation": "concatenate",
"field": "Shift ID"
},
{
"aggregation": "concatenate",
"field": "Date"
},
{
"aggregation": "concatenate",
"field": "Shift Time"
},
{
"aggregation": "concatenate",
"field": "Role"
}
]
},
"fieldsToSplitBy": "Staff Email",
"options": {}
},
"type": "n8n-nodes-base.summarize",
"typeVersion": 1.1,
"position": [
416,
0
],
"id": "1df34905-5947-4187-89cc-678807029fad",
"name": "Summarize"
},
{
"parameters": {
"jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n const email = item.json['Staff_Email'];\n const shiftIds = item.json['concatenated_Shift_ID'].split(',');\n const dates = item.json['concatenated_Date'].split(',');\n const times = item.json['concatenated_Shift_Time'].split(',');\n const roles = item.json['concatenated_Role'].split(',');\n\n let tableRows = '';\n for (let i = 0; i < shiftIds.length; i++) {\n const dateObj = new Date(dates[i]);\n const formattedDate = isNaN(dateObj)\n ? dates[i]\n : dateObj.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });\n\n tableRows += `\n <tr>\n <td style=\"padding:8px 12px;border:1px solid #ddd;\">${formattedDate}</td>\n <td style=\"padding:8px 12px;border:1px solid #ddd;\">${times[i]}</td>\n <td style=\"padding:8px 12px;border:1px solid #ddd;\">${roles[i]}</td>\n <td style=\"padding:8px 12px;border:1px solid #ddd;color:#888;\">${shiftIds[i]}</td>\n </tr>`;\n }\n\n const scheduleTableHtml = `\n <table style=\"border-collapse:collapse;font-family:Arial,sans-serif;font-size:14px;width:100%;max-width:500px;\">\n <thead>\n <tr style=\"background-color:#1F2937;color:#ffffff;\">\n <th style=\"padding:8px 12px;border:1px solid #ddd;text-align:left;\">Date</th>\n <th style=\"padding:8px 12px;border:1px solid #ddd;text-align:left;\">Time</th>\n <th style=\"padding:8px 12px;border:1px solid #ddd;text-align:left;\">Role</th>\n <th style=\"padding:8px 12px;border:1px solid #ddd;text-align:left;\">Shift ID</th>\n </tr>\n </thead>\n <tbody>${tableRows}\n </tbody>\n </table>`;\n\n results.push({\n json: {\n staffEmail: email,\n scheduleTableHtml: scheduleTableHtml\n }\n });\n}\n\nreturn results;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
624,
0
],
"id": "f646d90f-fa2e-4f2e-9748-5875e9aa0c32",
"name": "Format Schedule Email"
},
{
"parameters": {
"sendTo": "={{ $json.staffEmail }}",
"subject": "Your Schedule for This Week",
"message": "=Hi,<br><br>\nHere's your schedule for this week:<br><br>\n{{ $json.scheduleTableHtml }}\n<br><br>\nPlease confirm your shifts by replying to this email or using the confirmation link (coming soon).<br><br>\nThanks,<br>\n[Restaurant Name] Management",
"options": {}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
832,
0
],
"id": "653150c6-f69f-479f-a88a-06c33153e514",
"name": "Send Schedule Email",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n const shiftIds = item.json.staffEmail \n ? $('Format Schedule Email').all().find(i => i.json.staffEmail === item.json.staffEmail)\n : null;\n}\n\n// Simpler approach: pull directly from the Format Schedule Email node's original data\nconst formatted = $('Summarize').all();\n\nfor (const item of formatted) {\n const ids = item.json['concatenated_Shift_ID'].split(',');\n for (const id of ids) {\n results.push({ json: { shiftId: id.trim() } });\n }\n}\n\nreturn results;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1040,
0
],
"id": "1c57ec4b-1fcb-4a74-b285-0362a1ab7d83",
"name": "Code in JavaScript"
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc",
"mode": "list",
"cachedResultName": "Local biz autopilot ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 447491474,
"mode": "list",
"cachedResultName": "Weekly Schedule",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit#gid=447491474"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Shift ID": "={{ $json.shiftId }}",
"Notified?": "TRUE"
},
"matchingColumns": [
"Shift ID"
],
"schema": [
{
"id": "Shift ID",
"displayName": "Shift ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Date",
"displayName": "Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Shift Time",
"displayName": "Shift Time",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Role",
"displayName": "Role",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Staff Assigned",
"displayName": "Staff Assigned",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Staff Email",
"displayName": "Staff Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Notified?",
"displayName": "Notified?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Confirmed?",
"displayName": "Confirmed?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Needs Coverage?",
"displayName": "Needs Coverage?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Covered By",
"displayName": "Covered By",
"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": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
1248,
0
],
"id": "0981e2b7-0173-4ce8-979a-0f6ae8514a3a",
"name": "Update row in sheet",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc",
"mode": "list",
"cachedResultName": "Local biz autopilot ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 447491474,
"mode": "list",
"cachedResultName": "Weekly Schedule",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ccHh2acYFEDpmj6aEeovI5FsoRU1bFbQ9ZADLyrCHGc/edit#gid=447491474"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Shift ID": "={{ $json['Which Shift ID are you confirming? '] }}",
"Confirmed?": "TRUE"
},
"matchingColumns": [
"Shift ID"
],
"schema": [
{
"id": "Shift ID",
"displayName": "Shift ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "Date",
"displayName": "Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Shift Time",
"displayName": "Shift Time",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Role",
"displayName": "Role",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Staff Assigned",
"displayName": "Staff Assigned",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Staff Email",
"displayName": "Staff Email",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Notified?",
"displayName": "Notified?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Confirmed?",
"displayName": "Confirmed?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Needs Coverage?",
"displayName": "Needs Coverage?",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "Covered By",
"displayName": "Covered By",
"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": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
208,
384
],
"id": "44a60089-0a2d-4ef3-886a-2866f1fdcb6e",
"name": "Mark Confirmed",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"documentId": {
"__rl": true,
"value": "1n39mnFOlAP5GgP58G70jcBrSCOo_Jx2IFv7ffrVEMTk",
"mode": "list",
"cachedResultName": "Confirmations",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1n39mnFOlAP5GgP58G70jcBrSCOo_Jx2IFv7ffrVEMTk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": 477781584,
"mode": "list",
"cachedResultName": "Form Responses 1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1n39mnFOlAP5GgP58G70jcBrSCOo_Jx2IFv7ffrVEMTk/edit#gid=477781584"
},
"event": "rowAdded",
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTrigger",
"typeVersion": 1,
"position": [
-16,
384
],
"id": "dfd32895-b2db-4976-b4b3-08050a92d989",
"name": "New Confirmation Submitted",
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
192
],
"id": "728d61d8-beec-499f-bb1a-d732c6820db3",
"name": "Manager Force-Send"
}
],
"connections": {
"Sunday Auto-Publish": {
"main": [
[
{
"node": "Read Weekly Schedule",
"type": "main",
"index": 0
}
]
]
},
"Read Weekly Schedule": {
"main": [
[
{
"node": "Summarize",
"type": "main",
"index": 0
}
]
]
},
"Summarize": {
"main": [
[
{
"node": "Format Schedule Email",
"type": "main",
"index": 0
}
]
]
},
"Format Schedule Email": {
"main": [
[
{
"node": "Send Schedule Email",
"type": "main",
"index": 0
}
]
]
},
"Send Schedule Email": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"New Confirmation Submitted": {
"main": [
[
{
"node": "Mark Confirmed",
"type": "main",
"index": 0
}
]
]
},
"Manager Force-Send": {
"main": [
[
{
"node": "Read Weekly Schedule",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "b2394f1d-9410-4743-99c0-bcf7eb7c4e19",
"meta": {
"templateCredsSetupCompleted": true
},
"nodeGroups": [],
"id": "jmfZ4YjyLyNx5rUo",
"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.
gmailOAuth2googleSheetsOAuth2ApigoogleSheetsTriggerOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Staff Scheduling Automation (Publish + Confirm). Uses googleSheets, gmail, googleSheetsTrigger. Scheduled trigger; 10 nodes.
Source: https://github.com/justinrhedgep-star/cafe-autopilot-n8n/blob/main/03-staff-scheduler.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.
This n8n workflow automates scheduled checks for your target keywords’ positions in Google’s organic search results using SerpAPI. It logs new positions in Google Sheets, compares them to previous ran
YOUR_ID 4. Uses gmail, googleDrive, googleSheets, httpRequest. Scheduled trigger; 53 nodes.
special-day-email-sender. Uses googleSheets, gmail. Scheduled trigger; 43 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
Automatically processes new orders added to Google Sheets. Small orders are approved instantly; large orders trigger an HTML email with one-click Approve / Reject links — each handled by an independen