Built an AI Email Support Agent for Shopify with n8n + Claude + Outlook

Hey everyone :waving_hand:

Sharing another build. This one’s been quietly handling customer support emails for a Shopify store for a few weeks now and I’m pretty happy with how it turned out.

It’s an AI agent that reads incoming support emails, figures out what the customer actually wants, talks to Shopify on their behalf, and writes a personalized reply, all without a human in the loop (unless the AI isn’t confident enough, in which case it punts to a human).

What it does

Every email that lands in the support inbox gets routed through this workflow. The agent can handle:

  • :package: Order tracking: “Where’s my order?”

  • :house: Address changes: “Can I change my shipping address?”

  • :red_question_mark: General Q&A: “Do you ship to Canada?”

  • :globe_with_meridians: Website Q&A: “What’s your return policy?”

  • :prohibited: Spam / irrelevant: silently ignored

For each intent, the agent gathers the right context (Shopify order data, website FAQ content, etc.) and composes a reply that actually answers the customer’s question.

The architecture

Outlook Trigger (new email)
   → Parse Email Data
   → Claude: Intent Classifier
   → Extract Intent & Email Data
   → Route by Intent (switch)
       ├── Tracking
       ├── Address Change
       ├── General Q&A
       ├── Website Q&A
       └── Irrelevant → ignore

Each branch has its own little sub-workflow. Then everything funnels back into a Merge → Prepare Final Reply → Send via Outlook at the end.

Branch 1: Tracking :package:

Extract Order Number from email body
   → Order Number Found?
       ├── No  → "Hey, can you share your order number?" reply
       └── Yes → Shopify Get Order
                  → Parse Tracking Info
                  → Claude composes a friendly tracking reply

The Claude reply isn’t just a tracking link dump. It includes the carrier, estimated delivery window, and a personalized tone based on the original email.

Branch 2: Address Change :house:

This is the branch I’m most proud of, because it actually does something useful:

Extract Order Number
   → Order Number Found?
       ├── No  → "Please share your order number" reply
       └── Yes → Shopify Get Order
                  → Check Order Fulfillment Status
                  → Can Address Be Changed?
                      ├── Yes (not shipped yet)
                      │     → Claude extracts new address from email body
                      │     → Shopify Update Address API call
                      │     → Claude writes a confirmation reply
                      └── No (already shipped)
                            → Claude explains it's too late, offers alternatives

So if a customer emails saying “please change my shipping address to X,” and the order hasn’t been fulfilled yet, the agent literally updates the address in Shopify and replies confirming the change. No human touches it.

If the order already shipped, it gracefully explains why it can’t change anything and suggests contacting the carrier.

Branch 3: General Q&A :red_question_mark:

Claude: General Q&A → Parse Response & Confidence
   → Confident Enough for Reply?
       ├── Yes → send reply directly
       └── No  → flag as "pending human review"

This is the confidence-gating pattern. Claude returns both an answer and a confidence score (I prompt it to be self-critical). Below a threshold, the email is parked for a human instead of letting the bot guess.

Branch 4: Website Q&A :globe_with_meridians:

Website Q&A node → Code Node (parse response) → reply

This branch pulls from the store’s FAQ/policy pages so the agent can answer questions like “what’s your return window?” without me hardcoding those answers in a prompt.

Final assembly

All branches converge:

Merge: Prepare Final Reply
   → Reply to message (Outlook)
   → Update message (mark as handled)
   → AI Replied Email (log/notify)

Tech stack

Layer Tool
Orchestration n8n
Email Microsoft Outlook (trigger + reply)
LLM Claude (Anthropic), for intent classification & reply composition
Store data Shopify Admin API
Routing n8n Switch nodes

Lessons learned

A few things worth sharing:

  • Separate “classify” from “compose.” Early on I tried to make Claude both classify the intent and write the reply in one prompt. It worked, but accuracy on intent dropped. Splitting it into a small, focused classifier call followed by intent-specific composer calls made the whole thing way more reliable.

  • Confidence scores are gold. Asking the model to self-rate (“how confident are you in this answer, 0–1?”) and gating on it gave me a clean escalation path. If you don’t gate, the bot will confidently make stuff up about your return policy.

  • Always have a “pending” path. Every branch has a fallback for missing info (no order number, low confidence, etc.). The fallback doesn’t reply with an answer. It replies asking for what’s missing, or tags the email for a human. This is how you stay safe in production.

  • Use the Merge node properly. I wasted hours trying to chain branches sequentially before I realized Merge handles “many paths → one final step” cleanly.

  • Outlook’s “Update Message” is underrated. Marking emails as read / categorized once handled keeps the inbox clean and gives me an audit trail of what the AI touched.

Results so far

Roughly 70% of emails are now fully handled by the agent (mostly tracking and simple Q&A). Address changes work end-to-end whenever the order hasn’t shipped. The remaining ~30% get tagged for a human, which is a huge time save vs. answering every email manually.

What’s next

  • Multi-language support (Claude is already great at this, just need to detect language earlier in the flow)

  • Refund request intent (more complex, needs eligibility logic)

  • A Slack notification when an order goes “pending human review” so we don’t miss anything


Happy to answer questions about any branch. The address change flow especially has a few gotchas around Shopify’s fulfillment status field that took me a while to figure out. Drop a comment if you want me to write up that part in more detail.

Cheers :victory_hand:

3 Likes

Do you have metrics on how much time this actually saves? I guess it would be pretty directly linear to the quantity of emails you’re getting on a daily basis, but for me, stuff like this is less about minutes/hours saved doing the task, rather the hours/days it saves the customer in not having to wait for me to check my email and process their refund.