ConsentIVR

ConsentIVR - Documentation

Consent-first voice, SMS, and WhatsApp communications - enforced in code.

Flask Twilio · Telnyx · Plivo · Vonage SQLite / SQLCipher Telegram bot

01Overview

ConsentIVR is a Flask-based inbound IVR and opt-in outbound communications platform. An inbound IVR routes callers through editable menus; outbound campaigns place appointment reminders and surveys over voice, SMS, or WhatsApp. Operators run and monitor everything from a web dashboard or an interactive Telegram console, with optional live alerts.

Menus, business hours, campaigns, and recipients live in the database - routing and campaign settings can be changed without editing application code.

At a glance

MetricValue
Channels3 - voice, SMS, WhatsApp
Pluggable providers5
Consent gates per contact3
Operator-console languages5
Identity secrets captured0

Key design goals

Data-driven routing

Menus and keypad options are rows in ivr_menus / ivr_options, edited from the dashboard. A global inbound mode can send every call to the menu, a forwarding number, voicemail, or a closed message.

Consent is the gate, not a note

Outbound dialing lists are built only from granted consent records, and three gates are re-checked for every recipient at send time - the import check is never trusted on its own.

02Architecture

Signed carrier webhooks in, a thin Flask core, short-lived SQLite connections. Each layer is a handful of small modules, and one command runs the web app, the webhooks, and the Telegram bot together.

LayerModules
CarriersTwilio · Telnyx · Plivo · Vonage · console
Providersproviders.py - send_message(), place_call()
Web / TwiMLivr · outbound_voice · sms · webhooks · dashboard
Telegram botapi (long-poll) · middleware · handlers · keyboards · i18n · access · payments
Core logicconsent · hours · jobs + joblock · validate · crypto
StorageSQLite / SQLCipher (WAL) - contacts · consent · opt_outs · campaigns

Startup

python app.py

This single command serves the web app, the carrier webhooks, and the Telegram bot in one process.

03Inbound call flow

Every Twilio/Telnyx webhook is verified by signature before any of the following runs.

  1. Call arrives → check inbound mode
    ivr forward voicemail closed
  2. Business hours check (mode ivr only)
    open → entry menu closed → after-hours + voicemail
  3. Menu - gather one digit
    dial submenu voicemail message optout repeat
  4. Warm transfer on dial
    The agent hears a whisper before bridging; the caller can press * to leave. Unanswered calls fall through to voicemail.
  5. Post-call menu
    After the agent call ends, the caller can return to the menu instead of being dropped.

04Outbound campaigns

Appointment reminders and surveys are paced one recipient at a time. Every send passes three gates, re-checked at dial time.

Gate 1 Not opted out

Suppression / DNC list, matched on canonical E.164 so (415) 555-0123 and +14155550123 are the same person.

Gate 2 Has consent

Granted for this purpose and this channel. SMS and WhatsApp consent are distinct from voice.

Gate 3 Inside hours

Calling-window check. Outbound fails closed: no window configured means nothing is dialed.

Send →

voice · SMS · WhatsApp

Supporting mechanics

Background runner

Launches run in a thread so the dashboard returns at once; a SQLite single-flight lock stops two workers dialing the same campaign.

Press 0 for an agent

Reminder recipients can be warm-transferred to a live agent mid-call, with a whisper and a no-answer fallback.

STOP / START

An inbound STOP writes an opt-out instantly; START re-subscribes. Honored across SMS and WhatsApp.

05Capabilities

Each capability is a small, self-contained module.

CapabilityDescription
Surveys & resultsDTMF answers with optional labels (1=Poor…), a per-question breakdown with bars, and label-aware or raw CSV export.
Phone validatorOffline libphonenumber - validity, line type, region, carrier, timezones - cross-checked against your own opt-out and consent records.
Voices & AMDPer-campaign and per-menu Amazon Polly voices; per-campaign answering-machine detection.
Messages logEvery outbound text and inbound reply, with delivery status and a direction filter.
PGP exportsResult CSVs with PII download as .csv.pgp to a configured public key - or the export aborts rather than leak plaintext.
At-rest encryptionSet a key and the whole database opens with SQLCipher; if the driver is missing, the app refuses to start unencrypted.

06Telegram operator console

A second control surface beside the dashboard: an interactive bot that mirrors the same operations and reuses the same consent gates, so the two can never drift.

Module layout

PathModules
tgbot/api (long-poll, requests) · middleware (auth · rate-limit · locale) · handlers · keyboards · i18n · access · payments

Features

Full operator parity

Live stats, launch / pause campaigns, add consent-checked recipients, manage opt-outs, flip inbound mode, and validate numbers - all from inline keyboards.

Allowlist + roles

Access is per Telegram ID, never open. Bootstrap admins from env; roles mirror the dashboard - viewer reads, operator changes state, admin manages operators. Every action is audited.

Localized

Five languages - English, Spanish, French, Portuguese, German - chosen in-chat, each with its own slash-command menu.

Optional paid access

A user who isn't on the allowlist sees their own ID to request access, plus buy-access buttons - Telegram Stars or Crypto Pay - and a Learn-more link. A completed payment grants a console role for a configurable window, recorded in tg_payments for accountability.

Same safety model

Phone numbers in bot views are masked like the alerts; there is no identity-secret surface; and paid access only ever grants an operator-console role - never the consent, opt-out, or calling-time gates.

07Provider matrix

One interface, selected per channel by env var. Voice reuses the same TwiML - Telnyx reads it as TeXML. console logs instead of sending, for free local testing.

ProviderSMSVoiceWhatsAppNotes
twilioYesYes - TwiMLYesDefault backend.
telnyxYesYes - TeXML-Voice via a TeXML application.
plivoYes--SMS only here.
vonageYes--SMS only here.
consoleYesYesYesLogs - no account, no charges.

08Design principles

Enforced in code, not just documented.

01
No identity secrets

No prompt, route, or column for OTPs, SSNs, card numbers, or passcodes. The only digit the IVR reads is a menu selection.

02
Truthful identity

Prompts speak your real organization name; caller ID is a number you own. No spoofing configuration exists.

03
Consent before contact

Dialing lists come only from granted consent, re-checked per recipient at send time.

04
Always honor opt-out

Checked before every outbound call or text; callers opt out by keypress or STOP.

05
Recording off by default

When enabled, the disclosure plays before any audio is captured.

06
Authenticated access everywhere

Every carrier webhook is signature-verified; the Telegram console is an explicit per-user allowlist with roles.

09Out of scope

By design: no "is this number on WhatsApp / Telegram" presence check and no profile scraping. Those abuse a messenger's contact-sync and enable bulk enumeration of people without consent - the opposite of what this platform is for. The Telegram bot is an operator console, not a presence lookup.

10Compliance responsibilities

The system provides the controls; compliance is how you operate it. Still your responsibility:

  • The telemarketing, calling-time, recording-consent, and privacy laws that apply to you.
  • TCPA, state two-party-consent recording rules, and local equivalents.
  • Obtaining appropriate legal guidance for your specific use case.
Reminder: ConsentIVR provides technical controls to support consent-based communication, but software controls do not by themselves guarantee legal compliance.