Port campaign UTM links and piha.li shortener from monica_site #3

Closed
opened 2026-08-30 13:12:22 -07:00 by westfarn · 1 comment
Owner

Port campaign tracked-link UX and piha.li shortener integration from monica_site into this template so new client sites get both without copying by hand.

Reference implementation: ai_ml_operations/monica_site (issue to be linked after create; includes composer UTM panel + POST /api/links/ client).

Template split: email_sms (email/SMS composer) and directmail (postcard QR). Shared helper should live where both flags can use it (core or a small shared module) — do not duplicate mint logic.

1. Auto UTM tracked links (composer + report)

Same contract as Monica:

  • utm_source = client brand slug (not hardcoded monica; derive from site/branding)
  • utm_medium = email | sms | postcard
  • utm_campaign = hyphenated campaign name
  • Email: insert/refresh HTML <a> as the name is typed / on save
  • SMS: insert/refresh a plain-text URL (preview may linkify; the stored body stays text)
  • Postcard: QR of the tracked URL for copy/download into the PCM designer
  • Campaign report page shows the same panel

2. URL shortener

Call url_shortening_service (API.md).

  • POST /api/links/ on the API host (SHORTENER_BASE_URL), never piha.li / beta.piha.li
  • Auth: Authorization: Bearer <name>:<secret> (SHORTENER_API_TOKEN)
  • UTM query on target_url before mint; external_ref = campaign UUID
  • Live composer: portal JSON endpoint (login + CSRF). Browser must not call the shortener (no CORS).
  • Unconfigured env → long UTM URL, compose still works
  • target_url must be https and host must be on the shortener allowlist (SHORT_ALLOWED_HOSTS on that service)

3. Env / secrets to document in .env.example + .env.prod.example

SHORTENER_BASE_URL=https://shortener.aimloperations.com
SHORTENER_API_TOKEN=<caller-name>:<secret>

Beta: https://shortener-beta.aimloperations.com + a distinct token.

Operator side (shortener secret files, not this repo):

SHORTENER_API_TOKENS=<caller-name>:<secret>
SHORT_ALLOWED_HOSTS=<client-domain>,aimloperations.com

Public short hosts: piha.li (prod), beta.piha.li (beta).

scripts/bootstrap-client.sh / validate-env.sh: require these when FEATURE_EMAIL_SMS or FEATURE_DIRECT_MAIL is on in beta/prod.

Acceptance

  • Email/SMS/postcard composers auto-build UTM links (brand-specific utm_source)
  • Configured shortener mints piha.li / beta.piha.li URLs into SMS + QR
  • Feature-flag off → no shortener calls, no extra nav
  • Tests for UTM shape, mint (mocked HTTP), and unconfigured fallback
  • Env examples document caller + operator secrets
Port campaign tracked-link UX and piha.li shortener integration from monica_site into this template so new client sites get both without copying by hand. Reference implementation: [ai_ml_operations/monica_site](https://git.aimloperations.com/ai_ml_operations/monica_site) (issue to be linked after create; includes composer UTM panel + `POST /api/links/` client). Template split: `email_sms` (email/SMS composer) and `directmail` (postcard QR). Shared helper should live where both flags can use it (core or a small shared module) — do not duplicate mint logic. ## 1. Auto UTM tracked links (composer + report) Same contract as Monica: - `utm_source` = client brand slug (not hardcoded `monica`; derive from site/branding) - `utm_medium` = `email` | `sms` | `postcard` - `utm_campaign` = hyphenated campaign name - Email: insert/refresh HTML `<a>` as the name is typed / on save - SMS: insert/refresh a plain-text URL (preview may linkify; the stored body stays text) - Postcard: QR of the tracked URL for copy/download into the PCM designer - Campaign report page shows the same panel ## 2. URL shortener Call [url_shortening_service](https://git.aimloperations.com/ai_ml_operations/url_shortening_service) ([API.md](https://git.aimloperations.com/ai_ml_operations/url_shortening_service/src/branch/master/API.md)). - `POST /api/links/` on the **API host** (`SHORTENER_BASE_URL`), never `piha.li` / `beta.piha.li` - Auth: `Authorization: Bearer <name>:<secret>` (`SHORTENER_API_TOKEN`) - UTM query on `target_url` before mint; `external_ref` = campaign UUID - Live composer: portal JSON endpoint (login + CSRF). Browser must not call the shortener (no CORS). - Unconfigured env → long UTM URL, compose still works - `target_url` must be `https` and host must be on the shortener allowlist (`SHORT_ALLOWED_HOSTS` on that service) ## 3. Env / secrets to document in `.env.example` + `.env.prod.example` ``` SHORTENER_BASE_URL=https://shortener.aimloperations.com SHORTENER_API_TOKEN=<caller-name>:<secret> ``` Beta: `https://shortener-beta.aimloperations.com` + a distinct token. Operator side (shortener secret files, not this repo): ``` SHORTENER_API_TOKENS=<caller-name>:<secret> SHORT_ALLOWED_HOSTS=<client-domain>,aimloperations.com ``` Public short hosts: `piha.li` (prod), `beta.piha.li` (beta). `scripts/bootstrap-client.sh` / `validate-env.sh`: require these when `FEATURE_EMAIL_SMS` or `FEATURE_DIRECT_MAIL` is on in beta/prod. ## Acceptance - [ ] Email/SMS/postcard composers auto-build UTM links (brand-specific `utm_source`) - [ ] Configured shortener mints `piha.li` / `beta.piha.li` URLs into SMS + QR - [ ] Feature-flag off → no shortener calls, no extra nav - [ ] Tests for UTM shape, mint (mocked HTTP), and unconfigured fallback - [ ] Env examples document caller + operator secrets
Author
Owner

Monica implementation (source of truth for this port): ai_ml_operations/monica_site#9

That ticket covers auto UTM in the campaign composer plus minting short links via POST /api/links/ on the shortener API host. Copy that behavior into email_sms + directmail (shared mint client).

Monica implementation (source of truth for this port): https://git.aimloperations.com/ai_ml_operations/monica_site/issues/9 That ticket covers auto UTM in the campaign composer plus minting short links via `POST /api/links/` on the shortener API host. Copy that behavior into `email_sms` + `directmail` (shared mint client).
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: westfarn/web_django_template#3