Automate Shopify Abandoned-Cart Emails with n8n and AI

AgentRoost · June 13, 2026 · 6 min read · View as Markdown
AgentRoost — n8n Automation

About 70% of online shopping carts are abandoned before checkout. A well-timed email — one that speaks to what the customer actually left behind — recovers a meaningful slice of those lost sales.

Generic "You left something behind!" templates recover some of them. An email that says "You were this close to getting the Merino Wool Crew-Neck in forest green — here's why it's worth coming back" converts significantly better.

This guide walks through building exactly that: a running n8n workflow that catches Shopify checkout abandonment events in real time, waits the right amount of time, then asks an LLM to write a personalized, product-specific email — and sends it.


How the workflow fits together

The flow has five stages:

Shopify Webhook → Wait → Check if order placed → AI writes email → Send Email

Each stage maps to specific n8n nodes. Let's build it step by step.


Step 1 — Receive the abandonment event from Shopify

Node: Webhook

Shopify fires a checkouts/create or checkouts/update event when a customer fills in their email and adds items but doesn't complete the purchase. You'll catch this with a Webhook node.

In your n8n canvas, add a Webhook node. Set the method to POST, copy the generated URL — it will look like https://<your-id>.agentroost.app/webhook/shopify-cart — and paste it into Shopify:

Shopify Admin → Settings → Notifications → Webhooks → Create webhook Event: Checkout creation (and optionally Checkout update) Format: JSON URL: your Webhook node URL

