{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "62c90900-7ac7-4e60-a866-7cfcb70bc0ce",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1968,
        -3312
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f8a4a7ec-54d2-4288-8f60-1d56fa0b9bfc",
      "name": "Normalize Incoming Cart Data1",
      "type": "n8n-nodes-base.set",
      "position": [
        1328,
        -3536
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5de472e2-d1e2-4d63-a8c9-99ead5124765",
              "name": "cart_key",
              "type": "string",
              "value": "={{ $json.body.cart_key }}"
            },
            {
              "id": "37b6267a-7a1c-47f7-983c-554a353533bf",
              "name": "email",
              "type": "string",
              "value": "={{ $json.body.email }}"
            },
            {
              "id": "be5ab70f-aeae-4c9d-9ed5-99c4728a24c7",
              "name": "first_name",
              "type": "string",
              "value": "={{ $json.body.first_name }}"
            },
            {
              "id": "95e02b8b-f192-4392-9480-598ad6b9af32",
              "name": "cart_total",
              "type": "string",
              "value": "={{ $json.body.cart_total }}"
            },
            {
              "id": "532216ab-74f7-4e80-bd20-e1527c424823",
              "name": "=item_name",
              "type": "string",
              "value": "={{ $json.body.item_name }}"
            },
            {
              "id": "fc282f53-c42d-4fa5-973f-560e1a56227b",
              "name": "item_quantity",
              "type": "string",
              "value": "={{ $json.body.item_quantity }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bcd46750-ea3f-4b41-85b9-352bbe499e78",
      "name": "Wait before checking cart status1",
      "type": "n8n-nodes-base.wait",
      "position": [
        1568,
        -3536
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "47975c6e-dc86-4418-8128-9a1eaffcb071",
      "name": "Recheck cart status from store1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1776,
        -3536
      ],
      "parameters": {
        "url": "{{your_cart_API_here}}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": " cocart-cart-key",
              "value": "={{$json.cart_key}}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "920e7582-5ac2-443b-bc45-a7c9c564c60b",
      "name": "Cart is Still Abandoned?1",
      "type": "n8n-nodes-base.if",
      "position": [
        1984,
        -3536
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1236c97-f1bc-4fac-b8c5-d10b0c551fc4",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.item_count }}",
              "rightValue": 0
            },
            {
              "id": "1c8397fc-7051-44f6-8f9e-63758b3f99c2",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.needs_payment }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fc119174-0017-45b2-bb55-b2b0a5ab7261",
      "name": "Genrate Personalized Reminder Email1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2240,
        -3552
      ],
      "parameters": {
        "text": "=Create a personalized abandoned cart email.\n\nCustomer name: {{ $json.customer.billing_address.billing_first_name }}\nProduct: {{ $json.items[0].name }}\nTotal: \u20b9{{ $json.items[0].totals.total }}\n\nKeep it under 120 words.\n",
        "options": {
          "systemMessage": "You are an ecommerce marketing assistant.\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "8d0fff1f-e357-4c0e-996d-eca4611b7cad",
      "name": "Extrect Email Subject & Body from AI1",
      "type": "n8n-nodes-base.code",
      "position": [
        2544,
        -3552
      ],
      "parameters": {
        "jsCode": "// Input from the OpenAI node\nconst aiOutput = $json.output;\n\n// Split by line breaks\nconst lines = aiOutput.split(\"\\n\");\n\n// Extract subject (remove \"Subject: \" prefix)\nconst subject = lines[0].replace(\"Subject: \", \"\").trim();\n\n// Extract body (everything after first line)\nconst body = lines.slice(1).join(\"\\n\").trim();\n\n// Return as JSON to use in the next nodes\nreturn [\n  {\n    json: {\n      email_subject: subject,\n      email_body: body\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "86501dcd-f959-48cd-8ca5-1f1bb679903c",
      "name": "Prepare recovery Data1",
      "type": "n8n-nodes-base.set",
      "position": [
        2816,
        -3360
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c67e98b3-8bc0-45af-8f12-b6a612a9663f",
              "name": "Product_name",
              "type": "string",
              "value": "={{ $('Cart is Still Abandoned?1').item.json.items[0].name }}"
            },
            {
              "id": "ec4a0847-1f80-4170-ad5c-1daa8745c107",
              "name": "total",
              "type": "string",
              "value": "={{ $('Cart is Still Abandoned?1').item.json.items[0].totals.total }}"
            },
            {
              "id": "ba37c3aa-0f4a-428e-8c5a-6b2c05364c89",
              "name": "customer_email",
              "type": "string",
              "value": "={{ $('Cart is Still Abandoned?1').item.json.customer.billing_address.billing_email }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "af334cb5-8575-4885-a83f-90bda8ec8317",
      "name": "Send Abandoned cart email to customer1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2816,
        -3744
      ],
      "parameters": {
        "sendTo": "{{Customer_email_here}}",
        "message": "={{ $json.email_body }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.email_subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0ebb8b7c-ba76-4327-b6e4-bfb066538e3a",
      "name": "Notify internal team on slack1",
      "type": "n8n-nodes-base.slack",
      "position": [
        3088,
        -3360
      ],
      "parameters": {
        "text": "=This Product is in User's cart:\n\nProduct Name: {{ $json.Product_name }}\nPrice: {{ $json.total }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09S57E2JQ2",
          "cachedResultName": "n8n"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "92db772c-b7ba-477f-b42a-a320aeb74f1d",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        -3680
      ],
      "parameters": {
        "color": 7,
        "width": 224,
        "height": 288,
        "content": "When a user adds products to the cart and leaves the website without checkout, the website sends cart details (cart key, email, name, etc.) to this webhook."
      },
      "typeVersion": 1
    },
    {
      "id": "d9cfd166-2e4a-440a-bb30-8d268e8b835b",
      "name": "Receive Cart Event1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1088,
        -3536
      ],
      "parameters": {
        "path": "abandoned-cart",
        "options": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "73877890-32c3-4540-9ebd-195620b8182d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        -3680
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 304,
        "content": "This node cleans and organizes the incoming cart data."
      },
      "typeVersion": 1
    },
    {
      "id": "f8af7a51-5ef1-4328-bb93-b6d52e74f49a",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -3744
      ],
      "parameters": {
        "color": 7,
        "width": 1168,
        "height": 544,
        "content": "## Abandoned Cart Verification & AI Reminder Process\n\nThis part of the workflow waits for some time to give the customer a chance to complete checkout. After the wait, it checks the cart again to see if products are still there and payment is still pending. If the cart is still abandoned, AI generates a friendly and personalized reminder email using the customer and cart details. The AI message is then prepared in the correct format so an email can be sent to the customer and a notification can also be sent to the store owner. If the cart is already checked out, the workflow stops automatically."
      },
      "typeVersion": 1
    },
    {
      "id": "cd9f28a9-4d65-4890-ab21-1acbe54af739",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2752,
        -3952
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 384,
        "content": "This node sends the AI-generated reminder email to the customer.\n\nThe email includes:\n- Friendly message\n- Product details\n- Total price\nGoal: Encourage customer to complete checkout.\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4691f866-45fd-40e4-8bd3-6e92b6a371ca",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2752,
        -3520
      ],
      "parameters": {
        "color": 7,
        "width": 688,
        "height": 352,
        "content": "## Prepare Data & Notify team\n\n**Prepare Recovery Data:**  This node prepares final data needed for notifications to internal team \n\n**Notify internal team on slack:** This node sends a notification to the internal team on Slack. "
      },
      "typeVersion": 1
    },
    {
      "id": "463479be-3738-4fbe-8cbb-d1dc802d0003",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -4256
      ],
      "parameters": {
        "width": 496,
        "height": 720,
        "content": "## How it works\n\nWhen a customer leaves items in their cart, the store sends cart details to this workflow using a webhook. The workflow saves the cart information and waits for a short period to give the customer time to complete checkout. After waiting, it checks the cart again from the store. If the cart still has products and payment is not completed, the workflow treats it as an abandoned cart. An AI assistant then creates a friendly, personalized reminder email using the customer name, product name, and cart total. The email content is prepared properly and sent to the customer. At the same time, a notification is sent to Slack so the team knows a reminder was triggered. If the customer has already completed the purchase, the workflow stops automatically.\n\n\n## Setup steps\n\n**1. Webhook:** Connect the webhook to your store to receive abandoned cart details automatically.\n\n**2. Wait Time:**  Set a delay (for example, 30\u201360 minutes) before checking the cart again.\n\n**3. Cart API:** Configure the cart API to recheck the cart using the cart key.\n\n**4. OpenAI:** Connect OpenAI to generate a personalized abandoned cart email message.\n\n**5. Gmail:** Set up Gmail to send the reminder email directly to the customer.\n\n**6. Slack:** Connect Slack to notify your internal team when a cart reminder is sent."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Genrate Personalized Reminder Email1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Receive Cart Event1": {
      "main": [
        [
          {
            "node": "Normalize Incoming Cart Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare recovery Data1": {
      "main": [
        [
          {
            "node": "Notify internal team on slack1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cart is Still Abandoned?1": {
      "main": [
        [
          {
            "node": "Genrate Personalized Reminder Email1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Incoming Cart Data1": {
      "main": [
        [
          {
            "node": "Wait before checking cart status1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recheck cart status from store1": {
      "main": [
        [
          {
            "node": "Cart is Still Abandoned?1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before checking cart status1": {
      "main": [
        [
          {
            "node": "Recheck cart status from store1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Genrate Personalized Reminder Email1": {
      "main": [
        [
          {
            "node": "Extrect Email Subject & Body from AI1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrect Email Subject & Body from AI1": {
      "main": [
        [
          {
            "node": "Prepare recovery Data1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send Abandoned cart email to customer1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}