Novels of Scotland, software, and the space between. Author of the Wardstane Chronicles, the DI Cormac Buchan Investigations, and the Pondlife novels.
OutlookGnuCashOrders
GitHub · C#

OutlookGnuCashOrders

Turns Outlook order emails into GnuCash entries.

View on GitHub

Outlook GnuCash Orders

A real, installable Outlook add-in (C# / VSTO) — built on the same pattern as OutlookSpamPlugin — that detects order / receipt emails and captures them as GnuCash transactions. It adds a GnuCash Orders tab to the Outlook ribbon, watches new mail as it arrives, and can post balanced transactions directly into your GnuCash SQLite book (an OFX-file export is also available if you'd rather review each one in GnuCash's own import matcher first).

Platform: Classic Outlook for Windows (desktop). Like all VSTO add-ins, it does not run in the new Outlook, Outlook on the web, or Outlook for Mac.


How it works

new mail arrives ─▶ detect order ─▶ extract amount/date/merchant/order#
                                          │
                                          ▼
                            captured.tsv (per-user AppData)
                                          │
                       ┌──────────────────┴──────────────────┐
                 "Post to GnuCash"                     "Export OFX"
                       ▼                                     ▼
       direct SQLite write (backed up first,       orders.ofx ─▶ GnuCash:
       refuses if GnuCash has the book open)        File ▸ Import ▸ Import OFX/QFX

the moment it arrives. Shipping notices, refunds and marketing are demoted so they don't become transactions.

date (the email's received time), merchant, and order/reference number (Amazon's nnn-nnnnnnn-nnnnnnn order ID is matched directly, since Amazon's HTML often leaves invisible bidi formatting characters around the label that would otherwise break a plain "Order #" match — those characters are stripped everywhere, not just for Amazon). A best-effort item name is also picked up where the layout allows it, and shown in the transaction description/memo.

(and optional funding account). Anything unmatched lands in Expenses:Imported Orders funded from Imbalance-GBP for you to re-assign.

Message-ID is never processed twice (even if the extracted amount/order number come out slightly different between an auto-capture-on-arrival pass and a later Scan Inbox, e.g. because the body wasn't fully synced yet the first time), and a content-based key (order number, else a hash) catches the same order arriving in more than one email. posted and exported are tracked in captured.tsv as one combined "already sent to GnuCash" state — posting an order skips anything already exported, and exporting skips anything already posted, so the same order never lands in your book twice via the two different paths.

.gnucash SQLite file, takes a timestamped backup, refuses outright if GnuCash currently has it open (a non-empty gnclock table), then writes each order as its own balanced transaction (own commit per order, so one bad order never blocks the rest). Missing expense accounts are auto-created; missing funding accounts (real bank/credit accounts) never are — you create those in GnuCash yourself, and posting refuses with a clear error until you do.

still works, and won't re-export anything already posted directly.

The ribbon

A GnuCash Orders tab with these buttons:

Button Action
Capture Selected Detect and capture the order in the selected message(s)
Scan Inbox Sweep the whole Inbox and capture any orders found
Select GnuCash File... Pick the .gnucash file to post into (label shows the current one)
Post to GnuCash Write captured orders directly into your GnuCash SQLite book
Export OFX Write captured orders to orders.ofx for GnuCash import
View Captured Open the captured-orders list
Edit Rules Open rules.txt in Notepad
Edit Settings Open settings.txt in Notepad
Auto-capture: On/Off Capture from new mail automatically (label shows state)
Confirmations: On/Off Pop-up when an order is captured

Direct SQLite write vs. OFX

GnuCash is a desktop app with no live API and it locks its file while open, so GnuCashSqliteWriter.cs takes the same precautions a human would:

every time — a timestamped copy, never overwritten.

table while a book is open; if that table has any rows, posting throws instead of touching the file.

new Expenses:Shopping subcategory) are created automatically; missing funding accounts (a bank or credit card) are not — you must create those in GnuCash yourself first, so a mistyped rules.txt entry can't silently create a fake liability account.

independently, so if order #7 of 10 fails (say, an unrecognized funding account), orders 1–6 stay posted and 8–10 still get a chance.

If your book lives on OneDrive, pause syncing while posting (a live SQLite file mid-sync can corrupt) — or just use Export OFX instead, which never opens the book at all and lets you review everything in GnuCash's own import matcher.

The companion Python project OrderToGnuCash (in C:\Code\OrderToGnuCash) does the same two things (OFX export and direct SQLite write via piecash) for IMAP mailboxes instead of classic Outlook. The two projects are independent — this add-in doesn't depend on it, and vice versa.


Files it creates

All under %APPDATA%\OutlookGnuCashOrders\ (i.e. C:\Users\<you>\AppData\Roaming\OutlookGnuCashOrders\):

settings.txt     currency, GnuCash book path, OFX ids, default accounts, toggles
rules.txt        merchant -> account mapping (one rule per line)
captured.tsv     every captured order (dedup source of truth: posted + exported)
orders.ofx       the file you import into GnuCash (unless OfxOutput is set)
backups\         timestamped copy of your .gnucash file, taken before every direct write

GnuCashDbFile in settings.txt holds the path, but you don't need to edit it by hand — click Select GnuCash File... in the ribbon (or just click Post to GnuCash the first time; it'll prompt you) and pick your .gnucash file.

rules.txt format — match | ExpenseAccount | FundingAccount(optional):

amazon   | Expenses:Shopping        | Liabilities:Tesco Credit Card
screwfix | Expenses:Household:DIY   | Liabilities:Tesco Credit Card
uber     | Expenses:Travel

Install

Requires Visual Studio 2022 with the Office/SharePoint development workload, and .NET Framework 4.7.2+ (present on Windows 10/11). Pulls the System.Data.SQLite.Core NuGet package on first restore (needs network access once; cached afterward).

Quick install (PowerShell), with Outlook closed:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass   # if scripts are blocked
.\install.ps1

install.ps1 builds Release and registers the add-in for the current user under HKCU\Software\Microsoft\Office\Outlook\Addins\OutlookGnuCashOrders. Start Outlook and the GnuCash Orders tab appears. To remove: .\uninstall.ps1 (Outlook closed).

Or from Visual Studio

Open OutlookGnuCashOrders.sln, set Release, Build, then F5 to launch Outlook with the add-in loaded.

Manifest signing is enabled with a locally generated test certificate (OutlookGnuCashOrders_TemporaryKey.pfx) because the installed tooling requires it even for local |vstolocal loads. It's not for distribution — regenerate it under Project ▸ Properties ▸ Signing if you need your own.


Typical workflow

  1. Leave Auto-capture: On — orders are captured as mail arrives.

(Or click Scan Inbox to sweep what's already there.)

  1. Click Select GnuCash File... and pick your .gnucash file, once.
  2. Close GnuCash, then click Post to GnuCash. Captured orders are written

straight in as balanced transactions; re-check the popup for any that couldn't post (usually a funding account that doesn't exist yet).

  1. Prefer to review first? Export OFX still works: **File ▸ Import ▸ Import

OFX/QFX** in GnuCash, pick orders.ofx, and confirm in the matcher.


Notes & limitations

receipt layouts may need a rules.txt entry or a manual Capture Selected. Item name in particular is a best-effort guess (the first body line that doesn't look like a label/amount/address) and can be blank or occasionally wrong.

multi-currency orders are out of scope for this first version.

the expense and funding accounts to already share the order's currency — no currency conversion is attempted.


Project layout

OutlookGnuCashOrders.sln
OutlookGnuCashOrders.csproj
ThisAddIn.cs / .Designer.cs      Inbox hook + add-in lifecycle
Ribbon1.cs / Ribbon1.xml         the GnuCash Orders ribbon tab
OrderProcessor.cs                engine: process, scan, export, post, rules, settings
OrderExtractor.cs                detection + field extraction (regex)
OfxWriter.cs                     OFX 1.02 generation
GnuCashSqliteWriter.cs           direct SQLite write: backup, lock check, accounts, transactions
CapturedOrder.cs                 order model + idempotency key + TSV persistence
Properties/AssemblyInfo.cs
install.ps1 / uninstall.ps1

View OutlookGnuCashOrders on GitHub