129 lines
3.3 KiB
Markdown
129 lines
3.3 KiB
Markdown
# Spam Rescue & Placement Tracking
|
|
|
|
## Objectives
|
|
|
|
1. Detect when warmup emails land in spam/junk
|
|
2. Rescue them (move to inbox, positive signals)
|
|
3. Track spam rate per primary for dashboard and auto-pause
|
|
4. Never leave warmup mail unhandled in spam folders
|
|
|
|
## Folder discovery
|
|
|
|
### Default folder list (try in order)
|
|
|
|
| Provider | Folders |
|
|
|----------|---------|
|
|
| Gmail | `[Gmail]/Spam` |
|
|
| Outlook | `Junk` |
|
|
| Yahoo | `Bulk` or `Spam` |
|
|
| Generic | `Spam`, `Junk` |
|
|
|
|
### Target enhancement
|
|
|
|
1. `LIST` IMAP folders on connect; match known spam patterns
|
|
2. Store per-mailbox `spamFolderPath` after first discovery
|
|
3. Provider enum shortcuts connection presets
|
|
|
|
## Rescue workflow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant R as Rescuer
|
|
participant IMAP as Primary IMAP
|
|
participant DB as Database
|
|
|
|
R->>IMAP: Open spam folder
|
|
R->>IMAP: SEARCH unseen FROM satellite
|
|
IMAP-->>R: UIDs
|
|
loop Each UID
|
|
R->>IMAP: MOVE to INBOX
|
|
R->>DB: Log placement=spam, status=rescued
|
|
R->>IMAP: FLAGS Seen, Flagged
|
|
R->>IMAP: FLAGS Important (best effort)
|
|
R->>R: shouldReply?
|
|
alt Reply sampled
|
|
R->>SMTP: Send reply
|
|
else No reply
|
|
R->>DB: status=engaged_no_reply
|
|
end
|
|
end
|
|
```
|
|
|
|
## Per-message matching (fix MVP weakness)
|
|
|
|
Current MVP marks all pending logs from sender when any spam found. Target:
|
|
|
|
| Priority | Match key |
|
|
|----------|-----------|
|
|
| 1 | `Message-ID` header exact match |
|
|
| 2 | `In-Reply-To` chain |
|
|
| 3 | From + normalized subject + 24h window |
|
|
|
|
One UID → one WarmupLog row.
|
|
|
|
## Placement tracking
|
|
|
|
Add to `WarmupLog` or separate `PlacementEvent`:
|
|
|
|
| Field | Values |
|
|
|-------|--------|
|
|
| placement | `inbox`, `spam`, `unknown` |
|
|
| detectedAt | timestamp |
|
|
| rescuedAt | timestamp nullable |
|
|
| folder | string |
|
|
|
|
### Inbox placement rate
|
|
|
|
```
|
|
inboxRate = 1 - (spamDetected / totalReceived)
|
|
```
|
|
|
|
Target: ≥95% inbox after week 3.
|
|
|
|
## INBOX processing (non-spam path)
|
|
|
|
Scan primary INBOX for unread warmup from assigned satellites:
|
|
|
|
- Same matching rules
|
|
- If already in inbox: flag + optional reply (no move)
|
|
- Log `placement=inbox`
|
|
|
|
## Auto-pause triggers
|
|
|
|
| Condition | Action |
|
|
|-----------|--------|
|
|
| Spam rate >30% for 3 consecutive days | Pause campaign; alert operator |
|
|
| Spam rate >50% in 24h | Immediate pause |
|
|
| Rescue failures >5 in row | Mark primary `error` |
|
|
| Auth failure | Mark `error`; stop all jobs |
|
|
|
|
## Provider-specific notes
|
|
|
|
### Gmail / Google Workspace
|
|
|
|
- `\Important` via labels (`useLabels: true`)
|
|
- Postmaster Tools integration (future): pull domain reputation
|
|
- App passwords required; OAuth preferred for SaaS
|
|
|
|
### Microsoft 365 / Outlook
|
|
|
|
- Junk Email folder naming varies
|
|
- Enable IMAP in admin settings
|
|
- SNDS integration (future)
|
|
|
|
### Yahoo
|
|
|
|
- App password required
|
|
- Bulk folder common
|
|
|
|
## Compliance considerations
|
|
|
|
Rescue actions simulate **user marking not spam** — legitimate when acting on mail the user owns. Warmbox must only access mailboxes the operator controls.
|
|
|
|
**Do not** rescue mail the operator does not own (peer network phase requires explicit consent).
|
|
|
|
## Future: seed placement tests
|
|
|
|
Optional inbox placement probes (like GlockApps) — out of MVP scope but document hook:
|
|
|
|
`POST /campaigns/:id/placement-test` → send test to probe addresses → report inbox/spam
|