Auto-forward receipts to your accountant
Route anything that looks like a receipt to a fixed address on a monthly schedule.
Published Jun 16, 2026
Receipts arrive all month — a software renewal here, a courier invoice there, a hardware order somewhere in between. If someone at Northwind forwards each one to the accountant as it lands, the accountant’s inbox fills with noise and the odd receipt still slips through. Batching them into a single monthly digest is calmer for everyone, but doing that by hand means trawling a month of mail.
This script does the trawl for you. Once a month it searches your inbox for threads that carry an attachment and look like a receipt, forwards each one to a fixed accountant address, and labels it so the next run never forwards it twice. It is a small automation, but it turns a recurring chore into something you never think about.
What you’ll need
- A Gmail account that receives the receipts — this runs as you, so it must be the inbox the receipts land in.
- Your accountant’s email address.
- Nothing to set up in advance: the script creates the
receipts/forwardedlabel itself on the first run.
The script
// Where every receipt gets forwarded.
const ACCOUNTANT = '[email protected]';
// Words in a subject line that suggest the message is a receipt. Tune this
// for the vendors you actually buy from — see "Watch out for".
const HINTS = /\b(receipt|invoice|order confirmation|payment)\b/i;
// The label that marks a thread as already sent, so it is never forwarded
// twice on the next run.
const FORWARDED_LABEL = 'receipts/forwarded';
/**
* Finds recent threads with attachments that look like receipts, forwards
* each one to the accountant, and labels it so it is not picked up again.
* Designed to run once a month.
*/
function monthlyReceiptForward() {
// 1. Search the last 35 days for threads that carry an attachment and
// have not already been forwarded. 35 days gives a little overlap so
// nothing falls between two monthly runs.
const threads = GmailApp.search(
'newer_than:35d has:attachment -label:' + FORWARDED_LABEL
);
if (!threads.length) {
Logger.log('No candidate threads found — nothing to forward.');
return;
}
// 2. Get the "forwarded" label, creating it the first time the script runs.
const forwarded = GmailApp.getUserLabelByName(FORWARDED_LABEL)
|| GmailApp.createLabel(FORWARDED_LABEL);
// 3. Walk each thread and forward the ones that look like receipts.
let sent = 0;
for (const thread of threads) {
const msg = thread.getMessages()[0];
// Skip anything whose subject does not match the receipt hints.
if (!HINTS.test(msg.getSubject())) continue;
// Forward the message (attachments included) and mark the thread done.
msg.forward(ACCOUNTANT);
thread.addLabel(forwarded);
sent++;
}
Logger.log('Forwarded ' + sent + ' receipt(s) to ' + ACCOUNTANT + '.');
}
How it works
monthlyReceiptForwardsearches your inbox for threads from the last 35 days that have an attachment and do not already carry thereceipts/forwardedlabel. The 35-day window deliberately overlaps the month so nothing is missed between two scheduled runs.- If the search returns nothing, it logs a message and stops.
- It looks up the
receipts/forwardedlabel, creating it the first time the script runs so there is no manual setup. - For each thread it takes the first message and tests its subject line against
HINTS— a regular expression matching words like receipt, invoice and payment. Anything that does not match is skipped, which is what keeps personal mail out of the accountant’s inbox. - Matching messages are forwarded with
msg.forward, which carries the attachments along. The thread is then labelled so the next run ignores it. - It logs how many receipts were sent.
Example run
Say the inbox picked up these four threads over the last month:
| Subject | Has attachment | Forwarded? |
|---|---|---|
| Your receipt from Figma | Yes | Yes — matches “receipt” |
| Invoice #4471 — Couriers Ltd | Yes | Yes — matches “invoice” |
| Lunch photos | Yes | No — subject does not match |
| Order confirmation: 2× monitors | Yes | Yes — matches “order confirmation” |
After the run, the accountant receives three forwarded messages — the Figma
receipt, the courier invoice and the monitor order — each with its original
attachment. All three threads gain the receipts/forwarded label, so next
month’s run starts fresh and skips them.
Trigger it
Run this once a month so the accountant gets a single, predictable batch:
- In the Apps Script editor, open Triggers (the clock icon).
- Click Add Trigger.
- Choose the
monthlyReceiptForwardfunction, an event source of Time-driven, a Month timer, day 1 of month, and a time of 9am to 10am. - Save and approve the authorisation prompt.
Watch out for
- The filter is intentionally tight.
HINTSonly matches a handful of words, which avoids forwarding personal mail but also means a vendor with an unusual subject line (“Thanks for your order” with no other keyword) will be skipped. Add their wording to the regular expression as you spot gaps. - It checks the first message of each thread only. If a receipt arrives as a reply deep in an existing thread, the subject test runs against the original message, not the receipt — rare, but worth knowing.
- Threads are matched on attachments. A receipt delivered as inline text with no attachment will not be picked up; this automation is built for the common case of a PDF or image attached.
- Gmail caps how many messages you can send per day. Forwarding a normal month of receipts is well within the limit, but a first run over a large, unlabelled backlog could hit it — clear the backlog in smaller passes if so.
Related
Auto-file quotes and proposals you receive
Detect inbound proposal PDFs and store them in Drive by client.
Updated Jun 13, 2026
Forward attachments to Drive and reply with the link
Strip large attachments out of incoming threads, save them to Drive, and reply with the link.
Updated Jun 9, 2026
Convert long email threads into a summary note
Collapse a thread's history into a Doc for handover — perfect for client transitions or vacation cover.
Updated Jun 6, 2026
Pull event RSVPs from emails into a Sheet
Parse yes/no replies to event invites and tally attendance automatically.
Updated Jun 2, 2026
Turn forwarded emails into project tasks
Forward to [email protected] and a row lands in the Projects sheet under the right client.
Updated May 30, 2026