WhatsApp¶
Backfill only — no live connector
WhatsApp has no sanctioned API for a live poll, so there's no kind in
cap_connectors for it and no cap_connectors row to create. The only
way to bring WhatsApp history into cap_items is the one-shot backfill
below, run against an export you generate yourself.
What it does¶
Parses a per-chat WhatsApp "Export Chat" archive — the _chat.txt file
(iOS or Android) — filtered by date, and normalizes each message into the
same cap_items shape as every other connector. No network, no credentials.
Prereqs¶
Export the chat from the WhatsApp app: open the chat → ⋮ / contact name →
More → Export Chat → choose "Without Media" or "Include Media" → save the
result. You'll get either a single _chat.txt file or a folder containing
_chat.txt plus attachments.
Run it¶
python -m capture_agent.backfill whatsapp --export <path to _chat.txt or its containing dir> --since 2026-01-01
--since filters to messages on or after that date (YYYY-MM-DD). If
--export points at a directory, _chat.txt inside it is preferred; if
there's no such file, every .txt file in the directory is parsed.
Verify¶
The command prints a summary when it finishes, e.g. capture whatsapp
backfill: {'ingested': N, 'skipped_dupe': 0, 'unrouted': N, 'entities_created':
N, 'errors': 0}. Check cap_items in the PocketBase admin for the new rows.
Notes on the export format¶
- Two different mechanisms handle export tokens — don't confuse them.
- Whole-message system notices are dropped entirely. Author-less notices —
the end-to-end-encryption banner, business-account notices, and
group subject/description/icon changes — are matched against a fixed
phrase list and the whole line is skipped, so they never become a
cap_itemsrow. The media-omitted and "edited" markers (image omitted,video omitted,<This message was edited>) genuinely have no localized variants in the export. The group-change phrases are matched in English (the export's observed locale) plus a best-effort set of French variants — so a group-change notice in a language other than English or French may not be recognized as a system notice. - Media/attachment tokens are stripped in place. On an actual message the exporter emits an attachment or omitted-media token; the connector removes just that token and keeps the rest of the line as the message body (see the next note).
- Whole-message system notices are dropped entirely. Author-less notices —
the end-to-end-encryption banner, business-account notices, and
group subject/description/icon changes — are matched against a fixed
phrase list and the whole line is skipped, so they never become a
- A caption on an attached/omitted media message stays in the body,
mid-message. The connector strips only the attachment token itself
(
<attached: name>on iOS,name (file attached)on Android) or the<kind> omittedmarker — any caption text on the same message is left in place around where the token was.
Errors¶
Per-message parsing failures are logged and skipped so one malformed line
never aborts the whole import — re-running the same command later is safe,
since cap_items dedupes by external_id and already-imported messages are
left alone.