3 ways we automate our inboxes at Exhale Operations
The exact setup and prompts behind three inbox automations we run, so you can stop being the one who has to touch every email.
Your inbox can actually help you get stuff done.
I hope this peak into our systems can provide inspirations for the ways you can leverage your inbox to actually be more productive in your business. (Yes, there’s a world where your inbox isn’t the bane of your existence.)
I’m sharing blinded versions of real prompts from my system. I hope it goes without saying that if your system is set up differently, there may be some adaptation required. (Of course, if you don’t want to manage this yourself, hit a girl up and let’s talk about how Exhale could help.)
Automation 1Expense & revenue tracking
What it does: Regularly scans my inbox for new transactions (expenses or revenue), categorizes the charge and adds it to my bookkeeping spreadsheet to be ready for my weekly review
Why it matters: Opening up the accounts, logging data and categorizing use to take me at least 90 minutes per week, now down to 10 minutes of review
What has to exist first:
A credit card alert and a bank feed alert, set up to land in a standard place in your email (I use an inbox filter so they don’t cloud my inbox and the folder is only used to house these notifications)
A tracker spreadsheet the data will be logged in
A Claude account and connectors set up to be able to pull all these sources
How the automation works:
Because revenue notifications come from my bank account and expenses from my credit card, the automation is able to differentiate between the the two types based on email sender. Then Claude interprets the email based on pre-established set of rules to identify the likely category, based on how I separate the expenses and then logs the data in a new row in the spreadsheet. There’s an important fail safe to check for duplicate charges to avoid any automation loops that would burn my credits.
Note: this automation relies on a custom python script which has to run on your machine. Your Claude will be able to help you build one specifically tied to the way your tracking spreadsheet is built (or reach out to Exhale for support).
And now for the prompt itself (this will likely require some customization based on the details of your system setup)…
You are running the daily bookkeeper automation for [my name]. Process emails labeled [my Gmail label (I use "bookkeeping")] and append transactions to [my tracker sheet] using write_transaction.py.
There are TWO independent transaction sources that both land in the same [my label] Gmail label, and you must route each email to the correct pipeline based on which field appears in its body:
- Emails containing "Merchant:" → EXPENSE pipeline (credit card charge alerts)
- Emails containing "Description:" → REVENUE pipeline (business checking account feed: deposits, income, internal transfers)
Do not guess which pipeline applies from the sender address alone. Check for the field name in the body, since that is the reliable signal.
## Step 0: Verify folder access (do this first)
This task can run either in a Cowork sandbox (Dropbox mounted at [your finance folder, mounted path]) or directly on your machine (Dropbox at [path to your finance folder]). Resolve which one applies and remember the resolved path as FINANCE_DIR for use in Step 3.
if [ -d "$HOME/mnt/[your finance folder]" ]; then
FINANCE_DIR="$HOME/mnt/[your finance folder]"
else
FINANCE_DIR="$HOME/Dropbox/[path to your finance folder]"
fi
ls -la "$FINANCE_DIR/transaction-transfer/write_transaction.py"
ls -la "$FINANCE_DIR/weekly-stats/[your Google OAuth token file]"
If either is missing, STOP and report that the folder mount is missing or misconfigured. Don't proceed.
Install Python dependencies if needed:
pip install gspread google-auth google-auth-oauthlib --break-system-packages --quiet
## Step 1: Search for labeled emails
Search [my email] for emails with the [my label] label. Do not check any other connected Gmail accounts, since this label only exists on the primary business account. Process recent emails (last 24 to 48 hours, or unread) to avoid reprocessing. For each email, get the email ID, sender, subject, full plain text body, and received date.
If no emails are found, log "No emails to process" and end.
## Step 2: Determine pipeline and extract fields
**If it contains "Merchant:" → EXPENSE pipeline.** Extract:
- Vendor: text after "Merchant:" (keep exactly as-is, including any prefixes)
- Amount: numeric value after "Amount:" (no $ sign, exactly as it appears. Do NOT invert the sign yourself)
- Date: text after "Date:" → convert to YYYY-MM-DD
- Sender: the email's from address
- Body: the full email body text
**If it contains "Description:" → REVENUE pipeline.** Extract:
- Description: text after "Description:" (keep exactly as-is)
- Amount: numeric value after "Amount:", keeping the sign exactly as it appears (this pipeline does NOT invert signs: positive = money in, negative = money out)
- Date: text after "Date:" → convert to YYYY-MM-DD
If a required field is missing or unparseable, skip that email and log it as an extraction error.
## Step 3: Call the write script
For expense pipeline emails:
cd "$FINANCE_DIR/transaction-transfer"
python3 write_transaction.py --type expense --label "$VENDOR" --amount "$AMOUNT" --date "$DATE" --sender "$SENDER_EMAIL" --body "$EMAIL_BODY" --email-id "$EMAIL_ID"
For revenue pipeline emails:
cd "$FINANCE_DIR/transaction-transfer"
python3 write_transaction.py --type revenue --label "$DESCRIPTION" --amount "$AMOUNT" --date "$DATE" --email-id "$EMAIL_ID"
The script handles all categorization, sign handling (inverted for expense, not inverted for revenue), and duplicate detection itself. Do not attempt to categorize, invert signs, or pre-format amounts yourself. Just extract and pass through.
The script returns a status: added, skipped, flagged (duplicate risk), needs_review (no category rule matched), or error.
## Step 4: Log results and give me a summary
For each transaction, note its status. At the end, give me a short summary: emails processed, how many added, flagged as duplicates, needing manual categorization, skipped, and any errors, plus anything that needs my attention.
Leave the processed emails in the label. Don't archive or delete them. If the script fails for one transaction, log that one as an error and keep going with the rest.
Automation 2New client kickoff brief
What it does: When a new client books their kickoff call for the start of our engagement, the system aggregates the notes across my system to give me a consolidated briefing so I can come prepared for the call with no prep time.
Why it matters: I am able to prep for a call in under an hour and give the best first impression for a client, which sets the tone for the entire relationship
What has to exist first:
A standardized onboarding form for a client that collects data and generates a report in a consistent format for the automation to find
A consistent place for notes from discovery calls to be saved where my system can access them (My notes from Granola are automatically added to my Notion each day)
A scheduling link for booking kickoff calls that guarantees consistent naming for these calls so the system knows when to kickoff (and doesn’t trigger for a normal client call)
A Claude account and connectors set up to be able to pull all these sources
How the automation works:
Every new client's onboarding form gives their kickoff call a standardized meeting name, so it always matches on the way back through. Each night, Claude checks for a meeting with that name scheduled since the last run. When it finds one, it pulls the sales call notes (already transferred over from Granola into Notion), every email thread with that client including their intake form response, and the scope I saved for them, then compiles it all into one brief and drops it into Notion for me to read before the call.
You are running the nightly kickoff-brief automation. Your job is to find newly booked kickoff calls and prepare a brief before I need it.
## Step 0: Verify access
Confirm you can reach [YOUR EMAIL ACCOUNT], [YOUR NOTION SALES NOTES DATABASE], and [YOUR CLIENT BRIEFS DATABASE]. If any of the three isn't reachable, stop and report which one, rather than running partway.
## Step 1: Find new kickoff calls
Check for any meeting titled "[YOUR STANDARDIZED KICKOFF NAME, e.g. "Kickoff Call: {Client Name}"]" scheduled since your last run. Pull the client's name from the meeting title.
Check [YOUR CLIENT BRIEFS DATABASE] first to confirm a brief doesn't already exist for this client and call date. If one does, skip it. Don't create a duplicate.
If no new kickoff calls are found, log "No new kickoff calls" and end.
## Step 2: Gather the four sources
For the client on each new call, pull:
1. Sales call notes from [YOUR NOTION SALES NOTES DATABASE]
2. Every email thread with that client, including their intake form response
3. The saved scope of work from [WHERE YOUR SCOPE DOCS LIVE]
4. Anything already in [YOUR CLIENT BRIEFS DATABASE] for this client from a prior engagement, if any
If a source can't be found, don't leave that section blank or guess at what it might have said. Note it directly under that section as "Not found."
## Step 3: Compile the brief using this template
Title: [Client Name], Kickoff Brief, [Call Date]
Sources found: [X/4]
### Scope Summary
[Core deliverables and the engagement's start and end dates, pulled from the scope of work. "Not found" if missing.]
### Their Problem
[Aggregate across the sales call notes, email threads, and intake form to summarize the issue they say they're having, in their own words where possible. Note it directly if the sources describe the problem differently from each other.]
### Desired Outcome
[Aggregate across the same sources to summarize what they want to be true, or look different, once this engagement is done.]
### Flags for the Call
[Anything worth raising before the call: a mismatch between the sales conversation and the intake form, a scope item without a clear owner, a returning client with unresolved history, or a blind spot, something that matters to this engagement but isn't addressed anywhere in the four sources, worth asking about directly. "None" if there's nothing to flag, don't invent one to fill the section.]
### Hesitations to Address
[Any doubts, objections, or fears about the work that came up across the sources, so you know what to reassure them on going into the call. "None noted" if nothing surfaced.]
## Step 4: Create the brief
Create the brief as a new page in [YOUR CLIENT BRIEFS DATABASE], titled with the client's name and the call date.
## Step 5: Give me a summary
KICKOFF BRIEF SUMMARY
New calls found: [N]
Briefs created: [N]
Sources missing (by client): [list, or "None"]
Needs your attention: [list any flags raised in Step 3, or "None"]
Automation 3CRM that updates itself
What it does: ensures my CRM stays up to date by capturing any outreach or communications with past or potential future clients that I might not have manually logged.
Why it matters: while I typically log these things myself when I’ve communicated with someone, this automation gives me peace of mind that I will always have up to date tracking of my last communication. This makes my CRM more useful to me because the data stays up to date.
What has to exist first:
A CRM or tracker that already exists, with a field for last contacted and accurate names/emails for each contact (Notion, in my case, but the logic holds for any database Claude can read and write to)
A Claude account and connectors set up to be able to pull all these sources
How it works: Every night a scheduled task scans my outbound messages for emails to any contact in my CRM (with filters). Anything that matches gets its last-contacted date updated automatically, so the tracker stays accurate even on the nights I forget to touch it myself.
You are running the nightly CRM update automation. Your job is to keep "Last Contacted" accurate without me logging it myself.
## Step 0: Verify access
Confirm you can reach [YOUR EMAIL ACCOUNT] and [LINK TO YOUR CRM DATABASE]. If either isn't reachable, stop and report which one, rather than running partway.
## Step 1: Scan sent mail
Scan the sent folder of [YOUR EMAIL ACCOUNT] for anything sent since your last successful run.
If nothing was sent, log "No sent mail since last run" and end.
## Step 2: Match against the CRM
For each sent email, check the recipient's name and email address against [LINK TO YOUR CRM DATABASE].
- **Exact match (name and email both line up with one contact):** proceed to Step 2a.
- **No match at all:** don't add the recipient automatically. Hold them for the summary instead.
- **Ambiguous match (could reasonably be more than one contact, e.g. two contacts associated with same email, same first and last name exist at two companies):** don't guess. Hold them for the summary instead, using the flag format below.
## Step 2a: Confirm contact Status
For each exact match, review the Type: field of the database. If the status says "Signed" or "Active Client", do not continue. If the Type: field contains anything else, continue to Step 3.
## Step 3: Update matched contacts
For each exact match, update their "Last Contacted" field to today's date. If the write itself fails for one contact, log that one as an error and keep going with the rest, don't stop the whole run over it.
## Step 4: Give me a summary, using this format
CRM UPDATE SUMMARY
Emails scanned: [N]
Contacts updated: [N]
Unmatched senders: [N]
Ambiguous matches flagged: [N]
Errors: [N]
Updated:
[Contact name, updated to today's date]
Needs your attention:
Contact: [name or email]
Reason: [unmatched sender / ambiguous match / write error]
Details: [context, e.g. possible matches: Contact A, Contact B]
(repeat the block above for each item that needs attention, or write "None" if there isn't one)
What I setup before automating anything
It can feel tempting to immediately jump to automations. But ultimately, automations are only as useful as the data they leverage. The three automations I’m going to share sit on top of existing connections and systems. Nothing crazy, to be clear, but it’s important context for what it takes for these types of systems to work.
(If you read the below and immediately get overwhelmed with what you don’t have built, know that this is the foundational part of what Exhale does for many clients, so these systems and connections get built without you having to navigate all the technical. If that sounds like a relief, book a discovery call and we can chat more about your needs. No sleazy sales pitch, just a conversation.)
Systems that the automations rely on
An existing system for bookkeeping and financial tracking (in my case, because I work with a small number of clients at a time vs. a high volume product business, I manage this with my own spreadsheet hosted on Google Sheets, tracking my two business credit cards and one business bank account)
A CRM or contact tracker with accurate names and emails already in it (you cannot automate tracking people in your business if you don’t have a way to capture the information; similarly, because my business is relatively low volume, I manage this in a CRM I built for myself in Notion)
An intake process for new clients (before you can automate any sort of prep around client intake, you have to have steps to this process manually) that are captured somewhere
Claude and it’s connectors
Claude is my LLM of choice and I’m a frequent user of Cowork on the desktop app. I do pay for the Pro subscription but most, if not all, of what I setup here could be done on a free plan pending usage limitations
Claude is connected to my main work inbox, in my case via Gmail. Important: the native connector holds one account. If you work out of more than one inbox, the second needs its own connection set up through Google's own API, not the native connector.
And Claude is connected to my knowledge management system, in my case Notion, which is where my call notes, CRM, and many general guidelines live. If you have CRM in a separate system, Claude needs a path to both.
A custom Google Cloud connection or Zapier subscription
Google Sheets isn't something the native connectors write to reliably but in order to build my bookkeeping automation, I needed a way to get data from my inbox safely into my spreadsheet. My first method to do this was a Zapier subscription, which routed information via triggered automation in controlled, predictable ways. Then I figured out how to build a custom Google Cloud integration that allowed me to write directly to a sheet from a Claude scheduled task.
If you’re already using Claude for substantial parts of your workflow, the custom Google Cloud connection is at no extra cost.
If you'd rather not build it yourself…
This is the exact setup behind three things that run in my business without me touching them. If you'd rather hand the whole thing to someone else, that's the kind of system building Exhale does for clients.