- Install flow now assumes one admin-distributed service account JSON shared across the team. Each user creates their own Google Sheet and shares it with the SA email; per-user GCP project setup is gone. - DEPLOY.md: a step-by-step walkthrough for non-technical users following along with an AI agent (Terminal basics, screenshots-worth of expected output, common-error table). - scripts/append_row.py: sheet_id field accepts either a bare ID or a full Google Sheets URL; normalize_sheet_id() extracts the ID via regex. - scripts/setup.md: rewritten as an admin guide (one-time GCP setup, key rotation) plus a troubleshooting reference. - LICENSE: MIT (previously "private — internal use"). README license sections updated to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
4.8 KiB
name, description
| name | description |
|---|---|
| AutoACCT | Extract expense data from a receipt/invoice image (plus optional caption) and append it to a Google Sheet with HKD conversion. Use whenever the user provides a receipt image and wants it logged, or forwards a WhatsApp-style message that contains a receipt. |
AutoACCT — Receipt → Google Sheet
Default working language: English. All written output (row values, replies) is English unless the user explicitly requests otherwise.
When to use
- User provides a receipt / invoice / payment-screenshot image and wants it recorded.
- User says "log this", "record this expense", "add to AutoACCT", "记一下" with an image.
- Caption may be empty, or may add context (who paid, split %, category hint, payment method). Always incorporate caption if present.
Prerequisites (check once per session)
~/.openclaw/workspace/skills/AutoACCT/config.jsonexists. If onlyconfig.example.jsonis present, stop and tell the user to copy it and fill insheet_id,worksheet,service_account_path. Point them at the README install section.- Python deps installed:
google-api-python-client,google-auth. Ifappend_row.pyfails with ImportError, instruct the user to runpip install google-api-python-client google-authand retry.
Workflow
- Extract fields from the image using vision. Caption is auxiliary — never let caption override a legible receipt, but use it to fill gaps (category hint, note, payment method).
- Normalize per the rules below.
- Convert to HKD by running:
Output is
python ~/.openclaw/workspace/skills/AutoACCT/scripts/fx_convert.py <amount> <currency> --date <yyyy-mm-dd><hkd_amount>\t<fx_rate>\t<fx_date>(tab-separated). If currency is HKD, skip the call and setamount_hkd=amount,fx_rate=1,fx_date=<date>. - Append the row by piping JSON into:
Keys must match
echo '<json>' | python ~/.openclaw/workspace/skills/AutoACCT/scripts/append_row.pyschema.md(snake_case:date,merchant,category,amount,currency,amount_hkd,fx_rate,fx_date,payment_method,line_items,raw_ocr,note,receipt). Script addslogged_atautomatically. - Report to the user: the row you wrote and any field you had to guess.
Normalization rules
- Date →
yyyy-mm-dd. Use the receipt date. If no date visible, fall back to today and flag it. - Amount → grand total, numeric, no currency symbol. Tax/tip already included.
- Currency → ISO-4217 code (USD, CNY, HKD, JPY, EUR, GBP, …). Infer from symbol and language. If symbol is just "$" and context is ambiguous, check merchant country; if still unclear AND amount > 500 units, ask.
- Merchant → clean chain name. Strip store numbers, addresses, register IDs. "STARBUCKS #1234 SHENZHEN" →
Starbucks. - Category → pick exactly one from
categories.md. Default toOtherrather than invent a new one. - Payment method → one of
cash,card,alipay,wechat,octopus,other, or"". Only fill if visible on receipt or stated in caption. - Line items →
"name xQty price; name xQty price". Skip (empty string) if handwritten, illegible, or trivially one item. - Raw OCR → full receipt text, newlines as literal
\n. For audit. Trim trailing whitespace only. - Note → user's caption verbatim. Empty string if none.
- Receipt → if image arrived as a URL, use it. If it's a local path, write the local path and tell the user to wire Drive/S3 upload if they want hotlinkable receipts.
Caption handling
- Caption overrides only when the receipt lacks that field, OR when caption is an explicit correction ("this is actually groceries, not food").
- Split expenses: if caption says "split 50/50 with Alice", still log the full amount — splitting belongs in a separate sheet/column. Note the split in the Note field.
When to ask vs. guess
- Ask when: currency is ambiguous and amount is non-trivial; date could be MM/DD vs DD/MM and merchant country is unclear; amount is unreadable.
- Guess + flag when: category is multi-fit (pick most specific, mention it); merchant name is partially OCR'd (pick best guess, mention it).
- Never silently guess the amount or the currency.
Reply format
Logged to <worksheet> (row <N>):
Date: 2026-04-20
Merchant: Starbucks
Category: Food & Drink
Amount: CNY 48.00 → HKD 51.74 (fx 1.0779 on 2026-04-20)
Payment: wechat
Note: "breakfast with Mark"
Guessed: category (receipt didn't specify; "Food & Drink" based on items).
Omit the Guessed: line when nothing was guessed.
Reference files
categories.md— fixed category list.schema.md— Google Sheet column order and formats.scripts/setup.md— one-time setup (service account, sheet share, deps).