Skip to main content
Consuelo uses a conference-based architecture for all calls, enabling advanced features like transfers and hold.

Why Conferences?

Using Twilio Conferences instead of direct calls provides:
  1. Transfers - Add/remove participants without dropping the call
  2. Hold - Put caller on hold while keeping the session
  3. Multi-party - Support for warm transfers and coaching
  4. Recording - Single recording of the entire call

Architecture Overview

┌─────────────┐     device.connect()     ┌─────────────┐
│   Browser   │ ──────────────────────→  │   Twilio    │
│ (Twilio SDK)│                         │   Voice     │
└─────────────┘                         └──────┬──────┘
       │                                        │
       │  POST /v1/voice/twiml                  │
       │ ─────────────────────────────────→     │
       │                                        │
       │  Returns <Conference> TwiML            │
       │ ←─────────────────────────────────     │
       │                                        │
       ▼                                        ▼
┌─────────────┐                         ┌─────────────┐
│  Backend    │                         │  Conference │
│  (API)      │                         │  (Twilio)   │
└─────────────┘                         └──────┬──────┘

                                               │ Add customer
                                               │ via REST API

                                         ┌─────────────┐
                                         │  Customer   │
                                         │  (PSTN)     │
                                         └─────────────┘

Participant Labels

Each participant in a conference has a label:
LabelDescription
agentThe browser user (set via TwiML)
customerThe PSTN number being called
transfer-targetThe transfer recipient
Labels are set via:
  • Agent: participantLabel="agent" in TwiML
  • Customer: label="customer" in REST API call
  • Transfer target: Set during transfer initiation

Call Flow

  1. Browser calls device.connect({ To, From })
  2. Twilio hits POST /v1/voice/twiml webhook
  3. Backend creates conference conf-{uuid}
  4. Returns TwiML: <Conference startConferenceOnEnter="true">conf-{uuid}</Conference>
  5. Agent joins conference
  6. Backend dials customer into same conference

Conference Map

The backend maintains a mapping:
// callSid → conferenceName
conferenceMap.set(callSid, `conf-${uuid}`);
This is used for:
  • Finding the conference during transfers
  • Looking up hold status
  • Managing participant state
In production, this map should be stored in Redis for multi-instance deployments.