
Simple coupon points tracker with Google Sheets and scheduled email summary
Description
Categories
📊 Productivity
Nodes Used
n8n-nodes-base.setn8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.coden8n-nodes-base.gmailn8n-nodes-base.mergen8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.formTrigger
PriceKostenlos
Views0
Last Updated11/28/2025
workflow.json
{
"id": "zndFTylPvoppjr5A",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Simple coupon points tracker with Google Sheets and scheduled email summary",
"tags": [],
"nodes": [
{
"id": "59e7faf4-d3ed-4422-92b3-e1bcaac0bb8f",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
-528,
336
],
"parameters": {
"name": "={{$json[\"Screenshot\"][\"filename\"]}}",
"driveId": {
"__rl": true,
"mode": "id",
"value": ""
},
"options": {
"simplifyOutput": false
},
"folderId": {
"__rl": true,
"mode": "id",
"value": ""
},
"inputDataFieldName": "=Screenshot"
},
"typeVersion": 3
},
{
"id": "3b72e912-8bc1-4cc9-a24d-81b67207ceea",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-752,
656
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
6
],
"triggerAtHour": 10
}
]
}
},
"typeVersion": 1.2
},
{
"id": "d9463e4e-e7dc-4335-bf72-0b58ee871e3b",
"name": "calcDate",
"type": "n8n-nodes-base.code",
"position": [
-528,
208
],
"parameters": {
"jsCode": "const purchaseDate = new Date($json['Purchase Date']);\nconst delay = parseInt($json['Redeem Delay']);\n\nconst claimableDate = new Date(purchaseDate);\nclaimableDate.setDate(purchaseDate.getDate() + delay);\n\nreturn [{\n json: {\n ...$json,\n 'Claimable Date': claimableDate.toISOString().split('T')[0]\n }\n}];"
},
"typeVersion": 2
},
{
"id": "453d7da8-74c4-4182-a899-85eb154b9607",
"name": "Get row(s) in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-528,
656
],
"parameters": {
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultUrl": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 4.6
},
{
"id": "122edb03-03ae-446d-98d3-8e12e46c4332",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
160,
656
],
"parameters": {
"sendTo": "",
"message": "={{ $json.body }}\n",
"options": {
"appendAttribution": false
},
"subject": "=Weekly Claimable Bonus Points - Checked {{ $json.dateChecked }}"
},
"typeVersion": 2.1
},
{
"id": "41752228-49fe-40bc-a0dc-5d00f7a0c1b8",
"name": "filteredRows",
"type": "n8n-nodes-base.code",
"position": [
-288,
656
],
"parameters": {
"jsCode": "const today = new Date();\nconst todayStr = today.toISOString().slice(0, 10);\n\nconst filtered = items.filter(item => {\n const claimDate = new Date(item.json[\"Claimable Date\"]);\n return claimDate <= today;\n}).map(item => {\n return {\n json: {\n ...item.json,\n currentDate: todayStr\n }\n };\n});\n\nreturn filtered;"
},
"typeVersion": 2
},
{
"id": "6dfdcc94-ca0b-4edf-b1b5-75baf14fba55",
"name": "rewrite",
"type": "n8n-nodes-base.code",
"position": [
-64,
656
],
"parameters": {
"jsCode": "const today = new Date();\nconst todayStr = today.toISOString().slice(0, 10);\n\nconst rows = items\n .map(i => i.json)\n .filter(r => new Date(r[\"Claimable Date\"]) <= today);\n\nif (rows.length === 0) {\n return [{\n json: {\n body: \"<p>No claimable points this week.</p>\",\n dateChecked: todayStr\n }\n }];\n}\n\n// Build HTML table\nlet html = `<p>Claimable Bonus Points as of ${todayStr}:</p>`;\nhtml += `<table border=\"1\" cellpadding=\"4\" cellspacing=\"0\" style=\"border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px;\">`;\nhtml += \"<thead><tr>\";\n\n// Updated headers\nconst headers = [\n \"Row\",\n \"Coupon Name\",\n \"Account Used to Buy\",\n \"Program\",\n \"Points\",\n \"Bonus Points\",\n \"Purchase Date\",\n \"Redeem Delay (days)\",\n \"Claimable Date\",\n \"Coupon Screen\"\n];\n\nheaders.forEach(h => {\n html += `<th style=\"background:#eee;\">${h}</th>`;\n});\nhtml += \"</tr></thead><tbody>\";\n\n// Add rows\nrows.forEach(r => {\n html += \"<tr>\";\n html += `<td>${r.row_number || \"\"}</td>`;\n html += `<td>${r[\"Coupon Name\"] || \"\"}</td>`;\n html += `<td>${r[\"Account Used to Buy\"] || \"\"}</td>`;\n html += `<td>${r[\"Program\"] || \"\"}</td>`;\n html += `<td>${r[\"Points\"] || \"\"}</td>`;\n html += `<td>${r[\"Bonus Points\"] || \"\"}</td>`;\n html += `<td>${r[\"Purchase Date\"] || \"\"}</td>`;\n html += `<td>${r[\"Redeem Delay (days)\"] || \"\"}</td>`;\n html += `<td>${r[\"Claimable Date\"] || \"\"}</td>`;\n html += `<td>${r[\"Coupon Screen\"] || \"\"}</td>`;\n html += \"</tr>\";\n});\n\nhtml += \"</tbody></table>\";\n\nreturn [{\n json: {\n body: html,\n dateChecked: todayStr\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "46d71fc4-9f17-4635-8f0b-692d7ee3e0d7",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-288,
272
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineAll"
},
"typeVersion": 3.2
},
{
"id": "4ab00a13-cc29-4d63-8b09-5dccc5909876",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1264,
96
],
"parameters": {
"width": 448,
"height": 720,
"content": "## Coupon Points Tracker\nThis workflow helps you keep track of every loyalty point you should receive from your coupon activity. Upload screenshots, log all coupon details in Google Sheets, and get weekly summaries of points that are expected to appear in your account.\n\nInstead of focusing on claiming points immediately, it’s designed to spot missing points and help you follow up with customer service if needed. It calculates when points are expected based on purchase date plus redeem delay, so you’ll always know which points are due and which might be missing.\n\nUse this template to maintain a clear, organized record of your loyalty program activity and make sure you never miss points you’re entitled to (e.g., Payback, Miles & More).\n\n### How to use\n*Access the form trigger via a unique URL to enter coupon data and upload screenshots.\n*Connect your Google Drive and Google Sheets credentials in n8n to store files and log data automatically.\n*Set up the email recipient in the “Send a message” node to receive weekly summaries of expected points.\n*Adjust the schedule trigger to change how often you get updates.\n\n### Requirements\n*Google Drive account for storing uploaded screenshots\n*Google Sheets account for logging your points\n*Gmail account for sending weekly summary emails\n*Track, verify, and never miss a point!"
},
"typeVersion": 1
},
{
"id": "2b89a51c-9324-4aa4-a6ab-a767d0d307d2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-800,
96
],
"parameters": {
"color": 7,
"width": 1152,
"height": 384,
"content": "## Saving Coupon Data and Screenshots\nWhen you submit a coupon, the workflow automatically stores both your coupon details and any uploaded screenshots. The screenshot is first uploaded to Google Drive, keeping your proof safely stored in the cloud. At the same time, all coupon information is added as a new row in a dedicated Google Sheet.\nThis setup keeps your files and data neatly organized: screenshots are stored securely, while unclaimed coupon details are easy to view, track, and analyze from one central place."
},
"typeVersion": 1
},
{
"id": "bb0a9cc8-b5a6-4bc4-82e3-0764f61d1973",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-800,
512
],
"parameters": {
"color": 7,
"width": 1152,
"height": 304,
"content": "## Weekly Claimable Points Check\nOnce a week, a scheduled trigger runs automatically to check which of your stored coupons have reached their claimable date. The workflow looks through the Google Sheet, filters out the coupons that are now ready to redeem, and neatly formats the results into a clear summary email.\nYou’ll then receive this update via Gmail, so you always know which rewards you can claim. This simple automation helps you stay on top of your bonus points effortlessly and ensures you never miss a reward."
},
"typeVersion": 1
},
{
"id": "7e8d7622-6c5d-468b-b7b3-49cd2a394394",
"name": "Tracking Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
-752,
272
],
"parameters": {
"path": "CouponTracker",
"options": {
"formSubmittedText": "Your response has been recorded"
},
"formTitle": "Coupon Points Tracker",
"formFields": {
"values": [
{
"fieldLabel": "Coupon Name",
"requiredField": true
},
{
"fieldLabel": "Account Used",
"requiredField": true
},
{
"fieldType": "dropdown",
"fieldLabel": "Program",
"fieldOptions": {
"values": [
{
"option": "Payback"
},
{
"option": "Miles and More"
},
{
"option": "OTHER"
}
]
},
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Base Points Expected",
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Extra Points Expected"
},
{
"fieldType": "date",
"fieldLabel": "Purchase Date",
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Redeem Delay",
"requiredField": true
},
{
"fieldType": "file",
"fieldLabel": "Screenshot",
"multipleFiles": false
}
]
}
},
"typeVersion": 1
},
{
"id": "1dca24f0-285d-402e-a961-33e757934d12",
"name": "Append row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
160,
272
],
"parameters": {
"columns": {
"value": {
"Coupon Name": "={{ $json['Coupon Name'] }}"
},
"schema": [
{
"id": "Coupon Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Coupon Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Account Used to Buy",
"type": "string",
"display": true,
"required": false,
"displayName": "Account Used to Buy",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Program",
"type": "string",
"display": true,
"required": false,
"displayName": "Program",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Points",
"type": "string",
"display": true,
"required": false,
"displayName": "Points",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Bonus Points",
"type": "string",
"display": true,
"required": false,
"displayName": "Bonus Points",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Purchase Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Purchase Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Redeem Delay (days)",
"type": "string",
"display": true,
"required": false,
"displayName": "Redeem Delay (days)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Claimable Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Claimable Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Coupon Screen",
"type": "string",
"display": true,
"required": false,
"displayName": "Coupon Screen",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "fields",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "fields",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultUrl": "",
"cachedResultName": ""
}
},
"typeVersion": 4.6
},
{
"id": "fe2a2a00-3f37-4ca1-b38a-3091b4d577f5",
"name": "Clean Set",
"type": "n8n-nodes-base.set",
"position": [
-64,
272
],
"parameters": {
"values": {
"string": [
{
"name": "Coupon Name",
"value": "={{ $json[\"Coupon Name\"] }}"
},
{
"name": "Account Used to Buy",
"value": "={{ $json[\"Account Used\"] }}"
},
{
"name": "Program",
"value": "={{ $json[\"Program\"] }}"
},
{
"name": "Points",
"value": "={{ $json[\"Base Points Expected\"] }}"
},
{
"name": "Bonus Points",
"value": "={{ $json[\"Extra Points Expected\"] }}"
},
{
"name": "Purchase Date",
"value": "={{ $json[\"Purchase Date\"] }}"
},
{
"name": "Redeem Delay (days)",
"value": "={{ $json[\"Redeem Delay\"] }}"
},
{
"name": "Claimable Date",
"value": "={{ $json[\"Claimable Date\"] }}"
},
{
"name": "Coupon Screen",
"value": "={{ $json[\"webViewLink\"] }}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "2472690b-8a88-4ed4-b10a-1b67787d333d",
"connections": {
"Merge": {
"main": [
[
{
"node": "Clean Set",
"type": "main",
"index": 0
}
]
]
},
"rewrite": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"calcDate": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Clean Set": {
"main": [
[
{
"node": "Append row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Upload file": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"filteredRows": {
"main": [
[
{
"node": "rewrite",
"type": "main",
"index": 0
}
]
]
},
"Tracking Form": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
},
{
"node": "calcDate",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "filteredRows",
"type": "main",
"index": 0
}
]
]
}
}
}