How to Generate Personalized Win-Back Emails from AI Analysis of Order History

Build a Spojit workflow that runs on a schedule, finds lapsed Shopify customers, lets an Agent-mode Connector node analyze each person's purchase history to draft a tailored win-back message, and sends that message from your own domain through Resend.

What This Integration Does

Customers who used to buy regularly and then go quiet are some of your highest-value re-engagement targets, but a single generic "we miss you" blast ignores what each person actually bought. This workflow closes that gap. It pulls the orders for each lapsed customer, hands the buying history to the agent, and asks it to write a short, specific win-back email that references the products that customer cared about. Resend then delivers each message from your verified sending domain so it lands as a real email from your brand, not from a generic relay.

The workflow runs unattended on a Schedule trigger (for example every Monday morning). On each run it queries Shopify for customers whose last order falls inside your lapsed window, loops over them, fetches each customer's order history, generates a personalized draft with an Agent-mode Connector node, and sends it with Resend. Nothing is stored between runs, so the workflow is stateless: re-running it simply re-evaluates the lapsed set against live Shopify data. Because of that, you should narrow the query and add a guard (covered in Step 4) so the same customer is not emailed on every run.

Prerequisites

  • A Shopify connection in Spojit (Connections -> Add connection -> Shopify) with read access to orders and customers.
  • A Resend connection with a verified sending domain. Verify the domain first using the Resend verify-domain tool or the Resend dashboard, or your sends will be rejected.
  • A clear definition of "lapsed" for your store, for example "no order in the last 90 days" and "at least 2 lifetime orders", so you target real regulars rather than one-time buyers.
  • AI credits available on your plan, since the Agent-mode drafting step consumes credits per customer.

Step 1: Start with a Schedule trigger

Add a Trigger node and set its type to Schedule. Enter a 5-field Unix cron expression and an IANA timezone so the run fires at a sensible local hour. For a weekly Monday 9am send in Sydney, use:

0 9 * * 1
Australia/Sydney

The trigger output is { scheduledAt }, the timestamp of the run. You will reuse this as the reference point for your lapsed-window calculation in the next step. A single Schedule trigger can hold multiple schedules if you later want a second cadence.

Step 2: Compute the lapsed cutoff date

Add a Connector node in Direct mode on the date utility connector and pick the subtract tool. Subtract your lapsed window (for example 90 days) from {{ trigger.scheduledAt }} to get the cutoff date that orders must predate. Add a second date step with format if you need the cutoff as a plain YYYY-MM-DD string for the Shopify query. Store the formatted result, for example as {{ cutoff.value }}, so later steps can reference it.

Step 3: Find lapsed customers in Shopify

Add a Connector node in Direct mode on the Shopify connector and select the list-customers tool. The tool accepts a query field that uses Shopify search syntax, so you can filter on last-order date and lifetime order count. Build the query from your cutoff value:

last_order_date:<{{ cutoff.value }}T00:00:00Z AND orders_count:>=2

This returns customers whose most recent order predates the cutoff and who have ordered at least twice. Results are paginated, so keep the lapsed window tight on early runs to limit volume. Map the returned customer list to a variable such as {{ lapsed }}.

Step 4: Loop over each lapsed customer and pull their orders

Add a Loop node in ForEach mode over the customer list from Step 3. Inside the loop body, add a Connector node in Direct mode on the Shopify connector using the list-orders tool to retrieve that customer's purchase history. Filter by the loop item's customer id and to paid orders only:

customer_id:{{ item.id }} AND financial_status:paid

Optionally add a Condition node at the top of the loop body so you skip customers who have no usable history (for example fewer than 2 paid orders), which keeps the AI step from drafting on thin data. This is also where you would add a guard to avoid re-emailing: gate the send on a value such as a Shopify customer tag or metafield that you set after sending, so a customer is only contacted once per campaign.

Step 5: Draft the personalized win-back email with Agent mode

Inside the loop, add a Connector node in Agent mode. Agent mode lets the agent reason over the order history and produce structured output. Give it a prompt that passes the customer and their orders, and define a Response Schema so the output is reliable JSON your Resend step can map directly. A workable prompt:

You are writing a short win-back email for a lapsed customer of our store.
Customer: {{ item.first_name }} {{ item.last_name }}
Past orders: {{ orders }}
Reference the specific products they bought, acknowledge it has been a while,
keep it warm and under 120 words, and end with one clear call to return.
Return a JSON object with fields: subject, html, text.

Set the Response Schema to require subject, html, and text string fields. Store the result, for example as {{ draft }}. Because Agent mode runs once per loop iteration, this is the step that consumes AI credits per customer, so the lapsed query in Step 3 directly controls your cost.

Step 6: Send the email through Resend

Still inside the loop, add a Connector node in Direct mode on the Resend connector and pick the send-email tool. Map the fields from the customer and the generated draft:

from: Your Store <hello@yourdomain.com>
to: {{ item.email }}
subject: {{ draft.subject }}
html: {{ draft.html }}
text: {{ draft.text }}
reply_to: support@yourdomain.com

The from address must be on your verified Resend domain. Sending one email per loop iteration keeps each message fully personalized. If you prefer to batch, Resend also exposes send-batch-emails, which takes a list of email objects using the same fields. If you would rather send from Spojit's built-in mail service instead of your own domain, you could swap this step for a Send Email node, but Resend is the right choice when deliverability from your brand domain matters.

Tips

  • Keep the Step 3 lapsed window narrow at first (for example 90 to 120 days) so each run emails a manageable, well-defined set and your AI credit spend stays predictable.
  • Ask Miraxa to scaffold this for you with a prompt like "Build a workflow on a Schedule trigger that lists lapsed Shopify customers, loops over them, drafts a win-back email in Agent mode, and sends it with the Resend send-email tool", then fine-tune each node in the properties panel.
  • Use the Agent-mode Response Schema to force subject, html, and text fields so the Resend mapping never breaks on free-form output.
  • Add tags on the Resend send (campaign name) so you can measure win-back performance separately from transactional mail.

Common Pitfalls

  • Re-emailing the same people every run. The workflow is stateless, so without a guard (a tag, metafield, or a tighter window) the same lapsed customer is contacted on each schedule. Set and check a "win-back sent" marker as described in Step 4.
  • Unverified Resend domain. Sends from an unverified domain are rejected. Confirm the domain shows as verified before going live.
  • Timezone drift. The cron expression runs in the IANA timezone you set, not your browser's. Double-check the timezone in the Schedule trigger so the run does not fire overnight.
  • Shopify pagination. Both list-customers and list-orders return paginated results. On a large store, broaden cautiously and confirm you are reading the full set before trusting the lapsed count.

Testing

Before turning on the schedule, point the Step 6 to field at your own inbox and tighten the Step 3 query to a single known customer (for example by adding email:you@yourdomain.com). Run the workflow once from the designer and watch the execution logs: confirm the cutoff date is correct, the customer and orders resolve, the Agent-mode draft returns clean subject, html, and text values, and the Resend send succeeds. Once a single end-to-end pass looks right, restore your real lapsed query and enable the Schedule trigger.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.