Every 10 minutes
Log PDF invoices from Gmail in a spreadsheet
Every invoice that arrives by email is added as a row in your Invoices sheet with supplier, date, number and total.
- Runs
- Every 10 minutes
- Apps
- Gmail, Google Sheets
- AI
- Yes, uses the built-in AI allowance
- Access
- Gmail gmail.modify; Sheets read+write
Send this to your assistant
Create a ClickRuntime automation: watch my Gmail for emails with PDF invoices, pull out supplier, date, invoice number and total, and add a row to my Invoices sheet.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
The owner of a small design studio gets invoices from software vendors, freelancers and printers, all as PDF attachments in her inbox. At the end of each month she opens every one, types the totals into a spreadsheet for her bookkeeper, and still misses a few that were buried under newsletters.
Logging each invoice as it arrives gives you a complete list of what you owe and a tidy record for your accountant, without opening a single PDF. Freelancers, small businesses and office managers use it to keep their books up to date through the month instead of catching up at the end.
What you get out of it
Month-end takes minutes, not an afternoon
The sheet already holds every invoice, so preparing for the bookkeeper is a matter of checking the list rather than building it.
Fewer missed invoices
Invoices are picked up as they arrive, even when the email is buried under other messages. Late fees from forgotten bills become rare.
Spending is visible as it happens
A running list of supplier totals shows where money goes each month, which helps when deciding which subscriptions to cut.
Your accountant gets a clean list
Supplier, date, number and total in consistent columns is exactly what a bookkeeper needs to reconcile payments.
How it works
What happens, step by step
Every few minutes ClickRuntime checks your Gmail for new emails with a PDF attachment.
It skips emails it has already handled, which it marks with a Gmail label.
AI reads the invoice and picks out the supplier, date, invoice number and total.
A new row with those details is added to your Invoices sheet.
Before it runs live
- Connect Google through your own Google app (a one-time, 10-minute setup), so it works with your own Gmail
- Connect your Google Sheets account and pick the spreadsheets it may use
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Act only on the items that match your own rules, and skip the rest
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Slack
- Combine it with other Gmail and Google Sheets steps into one automation
Under the hood
The code that runs this automation
import base64, io
from pypdf import PdfReader
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, ai, report_fetched
SHEET_ID, LABEL_ID = "your-spreadsheet-id", "Label_Invoices"
SCHEMA = {"type": "object", "properties": {k: {"type": "string"} for k in ["supplier", "date", "number", "total"]}}
@on_trigger
def run(event):
creds = Credentials(credentials.connection("google", "work"))
gmail, sheets = build("gmail", "v1", credentials=creds, cache_discovery=False), build("sheets", "v4", credentials=creds, cache_discovery=False)
msgs = gmail.users().messages().list(userId="me", q="has:attachment filename:pdf -label:invoices-logged newer_than:7d").execute().get("messages", [])
report_fetched(len(msgs))
if not msgs:
return {"summary": "Nothing new"}
for m in msgs:
msg = gmail.users().messages().get(userId="me", id=m["id"]).execute()
part = next(p for p in msg["payload"].get("parts", []) if p.get("filename", "").lower().endswith(".pdf"))
data = gmail.users().messages().attachments().get(userId="me", messageId=m["id"], id=part["body"]["attachmentId"]).execute()["data"]
text = "".join(p.extract_text() or "" for p in PdfReader(io.BytesIO(base64.urlsafe_b64decode(data))).pages)[:6000]
f = ai.generate(f"Extract supplier, date, invoice number and total from this invoice:\n{text}", json_schema=SCHEMA, max_output_tokens=150).json
sheets.spreadsheets().values().append(spreadsheetId=SHEET_ID, range="Invoices!A:D", valueInputOption="USER_ENTERED",
body={"values": [[f.get("supplier"), f.get("date"), f.get("number"), f.get("total")]]}).execute()
gmail.users().messages().modify(userId="me", id=m["id"], body={"addLabelIds": [LABEL_ID]}).execute()
return {"logged": len(msgs)}FAQ
Common questions
Which emails does it look at?
What if an invoice has no clear total?
Can it save the PDF too?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Reply to chosen senders with AI and log every exchange
When someone on your list emails you, they get a prompt reply written by AI, and each email and reply is logged in a Google Sheet.
See how it worksScore new leads in a sheet and email the best ones
Each new lead in your sheet gets a score and a reason, and you get an email with a suggested first message for any strong one.
See how it worksLog TradingView alert emails to a Google Sheet
Every TradingView alert email becomes a row in your Signals sheet with the ticker, buy or sell signal and price.
See how it worksKeep exploring
Set up “Log PDF invoices from Gmail in a spreadsheet” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.