This workflow corresponds to n8n.io template #6045 — 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 →
{
"nodes": [
{
"id": "1",
"name": "Cart Abandoned Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
240,
300
],
"parameters": {
"path": "cart-abandoned",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 1
},
{
"id": "2",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
140,
180
],
"parameters": {
"width": 240,
"height": 160,
"content": "## Cart Recovery Config\n\n\u2699\ufe0f **Customize these settings:**\n- Recovery sequence timing\n- Discount percentages\n- Email templates\n- Exclusion rules"
},
"typeVersion": 1
},
{
"id": "3",
"name": "Recovery Settings",
"type": "n8n-nodes-base.set",
"position": [
440,
300
],
"parameters": {
"values": {
"number": [
{
"name": "firstDiscount",
"value": 10
},
{
"name": "secondDiscount",
"value": 15
},
{
"name": "finalDiscount",
"value": 20
}
],
"string": [
{
"name": "fromEmail",
"value": "user@example.com"
},
{
"name": "baseUrl",
"value": "https://your-store.com"
}
]
}
},
"typeVersion": 1
},
{
"id": "4",
"name": "Qualify Cart",
"type": "n8n-nodes-base.if",
"position": [
640,
300
],
"parameters": {
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.cart_value }}",
"rightValue": 50
},
{
"operator": {
"type": "string",
"operation": "isNotEmpty"
},
"leftValue": "={{ $json.customer_email }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "5",
"name": "Generate Recovery Data",
"type": "n8n-nodes-base.code",
"position": [
840,
300
],
"parameters": {
"jsCode": "// Generate discount codes for recovery sequence\nconst cartId = $json.cart_id;\nconst customerEmail = $json.customer_email;\nconst timestamp = Date.now();\n\n// Create unique discount codes\nconst codes = {\n firstCode: `SAVE${$node['Recovery Settings'].json.firstDiscount}-${cartId.slice(-4)}`,\n secondCode: `SAVE${$node['Recovery Settings'].json.secondDiscount}-${cartId.slice(-4)}`,\n finalCode: `SAVE${$node['Recovery Settings'].json.finalDiscount}-${cartId.slice(-4)}`\n};\n\n// Calculate recovery schedule\nconst schedules = {\n firstEmail: new Date(timestamp + 1 * 60 * 60 * 1000).toISOString(), // 1 hour\n secondEmail: new Date(timestamp + 24 * 60 * 60 * 1000).toISOString(), // 24 hours\n finalEmail: new Date(timestamp + 72 * 60 * 60 * 1000).toISOString() // 72 hours\n};\n\nreturn {\n ...codes,\n ...schedules,\n cartData: $json,\n recoveryId: `recovery_${cartId}_${timestamp}`\n};"
},
"typeVersion": 1
},
{
"id": "6",
"name": "Wait 1 Hour",
"type": "n8n-nodes-base.wait",
"position": [
1040,
200
],
"parameters": {
"unit": "hours",
"amount": 1
},
"typeVersion": 1
},
{
"id": "7",
"name": "Send First Recovery Email",
"type": "n8n-nodes-base.gmail",
"position": [
1240,
200
],
"parameters": {
"sendTo": "={{ $node['Generate Recovery Data'].json.cartData.customer_email }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f8f9fa; }\n .container { max-width: 600px; margin: 0 auto; background: white; border-radius: 10px; padding: 30px; }\n .header { text-align: center; margin-bottom: 30px; }\n .product-item { border: 1px solid #eee; padding: 20px; margin: 10px 0; border-radius: 8px; }\n .cta-button { background: #007bff; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 20px 0; }\n .discount { background: #28a745; color: white; padding: 10px; text-align: center; margin: 20px 0; border-radius: 5px; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h2>Your cart is waiting for you! \ud83d\uded2</h2>\n <p>Hello {{ $node['Generate Recovery Data'].json.cartData.customer_name }},</p>\n <p>You left some items in your cart. Don't let them get away!</p>\n </div>\n \n {{#each $node['Generate Recovery Data'].json.cartData.items}}\n <div class=\"product-item\">\n <h3>{{ this.name }}</h3>\n <p>Price: {{ this.price }} \u20ac</p>\n <p>Quantity: {{ this.quantity }}</p>\n </div>\n {{/each}}\n \n <div class=\"discount\">\n <h3>\ud83c\udf89 Special offer - 10% discount!</h3>\n <p>Code: <strong>{{ $node['Generate Recovery Data'].json.firstCode }}</strong></p>\n </div>\n \n <div style=\"text-align: center;\">\n <a href=\"{{ $node['Recovery Settings'].json.baseUrl }}/cart/{{ $node['Generate Recovery Data'].json.cartData.cart_id }}\" class=\"cta-button\">\n Complete my order\n </a>\n </div>\n \n <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n This offer expires in 24 hours. Hurry up!\n </p>\n </div>\n</body>\n</html>",
"options": {
"contentType": "html"
},
"subject": "You forgot something in your cart \ud83d\uded2"
},
"typeVersion": 1
},
{
"id": "8",
"name": "Wait 23 Hours More",
"type": "n8n-nodes-base.wait",
"position": [
1440,
200
],
"parameters": {
"unit": "hours",
"amount": 23
},
"typeVersion": 1
},
{
"id": "9",
"name": "Send Second Recovery Email",
"type": "n8n-nodes-base.gmail",
"position": [
1640,
200
],
"parameters": {
"sendTo": "={{ $node['Generate Recovery Data'].json.cartData.customer_email }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f8f9fa; }\n .container { max-width: 600px; margin: 0 auto; background: white; border-radius: 10px; padding: 30px; }\n .header { text-align: center; margin-bottom: 30px; }\n .urgency { background: #dc3545; color: white; padding: 15px; text-align: center; margin: 20px 0; border-radius: 5px; }\n .cta-button { background: #28a745; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 20px 0; }\n .discount { background: #ffc107; color: #212529; padding: 15px; text-align: center; margin: 20px 0; border-radius: 5px; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h2>\ud83d\udea8 Your cart expires soon!</h2>\n <p>Hello {{ $node['Generate Recovery Data'].json.cartData.customer_name }},</p>\n </div>\n \n <div class=\"urgency\">\n <h3>\u23f0 Only a few hours left!</h3>\n <p>Your cart will be automatically deleted soon</p>\n </div>\n \n <div class=\"discount\">\n <h3>\ud83c\udf81 Exceptional offer - 15% discount!</h3>\n <p>Code: <strong>{{ $node['Generate Recovery Data'].json.secondCode }}</strong></p>\n <p>Valid only for the next 24 hours</p>\n </div>\n \n <div style=\"text-align: center;\">\n <a href=\"{{ $node['Recovery Settings'].json.baseUrl }}/cart/{{ $node['Generate Recovery Data'].json.cartData.cart_id }}\" class=\"cta-button\">\n I'll recover my cart now\n </a>\n </div>\n \n <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n Your cart total: {{ $node['Generate Recovery Data'].json.cartData.cart_value }} \u20ac\n </p>\n </div>\n</body>\n</html>",
"options": {
"contentType": "html"
},
"subject": "Last chance - Your discount is waiting! \ud83d\udcb8"
},
"typeVersion": 1
},
{
"id": "10",
"name": "Wait 48 Hours More",
"type": "n8n-nodes-base.wait",
"position": [
1840,
200
],
"parameters": {
"unit": "hours",
"amount": 48
},
"typeVersion": 1
},
{
"id": "11",
"name": "Send Final Recovery Email",
"type": "n8n-nodes-base.gmail",
"position": [
2040,
200
],
"parameters": {
"sendTo": "={{ $node['Generate Recovery Data'].json.cartData.customer_email }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f8f9fa; }\n .container { max-width: 600px; margin: 0 auto; background: white; border-radius: 10px; padding: 30px; }\n .header { text-align: center; margin-bottom: 30px; }\n .final-offer { background: linear-gradient(45deg, #ff6b6b, #ffa500); color: white; padding: 20px; text-align: center; margin: 20px 0; border-radius: 10px; }\n .cta-button { background: #dc3545; color: white; padding: 20px 40px; text-decoration: none; border-radius: 5px; display: inline-block; margin: 20px 0; font-size: 18px; }\n .testimonial { background: #e9ecef; padding: 15px; margin: 20px 0; border-radius: 5px; font-style: italic; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h2>\ud83d\udd25 Final offer - Don't miss this chance!</h2>\n <p>{{ $node['Generate Recovery Data'].json.cartData.customer_name }}, this is really your last chance...</p>\n </div>\n \n <div class=\"final-offer\">\n <h2>\ud83c\udfaf EXCLUSIVE OFFER</h2>\n <h3>20% DISCOUNT</h3>\n <p>Code: <strong>{{ $node['Generate Recovery Data'].json.finalCode }}</strong></p>\n <p>\u23f0 Expires in 24 hours - Definitely!</p>\n </div>\n \n <div class=\"testimonial\">\n <p>\"I loved my purchases on this site! Fast delivery and quality products.\" - Sarah M.</p>\n </div>\n \n <div style=\"text-align: center;\">\n <a href=\"{{ $node['Recovery Settings'].json.baseUrl }}/cart/{{ $node['Generate Recovery Data'].json.cartData.cart_id }}\" class=\"cta-button\">\n I'll take advantage now!\n </a>\n </div>\n \n <p style=\"color: #666; font-size: 14px; margin-top: 30px;\">\n If you no longer want to receive these emails, <a href=\"#\">click here</a>.\n </p>\n </div>\n</body>\n</html>",
"options": {
"contentType": "html"
},
"subject": "Absolutely last chance - 20% discount! \ud83d\udd25"
},
"typeVersion": 1
},
{
"id": "12",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1940,
60
],
"parameters": {
"width": 240,
"height": 160,
"content": "## Recovery Analytics\n\n\ud83d\udcca **Track performance:**\n- Recovery conversion rates\n- Revenue generated\n- Email open rates\n- Best performing sequences"
},
"typeVersion": 1
},
{
"id": "13",
"name": "Track Recovery Start",
"type": "n8n-nodes-base.googleSheets",
"position": [
1040,
400
],
"parameters": {
"values": {
"values": [
"={{ $node['Generate Recovery Data'].json.recoveryId }}",
"={{ $node['Generate Recovery Data'].json.cartData.customer_email }}",
"={{ $node['Generate Recovery Data'].json.cartData.cart_value }}",
"={{ new Date().toISOString() }}",
"sequence_started"
]
},
"resource": "sheet",
"operation": "appendRow",
"sheetName": "Cart Recovery Tracking",
"documentId": "your-google-sheet-id"
},
"typeVersion": 1
}
],
"connections": {
"Wait 1 Hour": {
"main": [
[
{
"node": "Send First Recovery Email",
"type": "main",
"index": 0
}
]
]
},
"Qualify Cart": {
"main": [
[
{
"node": "Generate Recovery Data",
"type": "main",
"index": 0
}
]
]
},
"Recovery Settings": {
"main": [
[
{
"node": "Qualify Cart",
"type": "main",
"index": 0
}
]
]
},
"Wait 23 Hours More": {
"main": [
[
{
"node": "Send Second Recovery Email",
"type": "main",
"index": 0
}
]
]
},
"Wait 48 Hours More": {
"main": [
[
{
"node": "Send Final Recovery Email",
"type": "main",
"index": 0
}
]
]
},
"Cart Abandoned Webhook": {
"main": [
[
{
"node": "Recovery Settings",
"type": "main",
"index": 0
}
]
]
},
"Generate Recovery Data": {
"main": [
[
{
"node": "Wait 1 Hour",
"type": "main",
"index": 0
},
{
"node": "Track Recovery Start",
"type": "main",
"index": 0
}
]
]
},
"Send First Recovery Email": {
"main": [
[
{
"node": "Wait 23 Hours More",
"type": "main",
"index": 0
}
]
]
},
"Send Second Recovery Email": {
"main": [
[
{
"node": "Wait 48 Hours More",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automatic Detection: Instantly identifies abandoned carts via webhook from your e-commerce store.
Source: https://n8n.io/workflows/6045/ — 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 template is designed for freelancers, small businesses, and finance teams who need automated invoice management with intelligent payment follow-ups. Perfect for service providers, agencies, or an
Automate short-term trading research by generating high-quality trade ideas using MCP (Market Context Protocol) signals and AI-powered analysis. 📈🤖 This workflow evaluates market context, catalysts, m
A complete, production-ready newsletter automation workflow that validates email addresses, sends personalized welcome emails, and maintains comprehensive logs in Google Sheets. Perfect for marketing
This n8n workflow is designed to centralize the management and tracking of customer inquiries received through multiple channels (email and web forms).
Simplified registration: Automatically captures sign-ups via optimized web forms.