Files
ALwrity/docs-site/docs/features/backlink-outreach/outreach-operations.md

164 lines
5.1 KiB
Markdown

# Outreach Operations
Outreach operations handle the sending pipeline: policy validation, SMTP delivery, idempotency, suppression, and audit logging.
## Send Pipeline
Every outbound email goes through this pipeline:
```mermaid
flowchart TD
A[Send Request] --> B[Authenticate User]
B --> C[Resolve Lead Email from DB]
C --> D[Policy Validation]
D -->|Approved| E[Create Outreach Attempt Record]
D -->|Blocked| F[Record Audit Log + Return 403]
E --> G[Send via SMTP with TLS]
G -->|Success| H[Increment Counters]
G -->|Success| I[Mark Idempotency Key]
G -->|Success| J[Update Lead Status to Contacted]
G -->|Failure| K[Return 500 with Generic Error]
H --> L[Return 200 with Attempt Details]
I --> L
J --> L
style D fill:#fff3e0
style G fill:#e3f2fd
style F fill:#ffebee
```
!!! warning "Counter timing"
Counters and idempotency keys are marked **only after successful SMTP delivery**, never before. This prevents false cap consumption on failed sends.
## Policy Validation
Before every send, the system validates:
| Check | Rule | On Failure |
|---|---|---|
| **Daily user cap** | Max 100 emails/user/day | Block + audit |
| **Daily domain cap** | Max 20 emails/domain/day | Block + audit |
| **Suppression list** | Recipient not suppressed | Block + audit |
| **Idempotency** | No duplicate `(sender, recipient, subject)` in 24h | Block + audit |
| **Legal basis** | EU domains → "consent", others → "legitimate_interest" | Auto-assign |
**API:** `POST /api/v1/backlink-outreach/policy/validate`
```json
{
"recipient_email": "editor@example.com",
"sender_email": "outreach@yourdomain.com",
"subject": "Guest Post: AI Marketing Trends"
}
```
**Response:**
```json
{
"allowed": true,
"reason": "All checks passed",
"legal_basis": "legitimate_interest",
"daily_user_count": 23,
"daily_user_limit": 100,
"daily_domain_count": 5,
"daily_domain_limit": 20,
"region": "US"
}
```
### Region-Aware Legal Basis
The system infers the recipient's region from their email domain's TLD:
| TLDs | Region | Legal Basis |
|---|---|---|
| `.de`, `.fr`, `.it`, `.es`, `.nl`, `.pl`, `.se`, `.at`, `.be`, `.ch`, `.pt`, `.ie`, `.dk`, `.fi`, `.no`, `.cz`, `.gr`, `.hu`, `.ro`, `.bg`, `.hr`, `.sk`, `.si`, `.lt`, `.lv`, `.ee` | EU | `consent` |
| `.co.uk`, `.uk` | UK | `consent` |
| `.ca` | CA | `consent` |
| `.com.au`, `.co.nz` | AU/NZ | `consent` |
| All others | — | `legitimate_interest` |
!!! note "GDPR compliance"
EU, UK, CA, and AU domain leads always use `consent` as the legal basis. This means you should have obtained some form of consent before reaching out. For other regions, `legitimate_interest` is applied automatically.
## Suppression List
Recipients on the suppression list are blocked from receiving emails.
### Adding to Suppression
**API:** `POST /api/v1/backlink-outreach/suppression`
```json
{
"email": "unsubscribed@example.com",
"reason": "User requested unsubscribe"
}
```
### Listing Suppressed Recipients
**API:** `GET /api/v1/backlink-outreach/suppression`
### Auto-Suppression
Recipients are automatically added to the suppression list when:
- They reply with "not interested" language.
- They explicitly request to be removed.
- An email to their address hard-bounces.
## Idempotency
The system prevents duplicate sends using idempotency keys derived from `(sender_email, recipient_email, subject)`.
- Keys are valid for 24 hours.
- After successful SMTP delivery, the key is marked as used.
- Attempting to send the same `(sender, recipient, subject)` within 24h returns a policy block.
## SMTP Configuration
Emails are sent via SMTP with mandatory TLS:
| Setting | Env Var | Default |
|---|---|---|
| SMTP host | `SMTP_HOST` | — (required) |
| SMTP port | `SMTP_PORT` | `587` |
| SMTP username | `SMTP_USER` | — (required) |
| SMTP password | `SMTP_PASS` | — (required) |
| TLS verification | `SMTP_VERIFY_TLS` | `true` |
| Send timeout | `SMTP_SEND_TIMEOUT` | `30` seconds |
| From email | `SMTP_FROM_EMAIL` | — (required) |
!!! warning "TLS certificate verification"
By default, `SMTP_VERIFY_TLS=true` validates the SMTP server's TLS certificate. Set to `false` only for local development with self-signed certs. **Never disable in production.**
### SMTP Connection Flow
1. Connect to SMTP host on configured port.
2. Send `EHLO` greeting.
3. Upgrade to TLS with `STARTTLS`.
4. Send `EHLO` again (required by RFC 3207 after STARTTLS).
5. Authenticate with username/password.
6. Send the email with a configurable timeout.
7. Quit the connection cleanly.
## Audit Logging
Every policy check is recorded in the audit log:
| Field | Description |
|---|---|
| `user_id` | Authenticated user who initiated the send. |
| `lead_email` | Intended recipient. |
| `sender_email` | Sending address. |
| `subject` | Email subject line. |
| `policy_result` | `approved` or `blocked`. |
| `reason` | Human-readable explanation. |
| `legal_basis` | `consent` or `legitimate_interest`. |
| `timestamp` | When the check occurred. |
---
*Next: [Reply Inbox](reply-inbox.md) — IMAP monitoring and auto-classification.*