The payload arrives with everything you need: email, line_items (product titles, quantities, prices), subtotal_price, and abandoned_checkout_url (Shopify's recovery link).


Step 2 — Wait before sending anything

Node: Wait

Don't email immediately. Customers who abandon a cart sometimes complete the purchase within 30–60 minutes on a different device or after a phone call. Emailing them mid-checkout looks pushy and creates confusion if they do convert.

Add a Wait node after the Webhook. Set it to 1 hour (or 30 minutes for faster-moving products). The workflow suspends here — no polling, no memory usage — and resumes automatically when the timer fires.


Step 3 — Check whether the order was placed in the meantime

Node: HTTP Request + IF

Before sending anything, verify the cart is still abandoned. Use the HTTP Request node to call the Shopify REST API:

GET https://{{$node["Webhook"].json.domain}}/admin/api/2024-07/checkouts/{{$node["Webhook"].json.token}}.json

Add your Shopify API credentials (Admin API access token) in the Header Auth credential. The response includes a completed_at field — it's null if the cart is still open, or a timestamp if the order went through.

Add an IF node:

  • Condition: {{$node["HTTP Request"].json.checkout.completed_at}} is empty
  • True branch → continue to email
  • False branch → NoOp (do nothing, order was placed)

This prevents you from emailing someone who already bought.


Step 4 — Let the AI write a personalized email

Node: AI / LLM

This is where generic tools fall short. Instead of a fixed template, you give the LLM the cart contents and ask it to write something specific and useful.

Add a Basic LLM Chain node (under the AI section). In the System Message, put something like:

You are a friendly email copywriter for an e-commerce brand.
Write a short, warm abandoned-cart recovery email.
Be specific about the products. No hard-sell language.
Include a clear call-to-action at the end. Max 120 words.

In the User Message, use an expression that pulls the actual cart data:

The customer {{$node["Webhook"].json.email}} left these items:

{{$node["Webhook"].json.line_items.map(i => `- ${i.title} x${i.quantity} ($${i.price})`).join('\n')}}

Cart total: ${{$node["Webhook"].json.subtotal_price}}
Recovery link: {{$node["Webhook"].json.abandoned_checkout_url}}

Write the email.

The AI output is a natural, product-aware win-back message — different for a customer who left $12 of face wash than for someone who left $380 of camera gear.


Step 5 — Send the email

Node: Send Email (SMTP) or Gmail

Add a Send Email node (or the Gmail node if you prefer OAuth). Wire it up:

  • To: {{$node["Webhook"].json.email}}
  • Subject: something like Still thinking it over? or use another short AI call to generate a subject line
  • Body (HTML): {{$node["LLM"].json.text}}
  • From: your store's sender address

For SMTP, you'll need your email provider credentials (Gmail app password, SendGrid, Brevo, etc.) stored in an n8n credential. The node stays generic — you're just pointing it at your existing email infrastructure.


Handling edge cases

Duplicate triggers: Shopify can fire checkouts/update multiple times. Add a Set node early in the flow to extract the cart token, then use n8n's built-in Deduplication node (available in recent n8n versions) keyed on that token. Only the first event per token proceeds.

Unsubscribed customers: If you maintain a suppression list in a Google Sheet or Airtable, add an HTTP Request (or native node) to check it before the Wait step. If the customer is on the list, route to NoOp.

Test with a real checkout: Shopify's webhook test tool sends a sample payload but it won't have a real abandoned_checkout_url. Do one real checkout-dropout on your store (use a personal email) to see the actual payload shape before going live.


Run this on AgentRoost — no DevOps required

Building this locally means managing Docker, SSL certificates, a public hostname for the Shopify webhook, uptime monitoring, and your own OpenAI API key. All of that adds up before you've sent a single recovery email.

On AgentRoost, you get your own n8n instance — your login, your workflows, your data — running 24/7 on a public subdomain (https://<your-id>.agentroost.app). The AI/LLM nodes are already wired to included credits. You don't create an OpenAI account, you don't enter an API key, you don't monitor usage dashboards. The AI node just works.

How to set it up:

  1. Sign up at agentroost.app — from $19.99/mo, 14-day money-back guarantee.
  2. Create a new workspace, pick the n8n framework, give it a name.
  3. Your private n8n editor opens at https://<your-id>.agentroost.app within about 2 minutes.
  4. Import or build the workflow above. The Webhook node's URL is already public HTTPS — paste it into Shopify immediately.
  5. Activate the workflow. It runs 24/7 without you keeping a laptop open.

The included AI credits cover the LLM calls for email generation. As your volume grows, Plus and Pro tiers add more compute and more included credits. Compare plans to see what fits your store's size.


Tips to improve recovery rate

  • Timing matters more than copy. 1 hour is a good start; test 30 min vs. 2 hr to find your store's sweet spot.
  • Product images in the email require HTML templating — pull the line_items[].image URLs from the Shopify payload and add them to an HTML body template instead of plain text output from the AI.
  • Second follow-up (optional): add a second branch 24 hours later that checks again and sends a shorter "last chance" email if still no order. Keep it to a maximum of 2 emails per cart — more than that starts hurting sender reputation.
  • UTM-tag the recovery link: append ?utm_source=email&utm_medium=cart-recovery&utm_campaign=abandonment to abandoned_checkout_url so you can track recovery conversions in Google Analytics separately from organic traffic.

Frequently asked questions

Do I need an OpenAI API key to use the AI node in n8n on AgentRoost?

No. AI/LLM credits are included in your AgentRoost subscription. The AI node is pre-wired and ready to use — you won't be prompted for an API key, and you won't receive a separate OpenAI bill.

Will Shopify's webhook reach my n8n instance?

Yes. Every n8n instance on AgentRoost runs at a public HTTPS subdomain (https://<your-id>.agentroost.app). The Webhook node's URL is valid the moment your workspace is created — no tunnel, no port-forwarding, no SSL setup required.

What happens if a customer completes the order after I've already triggered the workflow?

The workflow waits (Step 2), then calls the Shopify API to check completed_at (Step 3). If the order was placed during the wait period, the IF node routes to a NoOp branch and no email is sent.

Can I cancel my AgentRoost plan if this doesn't work for my store?

Yes — plans are monthly, cancel anytime. There's also a 14-day money-back guarantee, so you can build and test the workflow with zero financial risk.

How do I stop the workflow from emailing the same customer twice if Shopify fires multiple webhook events?

Use a Deduplication node early in the flow, keyed on the cart token field from the Shopify payload. Only the first event per token passes through; subsequent updates for the same cart are dropped.