What this workflow does
- New order email (Gmail Trigger) polls the orders mailbox every minute and downloads attachments.
- Pick order attachment (Code) assigns a tracking ID, prefers a PDF, falls back to an image over 30 KB so signature logos are ignored, and flags emails with nothing readable.
- Readable attachment? (If) sends emails without a usable file straight to Slack.
- Encode attachment (Extract from File) converts the file to base64.
- Build extraction request (Code) sends PDFs as document blocks and images as image blocks, alongside the email text.
- Extract order with Claude (HTTP Request) returns strict JSON: customer, PO number, ship-to, requested ship date and lines with customer part number, description, quantity, unit of measure and price. The prompt forbids converting units or guessing SKUs.
- Read part cross-reference and Read order log (Google Sheets) load your customer part mappings, unit factors, contract prices and past orders.
- Match and validate (Code) handles refusals and API errors, matches parts by cross-reference first and your own SKU second (never a model guess), converts units, and checks contract price, ship-to, quantities and duplicate PO numbers. Every problem gets a reason.
- Log order (Google Sheets) writes every order as
heldorexception. - Exception? (If) and Post order exception (Slack) send problems to reps with a link to the email.
Before you import
- A current n8n version and OAuth access to the orders mailbox.
- An Anthropic API key. Reading purchase orders uses
claude-opus-5-5. - A Google Sheet and a Slack bot in your exceptions channel.
Setup
- Import the JSON and connect the Gmail, Anthropic, Google Sheets and Slack credentials.
- Create a
Part xreftab with headers: customer_domain, customer_part, sku, uom_factor, contract_price.uom_factoris how many of your units one customer unit holds, for example 12 for a case of 12. - Create an
Order logtab with headers: tracking_id, received_at, from_email, customer_domain, customer_name, po_number, ship_to, requested_ship_date, line_count, order_total, lines_json, status, reasons, gmail_thread_id, file_name. - Replace
REPLACE_WITH_SHEET_IDon all three sheet nodes andREPLACE_WITH_SLACK_EXCEPTIONS_CHANNEL_ID. - Narrow the Gmail filter if the mailbox also receives non-order mail.
Test it
Email the mailbox three test POs from a customer domain in your cross-reference: one clean, one with a wrong price, and one reusing an earlier PO number. Add an email with only a signature logo. Expect one held row, two exception rows with reasons, and three Slack messages.
Make it production-ready
- Replace Log order with order creation in NetSuite, QuickBooks Online or your ERP, creating orders on hold for the first two or three weeks.
- Add credit-hold and stock checks against the ERP inside Match and validate.
- Turn on customer acknowledgments last, once entry is stable.
- Add an n8n error workflow, and move the cross-reference to Postgres when it grows past a few thousand rows.
- Spreadsheet POs need a CSV or XLSX branch with Extract from File before the model step.
Read the full guide on automating order processing for matching and release strategy, or ask Lumeor about legacy ERP integration.