Skip to content
Invoice and Receipt Extractor

Module 07 · business · intermediate

Solutions 07 · Invoice and Receipt Extractor

Exercise 1

In Clean Receipt, replace needs_review with:

{{
  (() => {
    const o = $json.output;
    const s = Number(o.subtotal ?? 0), t = Number(o.tax ?? 0), total = Number(o.total);
    const nan = [s, t, total].some(Number.isNaN);
    const mismatch = o.subtotal != null && Math.abs(s + t - total) > 0.02;
    return !o.total || !o.date || !o.vendor || nan || mismatch;
  })()
}}

To test without calling OpenAI: run once, then pin the Extract Receipt Data output (pin icon in the output panel) and edit total to a wrong value.

Exercise 2

Has PDF? (false) → IF "Is Image?" ─true→ OpenAI (Image → Analyze Image) → Parse JSON → Clean Receipt
                                    └false→ Respond 400
  • Is Image?: {{ Object.values($binary ?? {}).some(f => f.mimeType?.startsWith('image/')) }}
  • OpenAI node, resource Image, operation Analyze Image, input type Binary File, model gpt-5-mini, prompt: "Extract vendor, invoice_number, date (YYYY-MM-DD), currency (ISO), subtotal, tax, total, category (meals/travel/software/office/utilities/other), line_items [{description, quantity, amount}] from this receipt. Reply with JSON only. Use null for missing values."
  • Parse JSON (Edit Fields): output (Object) = {{ JSON.parse($json.content.replace(/```json|```/g, '')) }}. The exact output field name depends on the node version; check its output panel.

Clean Receipt reads $json.output, so both branches feed it unchanged.

Exercise 3

Add a Gmail Trigger: poll every minute, Filters → Label IDs: your Receipts label, Simplify off, Options → Download Attachments on. Connect it to Has PDF?. The expression Object.keys($binary).find(...) picks attachment_0 automatically.

Two fixes for the email path: Dry Run? reads $('Receipt API'), which didn't run. Change it to {{ $('Receipt API').isExecuted && $('Receipt API').item.json.query.dry_run === 'true' }}, and route the final Respond only for API calls (the Called via API? pattern from Module 02).