# Bulk Gmail Operations

Patterns for deleting, archiving, or labeling large numbers of emails — 50+ at a time.

## Deletion (Move to Trash)

Gmail has no "permanently delete" via the API — `--add-labels TRASH` moves to Trash.
Messages auto-expire after 30 days. There's no separate "delete forever" call needed.

```bash
GAPI="python3 /DATA/.hermes/skills/productivity/google-workspace/scripts/google_api.py"
$GAPI gmail modify MESSAGE_ID --add-labels TRASH
```

Returns JSON with `"labels": [..., "TRASH", ...]` on success.

## Rate Limiting & Retries

**Pitfall**: Large bulk operations (~100 messages) will fail for a subset due to Gmail
API rate limits. Expect ~40-50% failure rate on the first pass of 100 sequential
`modify` calls without delays.

**Retry strategy**:
- Collect failed IDs
- Retry in batches of 5 with 0.5s sleep between batches
- Second pass usually clears ~90% of remaining failures
- Third pass (with 0.3s sleep between calls) clears the rest

```python
# Pattern for retrying failed IDs in batches
batch_size = 5
for i in range(0, len(failed), batch_size):
    batch = failed[i:i+batch_size]
    for mid in batch:
        terminal(f'{GAPI} gmail modify {mid} --add-labels TRASH')
    time.sleep(0.5)
```

## Pagination for Large Result Sets

The `gmail search` subcommand does NOT support a `--page` flag. Each search returns
up to ~100 results. For mailboxes with hundreds of matching messages, split by
date ranges:

```bash
# Instead of one big search:
$GAPI gmail search "from:amazon" --max 100   # caps at ~100

# Split by month:
$GAPI gmail search "from:amazon after:2026/05/01" --max 100
$GAPI gmail search "from:amazon after:2026/04/01 before:2026/05/01" --max 100
$GAPI gmail search "from:amazon after:2026/03/01 before:2026/04/01" --max 100
# ... continue back in time
```

Use `after:YYYY/MM/DD` and `before:YYYY/MM/DD` (Gmail search syntax, not ISO 8601).
Deduplicate by tracking seen message IDs in a set.

## Summary-First Confirmation Pattern

For bulk deletion, show the user a summary BEFORE executing:
- How many messages found, from which senders, across what date range
- Let the user confirm, then execute

This satisfies the "don't act without confirming" rule while avoiding per-message
confirmation fatigue for obvious spam/newsletter cleanup.
