17
✉️

Communications & Newsletters — Forms

Postal and email on one ledger · newsletters and mailing lists · WhatsApp and SMS in progress

Communications Service — Forms & Input Specification

Reference technical blueprint: comms.md Slug: comms · Module #15 · 8 sub-modules · ~10 forms

The substrate every other module sends through. Postal · Email · WhatsApp · SMS — one ledger, one template engine, one audience-segmentation engine. Every outbound message recorded with idempotency for retries.


Sub-module 1: Channels & Provider Settings

Form 1.1 — Provider Credentials Setup

Purpose: Configure SMTP / WhatsApp / SMS provider credentials per tenant. Most tenants use platform defaults; Pro/Enterprise can override. Who fills: Platform-admin (defaults) or tenant-admin (overrides). Rare.

Field Type Required Options / Validation Default Help
Channel Dropdown Yes Email · WhatsApp · SMS · Postal — Postal uses physical address
Provider Dropdown Yes (per channel — see help) — Email: Workspace SMTP / Resend / SendGrid; WhatsApp: Meta Cloud API; SMS: provider-TBD
Credential Reference Text Yes Secret Manager key name — e.g. whatsapp-cloud-token
Test Send Recipient Text No Email/phone — For verification
Active? Checkbox Yes — ☑ —

Submit action: Validates credentials by sending test message; activates channel for tenant.


Sub-module 2: Templates

Form 2.1 — Template Editor

Purpose: Create / edit a message template that can render to multiple channels.

Field Type Required Options / Validation Default Help
Template Name Text Yes Unique per tenant — e.g. donation_thanks_v1
Owner Module Dropdown Yes All modules — Which module uses this
Channels Supported Multi-select Yes Email · WhatsApp · SMS · Postal Email —
Subject (email) Text Conditional Jinja allowed: {{member.name}} — If Email selected
HTML Body (email) Rich-text Conditional Jinja-templated — If Email selected
Text Body (email/SMS) Textarea Conditional Jinja-templated, ≤160 chars for SMS — —
WhatsApp Template Name Text Conditional As approved in Meta Business Manager — If WhatsApp selected — must be pre-approved
WhatsApp Variables Order Comma-list Conditional e.g. member_name,amount,fy — —
Postal Letter Body Rich-text Conditional Jinja with PDF rendering hints — If Postal selected
Available Variables Read-only — Auto-populated — Lists vars the engine resolves
Locked? Checkbox Yes — ☐ If ☑, only platform-admin can edit

Submit action: Saves as new version (content-hashed); previous version preserved. Related: Test-send before activation.

Form 2.2 — Template Test Send

Purpose: Verify a template renders correctly before broadcasting.

Field Type Required Options / Validation Default Help
Template Dropdown Yes — — —
Channel Dropdown Yes From template's supported channels First —
Test Recipient Text Yes Email or phone Self —
Sample Variables Key-value pairs Yes JSON-like editor — e.g. {"member.name":"Test", "amount":"5000"}

Submit action: Sends one test message; logs to communication_log with is_test=True.


Sub-module 3: Audience Segmentation

Form 3.1 — Audience Segment Builder

Purpose: Define a reusable named segment (e.g. "FCRA donors who gave > ₹10k last year").

Field Type Required Options / Validation Default Help
Segment Name Text Yes Unique per tenant — —
Description Textarea No — — What this segment is for
Rule Type Dropdown Yes Tag · Donor History · Branch · Custom SQL · Manual List · Composite Tag —
Tag-based rules:
Required Tags Multi-select Conditional From tags taxonomy — —
Excluded Tags Multi-select No — — —
Donor-history rules:
Min Donation (₹) Number Conditional — — —
Period Dropdown Conditional Last FY · This FY · Last 12 months · All-time · Custom Last FY —
Fund Filter Multi-select No From funds All —
Branch rule:
Branches Multi-select Conditional — — —
Custom SQL:
SQL Where Clause Textarea Conditional Read-only on members join — Platform-admin only; tenant_id auto-applied
Manual list:
Member List Multi-select Conditional Manual member picker — —
Preview Count Read-only — — Computed Click "Preview" to recompute

Submit action: Saves segment; preview_count materialises on save.


Sub-module 4: Campaigns / Comms Jobs

Form 4.1 — Compose Bulk Campaign

Purpose: Send a templated message to a segment.

Field Type Required Options / Validation Default Help
Campaign Name Text Yes — — Internal label
Audience Segment Dropdown Yes — — Shows preview count
Template Dropdown Yes — — —
Channels Multi-select Yes From template's supported All —
Variables Source Dropdown Yes Auto-from-recipient · Static · Per-recipient overrides Auto —
Static Variables Key-value Conditional If Static — —
Schedule Dropdown Yes Send Now · One-shot at... · Recurring Send Now —
Send At Datetime Conditional — — If One-shot
Cron Expression Text Conditional Standard cron syntax — If Recurring
Approval Required? Checkbox Yes — Auto: ☑ if recipients > 500 Two-key for large blasts
Notes Textarea No — — —

Submit action: Creates comms_jobs row; if approval required, status=pending. Otherwise queued for dispatch.

Form 4.2 — Send Single Message (admin testing)

Purpose: Send one ad-hoc message — debugging, support replies.

Field Type Required Options / Validation Default Help
Channel Dropdown Yes — Email —
Recipient Type Dropdown Yes Member · External email · External phone · Vendor · Government office Member —
Recipient Search/text Yes — — Member search or raw email/phone
Template Dropdown Yes — — —
Variables Key-value Yes — — —

Submit action: Immediate dispatch; logged.


Sub-module 5: Suppression List

Form 5.1 — Add Suppression

Purpose: Honor an opt-out, bounce, or compliance request.

Field Type Required Options / Validation Default Help
Channel Dropdown Yes — — —
Address (email/phone) Text Yes — — —
Reason Dropdown Yes User opt-out · Hard bounce · Spam complaint · Legal demand · Other — —
Reason Notes Textarea No — — —
Suppress Until Date No Blank = forever — —

Submit action: Adds to suppression. All future sends to this address are blocked.


Sub-module 6: Campaign Monitor (read-only)

Form 6.1 — Campaign Status View

Purpose: Inspect a running or completed campaign's delivery + engagement.

Filters / Display fields: - Campaign Name, Status (queued / dispatching / completed / partial-failure) - Recipients: total / sent / delivered / opened / clicked / bounced / unsubscribed - Started At, Completed At - Per-channel breakdown - Failed-recipient list (downloadable CSV) - Re-send-failed button


Workflow

The Comms service is called by every other module, not used standalone. Typical flow: a module (Vitta, Compliance, Events, etc.) calls comms.send(template_name=…, recipient=…, vars=…) → Comms looks up the template, renders it for the chosen channel(s), records to communication_log, queues for async dispatch, dispatches via the channel adapter, captures delivery webhook updates, marks the log entry. Bulk campaigns compose via Form 4.1; single test sends via Form 2.2 or 4.2. Templates are versioned; suppression list is honored at send time.