V8 — first inbound-side skill. Closes the loop from "bill arrives by email"
to "ready to enter in Dolibarr UI". Read-only at every layer.
What ships:
- arcodange-email-ingest/scripts/zoho-curl.sh OAuth wrapper with token cache
(50 min TTL, mode 600) — avoids
hitting Zoho OAuth rate limit on
every invocation.
- arcodange-email-ingest/scripts/email-list.sh List candidates in /Inbox/books
(where the books@ alias auto-
routes mail). --candidates-only
filter on supplier patterns or
attachments. --all-folders to
scan everything.
- arcodange-email-ingest/scripts/email-inspect.sh Pull message + attachments,
pdftotext on each PDF, heuristic
extract (supplier, ref, dates,
totals, VAT rate), emit Dolibarr
supplier-invoice draft JSON.
Architecture choice — Zoho API (not IMAP):
- books@arcodange.fr is an alias of gabrielradureau@arcodange.fr → one OAuth
refresh_token covers everything.
- Gmail folded in via forwarding (arcodange@gmail.com → books@) — no Google
API setup, no app-passwords, no second OAuth flow.
- Token-based auth, no SCA rabbit hole.
V8.0 baseline (in /Inbox/books):
- 3 candidates: Mistral AI facture, Anthropic Stripe receipt (Fwd Gmail),
INPI payment receipt (Fwd Gmail).
- Heuristic extraction is best-effort: works on amounts/refs for some
templates, misses others (Mistral PDF format, Stripe receipt layout).
- --save-pdf <DIR> lets the operator grab the PDFs for manual entry when
the heuristic falls short.
Rate-limit pitfall documented: Zoho OAuth refresh has an aggressive throttle
("too many requests continuously"). The cache file at $TMPDIR/zoho-access-$USER
(mode 600, 50 min TTL) prevents this; on 401 the wrapper auto-refreshes once
and retries.
V8.1+ ideas in SKILL.md out-of-scope:
- mark ingested emails (IMAP flag or Zoho label)
- body text extraction (inline-HTML invoices)
- per-template parsers or LLM-based extraction
- IMAP fallback for non-Zoho mailboxes
CLI: bin/arcodange email {list|inspect|curl} integrated.
Base updates: dolibarr/SKILL.md cross-link, dolibarr/README.md env schema
extended with ZOHO_CLIENT_ID/SECRET/REFRESH_TOKEN/DC.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
3.3 KiB
Markdown
74 lines
3.3 KiB
Markdown
# dolibarr — one-time setup
|
|
|
|
Skill body: [SKILL.md](SKILL.md). This README is the human-facing setup checklist.
|
|
|
|
## 1. Create `.env` (mode 600, never committed)
|
|
|
|
```bash
|
|
cat > .claude/skills/dolibarr/.env <<'EOF'
|
|
DOLIBARR_URL=https://erp.arcodange.lab
|
|
DOLIBARR_API_KEY=<get from Dolibarr UI: Users → ai_agent → API key>
|
|
DOLIBARR_USER=ai_agent
|
|
DOLIBARR_PASSWORD=<the ai_agent password, only needed for occasional UI login>
|
|
|
|
# Required by arcodange-bank-reco only (omit if you only use dolibarr-* skills)
|
|
QONTO_LOGIN=arcodange-XXXXX
|
|
QONTO_SECRET_KEY=<from Qonto Settings → Integrations → API>
|
|
QONTO_ORG_SLUG=arcodange-XXXXX # same as login in most cases
|
|
WISE_API_TOKEN=<from wise.com/settings/api-tokens>
|
|
WISE_PROFILE_ID=<numeric id of the BUSINESS profile — bank probe prints it>
|
|
# Optional: only needed if Wise ever opens the EU statement endpoint
|
|
WISE_SCA_KEY_PATH=~/.config/arcodange-erp/wise-sca-private.pem
|
|
|
|
# Required by arcodange-email-ingest only
|
|
ZOHO_CLIENT_ID=<from api-console.zoho.com self-client>
|
|
ZOHO_CLIENT_SECRET=<same>
|
|
ZOHO_REFRESH_TOKEN=<exchanged from one-time code via /oauth/v2/token>
|
|
ZOHO_DC=eu # eu | com | in | au
|
|
EOF
|
|
chmod 600 .claude/skills/dolibarr/.env
|
|
```
|
|
|
|
Verify it's gitignored:
|
|
|
|
```bash
|
|
git check-ignore .claude/skills/dolibarr/.env # should print the path
|
|
```
|
|
|
|
## 2. Grant `ai_agent` the four `voir_tous` permission flags
|
|
|
|
`ai_agent` is read-only by design. But Dolibarr's per-record ACL silently filters out invoices and thirdparties unless the `voir_tous` (see-all) flags are ticked. Without them, `/invoices` returns `[]` and `/thirdparties` returns 404 — looks like an empty database.
|
|
|
|
In the Dolibarr UI (https://erp.arcodange.lab/ → **Setup → Users & Groups → `ai_agent` → Permissions**), tick:
|
|
|
|
- [ ] **Tiers** → Lire les tiers
|
|
- [ ] **Tiers** → Voir tous les tiers (et pas seulement ceux liés à l'utilisateur courant)
|
|
- [ ] **Factures** → Lire les factures
|
|
- [ ] **Factures** → Voir toutes les factures (et pas seulement celles liées à l'utilisateur courant)
|
|
- [ ] **Factures fournisseurs** → Lire les factures fournisseurs (required by `dolibarr-tva-deductible`)
|
|
- [ ] **Factures fournisseurs** → Voir toutes les factures fournisseurs
|
|
|
|
Save. Future modules used by `dolibarr-*` sibling skills (Paiements, Produits, …) need the same treatment.
|
|
|
|
## 3. Quick-start test
|
|
|
|
```bash
|
|
./.claude/skills/dolibarr/scripts/dol-curl.sh /users/info | jq -r .login
|
|
# → ai_agent
|
|
./.claude/skills/dolibarr/scripts/dol-curl.sh /status
|
|
# → {"success":{"code":200,"dolibarr_version":"22.0.4",...}}
|
|
./.claude/skills/dolibarr/scripts/dol-curl.sh /thirdparties/1 | jq '{ref, country_code, town}'
|
|
# → {"ref":"KissMetrics","country_code":"US","town":"St. Petersburg"}
|
|
```
|
|
|
|
If the third one returns HTTP 403 `Access not allowed for login ai_agent on this thirdparty`, the `voir_tous` flags from step 2 are missing.
|
|
|
|
## 4. Rotating the API key
|
|
|
|
If the key leaks: Dolibarr UI → Users → `ai_agent` → API key → **Generate new** → copy the new value into `.env`. No other change needed; every `dolibarr-*` skill picks it up via `dol-curl.sh`.
|
|
|
|
## Pointers
|
|
|
|
- Full skill body, endpoint catalogue, gotchas: [SKILL.md](SKILL.md).
|
|
- First workflow skill that depends on this one: [../dolibarr-invoice-audit/SKILL.md](../dolibarr-invoice-audit/SKILL.md).
|