---
name: whatsapp-weekly-report
description: Produce a weekly digest of chosen WhatsApp groups as a polished HTML report. Trigger when the user says "WhatsApp weekly report", "summarize my WhatsApp groups", or runs the scheduled routine. Requires the WhatsApp connector extension (whatsapp_* tools).
---

# WhatsApp weekly report

Compose a tight weekly digest of the WhatsApp groups the user names, using the
WhatsApp connector tools. This skill is **policy**; the extension is **plumbing**.
The skill owns: which groups, the window, the summary shape, and delivery. The
extension owns: linking, fetching, sending.

**Default output is the rich HTML digest** (see below) — one file per group,
rendered as an artifact in the chat. Plain-text-in-chat is the opt-out, only when
the user explicitly asks for a quick text summary.

## Real connector tools (use these exact names)

| Need | Tool | Key args |
|---|---|---|
| Check link state | `whatsapp_status` | → `logged_in`, `needs_pairing`, `bridge_reachable` |
| Show the QR | `pair_whatsapp` | — |
| Find a group's JID | `list_chats` | `query`, `limit`, `sort_by` (`"last_active"`), `include_last_message` |
| Fetch a group's messages | `list_messages` | `chat_jid`, `after` (ISO-8601), `limit`, `page`, `include_context` |
| Confirm one chat | `get_chat` | `chat_jid` |
| Deliver to self (optional) | `send_message` / `send_file` | `recipient`, `message` / file |

There is **no** `whatsapp_fetch_messages`, `whatsapp_send`, or `whatsapp_pair` —
those names do not exist. `whatsapp_status` returns `logged_in`, not `linked`.

## Inputs (from the user / routine prompt)

- **groups** — the group names to cover. The user always supplies these
  (e.g. "Family, JobsHub, Soccer"). Never guess; if none are given, ask, or run
  `list_chats` and ask which to include.
- **days** — lookback window. Default **7**.
- **delivery** — how to return the report. **Default: the HTML digest, rendered
  as an artifact in the chat (one per group).** If the user says "just text" /
  "quick summary", write plain text in the chat instead. If they say "send it to
  me", deliver to their own number via `send_file` (the HTML) or `send_message`
  (a text version).

## Procedure

1. **Check the link.** Call `whatsapp_status`. If `logged_in` is false, tell the
   user to pair (run `pair_whatsapp` and scan the QR, or use the `whatsapp-init`
   skill) and stop.
2. **Resolve each group's JID.** For every group name, call `list_chats` with
   `query: "<name>"`, `sort_by: "last_active"` and match the right chat — keep its
   `chat_jid` (group JIDs end in `@g.us`). Confirm with `get_chat` if ambiguous.
3. **Fetch per group, windowed.** Compute the cutoff = now − `days` as an ISO-8601
   string. For each group call:
   `list_messages(chat_jid=<jid>, after=<cutoff>, limit=200, include_context=false)`.
   - `list_messages` pages backward from newest. If you get a full `limit` page and
     the oldest returned message is still newer than the cutoff, fetch the next
     `page` until you cross the cutoff (or results run dry).
   - There is **no date-range API and no `coverageComplete` flag**: if WhatsApp
     stops serving older history before the cutoff (pages run dry early), note that
     the group's older messages may be truncated.
   - Do one group at a time; don't fabricate a single multi-group call.
4. **Summarize per group.** For each group write:
   - **Activity** — message count; most-active people when names resolve.
   - **Key topics & decisions** — what was discussed, what was decided.
   - **Questions asked** — especially unanswered ones.
   - **Links / files shared.**
   - **Needs your attention** — @-mentions of the user, deadlines, action items.
   - A group with 0 messages gets a single line saying so.
5. **Lead with a cross-group "what matters this week"** — 1–3 lines at the top.
6. **Deliver.** Default = the HTML digest below, one file per group, rendered as an
   artifact in the chat. Lead with the plain-text cross-group summary, then the
   per-group HTML. Only fall back to all-text if the user asked for that.

## HTML digest (the default format)

A polished single-group digest template lives at `templates/weekly-digest.html`.
It is fully self-contained — no network images (initials avatars), only Google
Fonts. To produce one:

1. **Read** `templates/weekly-digest.html`.
2. **Fill only the `DATA = {…}` block** near the bottom from your summary — leave
   the render code untouched. Fields (see the comment in the file):
   - `group`, `week` (e.g. `"Mon 8 – Sun 14 Jun 2026"`), `footer`
   - `stats`: `{ messages, people, busiestDay, needYou }` — the 4 top tiles
   - `needsYou[]`: `{ type:"do"|"ask"|"at", tx, who }` — `tx` allows `<b>…</b>`
   - `decided[]`: `{ tx, mt }` — `mt` is a meta line like `"Decided Thu · Trips"`
   - `restline[]`: `{ type, x }` — small "quietly handled" pills
   - `topics[]`: pre-sorted desc, ≤6, `{ n, v, c? }` (`c` = optional hex bar colour)
   - `people[]`: pre-sorted desc, ≤5, `{ n, c }` — use `n:"me"` for the reader
3. **Write** the filled HTML to a file and render it as an artifact (or deliver it).
4. **One group per file.** For multiple groups, produce one digest each, led by the
   plain-text cross-group summary.

**Privacy still applies:** never put a phone number in `DATA` — display names only.

## Notes / limits

- **No date-range API.** `list_messages` pages backward from newest via `after` +
  `page`; you stop when you cross the cutoff or pages run dry. Early-dry = older
  history no longer served → note possible truncation.
- **Names** can be partial (a sender shows as a number/`lid` until they post
  live). Group subjects always resolve. Don't invent names.
- **Privacy** — the user's phone number must never be surfaced in the report body
  or anywhere it leaves the machine. Use display names.
- **No bulk sending** via `send_message` / `send_file` (ban risk) — at most one
  delivery message to the user's own number.

## Scheduling

To run this weekly, create a Routine in Claude Desktop's **Scheduled** tab:

- **Name:** WhatsApp Weekly Report
- **Schedule:** Weekly, e.g. Monday 09:00
- **Instructions:** `Run the whatsapp-weekly-report skill for groups: Family,
  JobsHub, Soccer. days=7. Deliver the HTML digest in the chat.`

The routine runs while Claude Desktop is open and the machine is awake; the report
fetches its window at call time, so gaps between runs don't lose data (within
WhatsApp's history-serving limit).
