Unignore site/ (was blocked by mkdocs /site rule), add compose/Docker/uv tooling, and split deploys so push to main goes to beta while prod stays manual.
117 lines
4.0 KiB
Markdown
117 lines
4.0 KiB
Markdown
# Messaging
|
||
|
||
Campaign compose/send, SMTP2GO email + SMS, PCM Integrations postcards, and delivery webhooks.
|
||
|
||
## SMTP2GO webhook setup
|
||
|
||
Campaign report page polls provider events every 10s. Create **two** webhooks in
|
||
SMTP2GO → **Settings → Webhooks** (email and SMS stay separate).
|
||
|
||
### Auth (`SMTP2GO_WEBHOOK_SECRET`)
|
||
|
||
1. Set `SMTP2GO_WEBHOOK_SECRET` in `.env` / prod env (long random string).
|
||
2. In SMTP2GO, set **Authorization header** to **Bearer** and paste that same secret
|
||
(do not leave it as “None”).
|
||
3. Fallback: `?token=<SMTP2GO_WEBHOOK_SECRET>` on the webhook URL also works.
|
||
|
||
### Email webhook
|
||
|
||
| Field | Value |
|
||
|-------|--------|
|
||
| URL | `https://mkdrealtor.com/portal/messaging/webhooks/email/` |
|
||
| Authorization header | **Bearer** + `SMTP2GO_WEBHOOK_SECRET` |
|
||
| Output type | JSON |
|
||
| Email events | processed, bounced, rejected, spam, delivered, unsub/resub, opened, clicked |
|
||
| Email headers | `X-Monica-Message-Id` |
|
||
| SMS events | leave unchecked |
|
||
|
||
`X-Monica-Message-Id` is set on every campaign email send and is required so webhook
|
||
events match the correct recipient row.
|
||
|
||
Beta / other hosts: swap the hostname, keep the path.
|
||
|
||
### SMS webhook (separate)
|
||
|
||
| Field | Value |
|
||
|-------|--------|
|
||
| URL | `https://mkdrealtor.com/portal/messaging/webhooks/sms/` |
|
||
| Authorization header | **Bearer** + same `SMTP2GO_WEBHOOK_SECRET` |
|
||
| Output type | JSON |
|
||
| Email events | leave unchecked |
|
||
| SMS events | Submitted, Sending, Delivered, Failed, Rejected, Opt-out |
|
||
|
||
This endpoint also accepts inbound reply POSTs (`text=STOP`, `from=…`) and opts the
|
||
contact out of SMS.
|
||
|
||
## PCM Integrations (postcards)
|
||
|
||
Default postcard provider. Designer embeds PCM’s editor; orders use DirectMail API v3.
|
||
|
||
### Env
|
||
|
||
| Var | Purpose |
|
||
|-----|---------|
|
||
| `PCM_API_KEY` | Bearer token for `https://v3.pcmintegrations.com` |
|
||
| `PCM_WEBHOOK_SECRET` | Auth for inbound status webhooks |
|
||
| `PCM_RETURN_ADDRESS` | JSON return address on orders |
|
||
| `POSTCARD_PROVIDER` | `pcm` (default) |
|
||
|
||
### Designer
|
||
|
||
Portal → **Postcard design**: create/list designs via API, edit in iframe
|
||
(`POST /design/custom`, `GET /design/{id}/edit?mode=embed`). Save as a
|
||
`MessageTemplate` (stores `design_id`) then pick it when composing a postcard campaign.
|
||
|
||
### Postcard webhook
|
||
|
||
Create a webhook subscription in the PCM dashboard (Working with Webhooks):
|
||
|
||
| Field | Value |
|
||
|-------|--------|
|
||
| URL | `https://mkdrealtor.com/portal/messaging/webhooks/postcard/` |
|
||
| Authorization | **Bearer** + `PCM_WEBHOOK_SECRET` |
|
||
| Events | Order / recipient status (Pending, Processing, Processed, Delivered, Undeliverable, Canceled) |
|
||
| Environments | Sandbox and/or Production as needed |
|
||
|
||
Fallback: `?token=<PCM_WEBHOOK_SECRET>` on the URL.
|
||
|
||
Correlation: we send `extRefNbr=<Message.uuid>` on each recipient; webhooks should
|
||
echo that (or `orderID`, matched to `Message.provider_message_id`).
|
||
|
||
### Campaign completion email
|
||
|
||
When a campaign reaches **completed** (email, SMS, or postcard), one summary email
|
||
goes to `campaign.created_by.email`, else `CONTACT_EMAIL`. Guarded by
|
||
`Campaign.notify_sent_at` so it only sends once.
|
||
|
||
### Local development
|
||
|
||
SMTP2GO / PCM cannot reach `localhost`. Use a tunnel (Cloudflare Tunnel / ngrok) to `:8000`,
|
||
or test webhooks against beta/prod.
|
||
|
||
For real SMTP delivery locally (not console logs):
|
||
|
||
```bash
|
||
# in .env
|
||
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
||
EMAIL_HOST_USER=…
|
||
EMAIL_HOST_PASSWORD=…
|
||
SMTP2GO_WEBHOOK_SECRET=…
|
||
SMTP2GO_SMS_API_KEY=… # SMS sends only
|
||
PCM_API_KEY=…
|
||
PCM_WEBHOOK_SECRET=…
|
||
PCM_RETURN_ADDRESS={…}
|
||
```
|
||
|
||
### Endpoints (app)
|
||
|
||
| Path | Purpose |
|
||
|------|---------|
|
||
| `POST /portal/messaging/webhooks/email/` | Email delivery / open / click / bounce / … |
|
||
| `POST /portal/messaging/webhooks/sms/` | SMS delivery events + inbound STOP |
|
||
| `POST /portal/messaging/webhooks/postcard/` | PCM order / mail tracking events |
|
||
| `GET /portal/messaging/campaigns/<id>/status.json` | Live stats for the campaign report UI |
|
||
| `GET /portal/messaging/postcard/` | PCM designer iframe |
|
||
|
||
Code: `webhooks.py`, `providers/postcard/pcm.py`, `views.py`.
|