Turn vendor invoice emails into draft bills in Xero
Every 30 minutes, this agent reads new supplier invoice emails in Gmail, drafts the bill in Xero, and asks for approval in Slack.
Build me an agent workflow that ingests vendor invoice emails from Gmail and turns them into draft bills in Xero with a Slack approval card. Run it on a cron schedule every 30 minutes.
On each run the agent should: (1) Call Gmail List Messages with a query that filters to a configurable label (default: vendor-invoices) and excludes any message that already carries the processed label (default: processed-to-xero). Make the label names configurable. (2) For each new message, call Gmail Get a Message with full detail level to retrieve the email body, headers, and any PDF attachments.
Use the model to extract the following fields from the email body and any PDF attachments: vendor name, vendor email or domain, invoice number, issue date, due date, currency, subtotal, tax amount, total amount, and line items (description, quantity, unit price, line total, and tax rate if present). Include a short confidence note describing how clean the extraction was and which field, if any, looked uncertain.
Then ensure the supplier exists in Xero. Look up the contact by vendor name (and email if available). If no match exists, call Xero Create Contacts to create the supplier with IsSupplier=true and the email/domain on file. Take the resulting ContactID.
Call Xero Create Invoices with Type=ACCPAY, Status=DRAFT, the supplier ContactID, the extracted invoice number as InvoiceNumber, the issue date as Date, the due date as DueDate, the currency code, and the extracted line items mapped to LineItems (Description, Quantity, UnitAmount, and TaxAmount or TaxType where possible). Put the Gmail message permalink (https://mail.google.com/mail/u/0/#inbox/<messageId>) in the Reference field so reviewers can jump back to the source email from Xero.
After the bill is created, call Gmail Modify Message Labels on the original message to add the processed label (default: processed-to-xero) and remove UNREAD so the next run skips it. If the processed label does not exist yet, create it first.
Finally, post an approval card in Slack via Slack Send a Message to a configurable channel. The message should include: vendor name, invoice number, issue date, due date, currency, total amount, tax amount, a one-line summary of line items, a link to the draft bill in Xero, a link to the source Gmail message, and the AI confidence note. Make it clear the bill is in DRAFT and needs a human to approve in Xero before payment.
Configurable inputs: Gmail watch label, processed label, Slack approval channel, Xero organization (tenant) if the user has multiple, and an optional sender allowlist (only ingest messages from these domains). Skip and log any message where extraction fails or the total is missing, and do NOT apply the processed label in that case so a human can re-run it after fixing the source.
Additional information
What does this prompt do?
- Watches a Gmail label for new vendor invoice emails and PDF attachments.
- Reads each email and PDF to pull out the vendor, invoice number, dates, line items, tax, and total.
- Finds or creates the matching supplier in Xero, then drafts a bill with the line items and a link back to the original email.
- Marks the email as processed so it never gets billed twice, and posts a Slack approval card so a human signs off before payment.
What do I need to use this?
- A Gmail account with a label set up for incoming vendor invoices, for example vendor-invoices.
- A Xero organization where you can create supplier contacts and draft bills.
- A Slack workspace and a channel where the finance approver wants the approval card posted.
How can I customize it?
- Change which Gmail label the agent watches, or add filters like sender domain or subject keywords.
- Pick the Slack channel that gets the approval card, and tweak which fields show up on the card.
- Adjust the cadence. Every 30 minutes is the default, but hourly or twice a day works just as well for low-volume mailboxes.
Frequently asked questions
Will the bill be paid automatically?
What happens if the same invoice email arrives twice?
Does it read PDF attachments, or only the email body?
What if the supplier is not in Xero yet?
Can I see which email a Xero bill came from?
Stop hand-keying supplier bills into Xero.
Connect Gmail, Xero, and Slack once, and Geni turns every new vendor invoice email into a draft bill waiting for approval.