This workflow corresponds to n8n.io template #17815 — we link there as the canonical source.
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": "Send weekly timesheet reminders to security agents with Gmail and Google Sheets",
"nodes": [
{
"name": "Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-580,
-149
],
"parameters": {
"color": 7,
"width": 420,
"height": 1460,
"content": "## Send Weekly Timesheet Reminders to Security Agents\n\nEvery Friday at 16:00, this workflow reads your active agent roster from Google Sheets, sends each active agent a personalized email reminding them to submit their weekly timesheet, and records the reminder date back in the sheet \u2014 no more chasing on Monday morning.\n\n### How it works\n\n1. **Every Friday 16:00** fires the workflow on a weekly schedule.\n2. **Configure** holds all user-facing settings (sheet URL, manager email).\n3. **Read Active Agents** fetches all rows from your agent roster.\n4. **Capture Row Index** assigns each row a unique index for the final update.\n5. **Filter Active** keeps only agents with Status = Active.\n6. **Send Timesheet Reminder** delivers a personalized reminder to each agent's email.\n7. **Prepare Row Update** retrieves the row index for the sheet update.\n8. **Record Reminder Date** writes today's date to the Last_Reminded column.\n\n### Setup\n\n1. Connect your **Google Sheets OAuth2** credential.\n2. Connect your **Gmail OAuth2** credential.\n3. In the **Configure** node, update `sheetUrl` and `managerEmail`.\n4. Ensure your agent sheet has columns: Agent_Name, Email, Status, Last_Reminded.\n5. Set Status to **Active** for agents who should receive reminders.\n6. Activate the workflow.\n\n### Customization\n\n- Change the trigger time in **Every Friday 16:00** (e.g. 14:00 for an earlier deadline).\n- Add a `Timesheet_Submitted` column and filter it in **Filter Active** to skip agents who already submitted.\n- CC the manager by adding a `cc` field in the Send Timesheet Reminder node."
},
"typeVersion": 1
},
{
"name": "Trigger & Configure",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
-149
],
"parameters": {
"color": 1,
"width": 720,
"height": 369,
"content": "## Trigger & Configure\n\nFires every Friday at 16:00. The Configure node holds all user-facing settings \u2014 update `sheetUrl` and `managerEmail` before activating."
},
"typeVersion": 1
},
{
"name": "Read Data",
"type": "n8n-nodes-base.stickyNote",
"position": [
740,
-147
],
"parameters": {
"color": 1,
"width": 720,
"height": 367,
"content": "## Read Data\n\nFetches all rows from the agent roster sheet. Assigns each row a unique index for the final reminder-date update."
},
"typeVersion": 1
},
{
"name": "Filter & Send",
"type": "n8n-nodes-base.stickyNote",
"position": [
1540,
-147
],
"parameters": {
"color": 1,
"width": 720,
"height": 367,
"content": "## Filter & Send\n\nKeeps only agents with Status = Active. Sends a personalized HTML timesheet reminder to each active agent via Gmail."
},
"typeVersion": 1
},
{
"name": "Record & Update",
"type": "n8n-nodes-base.stickyNote",
"position": [
2340,
-147
],
"parameters": {
"color": 1,
"width": 720,
"height": 367,
"content": "## Record & Update\n\nRetrieves the row index after the email is sent. Updates Google Sheets: records today's date in the Last_Reminded column."
},
"typeVersion": 1
},
{
"name": "Every Friday 16:00",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 16 * * 5"
}
]
}
},
"typeVersion": 1.3
},
{
"name": "Configure",
"type": "n8n-nodes-base.set",
"position": [
400,
0
],
"parameters": {
"mode": "manual",
"options": {},
"assignments": {
"assignments": [
{
"id": "cfg-sheet",
"name": "sheetUrl",
"type": "string",
"value": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID_HERE/edit"
},
{
"id": "cfg-manager",
"name": "managerEmail",
"type": "string",
"value": "user@example.com"
}
]
},
"includeOtherFields": false
},
"typeVersion": 3.4
},
{
"name": "Read Active Agents",
"type": "n8n-nodes-base.googleSheets",
"position": [
800,
0
],
"parameters": {
"options": {},
"resource": "sheet",
"operation": "read",
"sheetName": {
"__rl": true,
"mode": "id",
"value": 0
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Configure').first().json.sheetUrl }}"
}
},
"typeVersion": 4.7
},
{
"name": "Capture Row Index",
"type": "n8n-nodes-base.set",
"position": [
1200,
0
],
"parameters": {
"mode": "manual",
"options": {},
"assignments": {
"assignments": [
{
"id": "assign-row",
"name": "row_number",
"type": "number",
"value": "={{ $itemIndex + 2 }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"name": "Filter Active",
"type": "n8n-nodes-base.filter",
"position": [
1600,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-active",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Status }}",
"rightValue": "Active"
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Send Timesheet Reminder",
"type": "n8n-nodes-base.gmail",
"position": [
2000,
0
],
"parameters": {
"sendTo": "={{ $json.Email }}",
"message": "={{ \"<html><body style=\\\"font-family:Arial,sans-serif\\\"><p>Hello <strong>\" + $json.Agent_Name + \"</strong>,</p><p>This is a reminder to submit your weekly timesheet before end of day today.</p><p>Please send your hours to <a href=\\\"mailto:\" + $('Configure').first().json.managerEmail + \"\\\">\" + $('Configure').first().json.managerEmail + \"</a>.</p><p>If you have already submitted, please disregard this message.</p><p>Thank you</p></body></html>\" }}",
"options": {
"appendAttribution": false
},
"subject": "={{ \"Timesheet reminder \u2014 week of \" + $now.startOf('week').toFormat('dd/MM/yyyy') }}",
"resource": "message",
"emailType": "html",
"operation": "send"
},
"typeVersion": 2.2
},
{
"name": "Prepare Row Update",
"type": "n8n-nodes-base.set",
"position": [
2400,
0
],
"parameters": {
"mode": "manual",
"options": {},
"assignments": {
"assignments": [
{
"id": "restore-row",
"name": "row_number",
"type": "number",
"value": "={{ $('Filter Active').item.json.row_number }}"
}
]
}
},
"typeVersion": 3.4
},
{
"name": "Record Reminder Date",
"type": "n8n-nodes-base.googleSheets",
"position": [
2800,
0
],
"parameters": {
"columns": {
"value": {
"row_number": "={{ $json.row_number }}",
"Last_Reminded": "={{ $now.toFormat('dd/MM/yyyy') }}"
},
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
]
},
"options": {},
"resource": "sheet",
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "id",
"value": 0
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Configure').first().json.sheetUrl }}"
}
},
"typeVersion": 4.7
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"connections": {
"Configure": {
"main": [
[
{
"node": "Read Active Agents",
"type": "main",
"index": 0
}
]
]
},
"Filter Active": {
"main": [
[
{
"node": "Send Timesheet Reminder",
"type": "main",
"index": 0
}
]
]
},
"Capture Row Index": {
"main": [
[
{
"node": "Filter Active",
"type": "main",
"index": 0
}
]
]
},
"Every Friday 16:00": {
"main": [
[
{
"node": "Configure",
"type": "main",
"index": 0
}
]
]
},
"Prepare Row Update": {
"main": [
[
{
"node": "Record Reminder Date",
"type": "main",
"index": 0
}
]
]
},
"Read Active Agents": {
"main": [
[
{
"node": "Capture Row Index",
"type": "main",
"index": 0
}
]
]
},
"Send Timesheet Reminder": {
"main": [
[
{
"node": "Prepare Row Update",
"type": "main",
"index": 0
}
]
]
}
},
"description": "Every Friday at 16:00, reads the active agent roster from Google Sheets, sends each active agent a personalized reminder to submit their weekly timesheet, and records the reminder date back in the sheet."
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs every Friday at 16:00, reads an agent roster from Google Sheets, emails each active agent a personalized timesheet reminder via Gmail, and writes the date the reminder was sent back to the sheet. Runs every Friday at 16:00 on a schedule trigger. Reads all…
Source: https://n8n.io/workflows/17815/ — 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.
BSW Growth Agent · Lite (Free Tier). Uses googleSheets, googleDrive, httpRequest, gmail. Scheduled trigger; 21 nodes.
Founder's Discovery Engine. Uses googleSheets, googleDrive, httpRequest, gmail. Scheduled trigger; 21 nodes.
This workflow runs every Monday at 08:00 to read a Google Sheets roster, calculate days until each agent’s certification expiry date, and send a consolidated HTML alert email via Gmail to the configur
Perfect for store owners and agencies.
Ejemplo01-mejorado. Uses gmail, googleSheets. Scheduled trigger; 6 nodes.