--- name: email-to-expense description: | Process emails from a Gmail label into work expenses. Opens Gmail via browser automation, iterates through emails in the "expense" label, saves each as PDF, extracts metadata, and logs them to MongoDB via the log-work-expense skill. Triggers when user mentions: - "process my expense emails" - "email to expense" - "triage my expense label" - "process expense label" --- # Email to Expense Pulls emails from Gmail's "expense" label, saves them as PDFs, extracts metadata, and inserts them into `wip.work_expenses`. ## Prerequisites - Browser tool available (`openclaw browser`) - User's Gmail must be logged in (use `profile="user"`) - `log-work-expense` skill scripts accessible at `~/notes/skills/log-work-expense/scripts/` ## Flow ### 1. Open Gmail with expense label Open Gmail filtered to the "expense" label using the user's browser profile: ``` URL: https://mail.google.com/mail/u/0/#label/expense ``` If the label name has spaces or special characters, URL-encode it. The label may also be accessed as "2 expense" — adjust accordingly. Take a snapshot to see how many emails are in the list. Note the email count. ### 2. Iterate through each email For each email in the label (oldest first to maintain order): 1. **Click the email** to open it 2. **Snapshot the open email** to extract metadata: - **Date** — from the email header (parse the displayed date string) - **Sender** — from the "From" field - **Subject** — from the subject line 3. **Save as PDF** — Use the browser's print-to-PDF functionality: - Use `action="pdf"` if available, or trigger `Ctrl+P` and save to a temp directory - Save to `/tmp/email_expense_.pdf` 4. **Upload PDF to S2** — Use the S2 upload endpoint from TOOLS.md: ```bash curl -X POST https://api.connorrhodes.com/agent/s2_upload \ -H "x-api-key: LT6CXiLT5cEApfqtThz17bENr6OLp804FepOMqa1tZkfTGXiiCcSFlupl6gaYeX" \ -F "file=@/tmp/email_expense_.pdf" ``` Collect the returned S2 URL. 5. **Return to the email list** — Go back to the label view ### 3. Classify each expense After collecting all emails, classify each one: **Known merchants (auto-classify):** | Sender / Keyword | Type | Default Account | |-------------------|------|-----------------| | DoorDash | meal | _(ask user)_ | | Uber Eats | meal | _(ask user)_ | | Amazon | other | _(ask user)_ | For unknown senders, **ask the user** to classify: - Type: `meal`, `mileage`, `other`, `professional-development`, `software`, etc. - Account: the work account to bill against ### 4. Insert into MongoDB For each classified email, run the existing log_expense.py script: ```bash uv run --with pymongo ~/notes/skills/log-work-expense/scripts/log_expense.py \ "" ``` - **type**: meal, mileage, or other - **account**: from classification step - **date**: parsed from the email header (YYYY-MM-DD format) - **note**: include sender and subject for context, e.g. "DoorDash - order confirmation" - **s2_url**: the uploaded PDF URL ### 5. Confirm Show a summary table of all processed expenses: - Sender | Date | Type | Account | Status ### 6. Cleanup - Remove local PDF files from `/tmp/` - Optionally archive/remove the processed label from Gmail (ask user first) ## Notes - Always ask the user to confirm before inserting expenses into the database - If an email doesn't look like an expense (no receipt, no order confirmation, etc.), skip it and note it - The Gmail label URL format: `https://mail.google.com/mail/u/0/#label/` - For labels with spaces, the URL typically uses the raw label name