Skip to main content

Telephony adapters for converting recordings to vCon format - supports Twilio and more

Project description

vCon Telephony Adapters

A monorepo of webhook-based adapters that convert telephony platform recordings into vCon (Virtual Conversation) format and post them to a vCon conserver.

Overview

This project provides a unified framework for converting call recordings from various telephony platforms into the standardized vCon format:

  • Twilio - Convert Twilio call recordings via webhooks
  • FreeSWITCH - Convert FreeSWITCH recordings via mod_http_cache events
  • Asterisk - Convert Asterisk recordings via ARI events
  • Telnyx - Convert Telnyx call recordings via webhooks
  • Bandwidth - Convert Bandwidth call recordings via webhooks

Architecture

vcon-telephony-adapters/
├── core/                    # Shared core modules
│   ├── base_builder.py      # Abstract vCon builder
│   ├── base_config.py       # Base configuration
│   ├── poster.py            # HTTP posting to conserver
│   └── tracker.py           # State tracking for duplicates
├── adapters/                # Platform-specific adapters
│   ├── twilio/              # Twilio adapter
│   ├── freeswitch/          # FreeSWITCH adapter
│   ├── asterisk/            # Asterisk adapter
│   ├── telnyx/              # Telnyx adapter
│   └── bandwidth/           # Bandwidth adapter
├── twilio_adapter/          # Backwards compatibility layer
├── tests/                   # Test suite
└── main.py                  # CLI entry point

Requirements

  • Python 3.10+
  • vcon-lib - The vCon library for creating vCon objects

Installation

Prerequisites

First, install the vcon library:

pip install git+https://github.com/vcon-dev/vcon-lib.git

Using pip

pip install -e .

Development installation

pip install -e ".[dev]"

Quick Start

Running an adapter

# Twilio
vcon-adapter twilio

# FreeSWITCH
vcon-adapter freeswitch

# Asterisk
vcon-adapter asterisk

# Telnyx
vcon-adapter telnyx

# Bandwidth
vcon-adapter bandwidth

Twilio Adapter

Configuration

# Required
CONSERVER_URL=https://your-conserver.example.com/api/vcons
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token_here

# Optional
PORT=8080
VALIDATE_TWILIO_SIGNATURE=true
WEBHOOK_URL=https://your-domain.com
DOWNLOAD_RECORDINGS=true
RECORDING_FORMAT=wav

Twilio Configuration Options

Variable Required Default Description
TWILIO_ACCOUNT_SID Yes* - Your Twilio Account SID
TWILIO_AUTH_TOKEN Yes* - Your Twilio Auth Token
VALIDATE_TWILIO_SIGNATURE No true Validate webhook signatures
WEBHOOK_URL No - Public URL for signature validation

* Required when DOWNLOAD_RECORDINGS=true or VALIDATE_TWILIO_SIGNATURE=true

Configuring Twilio

  1. In your Twilio console, configure your phone number or TwiML app to record calls.

  2. Set the Recording Status Callback URL to your adapter endpoint:

    https://your-domain.com/webhook/recording
    
  3. Select the recording status events you want to receive (at minimum, completed).

Using with TwiML

<Response>
    <Record
        recordingStatusCallback="https://your-domain.com/webhook/recording"
        recordingStatusCallbackEvent="completed"
    />
</Response>

FreeSWITCH Adapter

Configuration

# Required
CONSERVER_URL=https://your-conserver.example.com/api/vcons

# FreeSWITCH-specific
FREESWITCH_HOST=localhost
FREESWITCH_ESL_PORT=8021
FREESWITCH_RECORDINGS_PATH=/var/lib/freeswitch/recordings
FREESWITCH_RECORDINGS_URL_BASE=https://fs.example.com/recordings
FREESWITCH_WEBHOOK_SECRET=your_webhook_secret

# Optional
PORT=8082
VALIDATE_FREESWITCH_WEBHOOK=false
DOWNLOAD_RECORDINGS=true
RECORDING_FORMAT=wav

FreeSWITCH Configuration Options

Variable Required Default Description
FREESWITCH_HOST No localhost FreeSWITCH host
FREESWITCH_ESL_PORT No 8021 ESL port
FREESWITCH_RECORDINGS_PATH No /var/lib/freeswitch/recordings Local recordings path
FREESWITCH_RECORDINGS_URL_BASE No - URL base for HTTP downloads
FREESWITCH_WEBHOOK_SECRET No - HMAC secret for webhook validation
VALIDATE_FREESWITCH_WEBHOOK No false Enable webhook signature validation

Configuring FreeSWITCH

Add mod_http_cache or a custom event handler to send recording events to the webhook:

# In your dialplan, after recording:
<action application="curl" data="https://your-domain.com/webhook/recording post ${recording_data}"/>

The webhook expects JSON data with FreeSWITCH event variables (uuid, caller_id_number, destination_number, etc.).


Asterisk Adapter

Configuration

# Required
CONSERVER_URL=https://your-conserver.example.com/api/vcons

# Asterisk-specific (for ARI access)
ASTERISK_HOST=localhost
ASTERISK_ARI_PORT=8088
ASTERISK_ARI_USERNAME=asterisk
ASTERISK_ARI_PASSWORD=asterisk
ASTERISK_RECORDINGS_PATH=/var/spool/asterisk/recording

# Optional
PORT=8083
VALIDATE_ASTERISK_WEBHOOK=false
ASTERISK_WEBHOOK_SECRET=your_webhook_secret
DOWNLOAD_RECORDINGS=true
RECORDING_FORMAT=wav

Asterisk Configuration Options

Variable Required Default Description
ASTERISK_HOST No localhost Asterisk host
ASTERISK_ARI_PORT No 8088 ARI HTTP port
ASTERISK_ARI_USERNAME No - ARI username
ASTERISK_ARI_PASSWORD No - ARI password
ASTERISK_RECORDINGS_PATH No /var/spool/asterisk/recording Local recordings path
ASTERISK_WEBHOOK_SECRET No - HMAC secret for webhook validation
VALIDATE_ASTERISK_WEBHOOK No false Enable webhook signature validation

Configuring Asterisk

Use a Stasis application or AGI script to send recording events to the webhook endpoint:

// ARI recording finished handler example
client.on('RecordingFinished', function(event) {
    // POST to https://your-domain.com/webhook/recording
});

Telnyx Adapter

Configuration

# Required
CONSERVER_URL=https://your-conserver.example.com/api/vcons
TELNYX_API_KEY=KEY_xxxxxxxxxxxxx

# Optional
PORT=8084
VALIDATE_TELNYX_WEBHOOK=false
TELNYX_PUBLIC_KEY=your_public_key_for_signature_validation
DOWNLOAD_RECORDINGS=true
RECORDING_FORMAT=wav

Telnyx Configuration Options

Variable Required Default Description
TELNYX_API_KEY Yes* - Telnyx API key for downloading recordings
TELNYX_PUBLIC_KEY No - Public key for webhook signature validation
VALIDATE_TELNYX_WEBHOOK No false Enable webhook signature validation

* Required when DOWNLOAD_RECORDINGS=true

Configuring Telnyx

  1. In the Telnyx Mission Control Portal, configure your Call Control Application.

  2. Set the Webhook URL for recording events:

    https://your-domain.com/webhook/recording
    
  3. Enable call.recording.saved events.


Bandwidth Adapter

Configuration

# Required
CONSERVER_URL=https://your-conserver.example.com/api/vcons
BANDWIDTH_ACCOUNT_ID=your_account_id
BANDWIDTH_USERNAME=your_api_username
BANDWIDTH_PASSWORD=your_api_password

# Optional
PORT=8085
VALIDATE_BANDWIDTH_WEBHOOK=false
BANDWIDTH_WEBHOOK_USERNAME=webhook_user
BANDWIDTH_WEBHOOK_PASSWORD=webhook_pass
DOWNLOAD_RECORDINGS=true
RECORDING_FORMAT=wav

Bandwidth Configuration Options

Variable Required Default Description
BANDWIDTH_ACCOUNT_ID Yes - Bandwidth Account ID
BANDWIDTH_USERNAME Yes* - API username for downloading recordings
BANDWIDTH_PASSWORD Yes* - API password for downloading recordings
BANDWIDTH_WEBHOOK_USERNAME No - HTTP Basic Auth username for webhook
BANDWIDTH_WEBHOOK_PASSWORD No - HTTP Basic Auth password for webhook
VALIDATE_BANDWIDTH_WEBHOOK No false Enable HTTP Basic Auth validation

* Required when DOWNLOAD_RECORDINGS=true

Configuring Bandwidth

  1. In the Bandwidth Dashboard, configure your Voice Application.

  2. Set the Callback URL for recording events:

    https://your-domain.com/webhook/recording
    
  3. Optionally configure HTTP Basic Authentication credentials.


Common Configuration

All adapters share these common configuration options:

Variable Required Default Description
CONSERVER_URL Yes - URL of your vCon conserver endpoint
CONSERVER_API_TOKEN No - API token for conserver authentication
CONSERVER_HEADER_NAME No x-conserver-api-token Header name for API token
HOST No 0.0.0.0 Host to bind the server to
PORT No 8080 Port to run the server on
DOWNLOAD_RECORDINGS No true Download and embed recording audio
RECORDING_FORMAT No wav Recording format (wav or mp3)
INGRESS_LISTS No - Comma-separated routing lists for conserver
STATE_FILE No .{adapter}_state.json State tracking file
LOG_LEVEL No INFO Logging level

API Endpoints

All adapters expose the same endpoint structure:

POST /webhook/recording

Receives recording events from the telephony platform.

Response: Always returns 200 OK with body "OK" to acknowledge receipt.

GET /health

Health check endpoint.

Response:

{
    "status": "healthy",
    "service": "vcon-{platform}-adapter"
}

GET /status/{recording_id}

Get the processing status for a specific recording.

Response (200):

{
    "recording_id": "rec-xxxxx",
    "vcon_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "status": "success"
}

vCon Structure

All adapters create vCons with this structure:

{
    "vcon": "0.0.1",
    "uuid": "auto-generated-uuid",
    "created_at": "2025-01-21T10:30:00+00:00",
    "parties": [
        {"tel": "+15551234567"},
        {"tel": "+15559876543"}
    ],
    "dialog": [
        {
            "type": "recording",
            "start": "2025-01-21T10:30:00+00:00",
            "duration": 120.0,
            "parties": [0, 1],
            "originator": 0,
            "mimetype": "audio/wav",
            "body": "base64-encoded-audio-data",
            "encoding": "base64"
        }
    ]
}

Platform-Specific Tags

Each adapter adds metadata tags to the vCon:

Twilio:

  • source: twilio_adapter
  • recording_sid, call_sid, account_sid
  • direction, recording_source
  • Caller/called geographic info

FreeSWITCH:

  • source: freeswitch_adapter
  • freeswitch_uuid, caller_name
  • account_code, freeswitch_context
  • sip_user_agent

Asterisk:

  • source: asterisk_adapter
  • asterisk_channel, asterisk_uniqueid
  • linkedid, dialplan_context
  • sip_user_agent, asterisk_language

Telnyx:

  • source: telnyx_adapter
  • telnyx_recording_id, telnyx_call_session_id
  • telnyx_call_control_id, telnyx_connection_id
  • recording_channels

Bandwidth:

  • source: bandwidth_adapter
  • bandwidth_recording_id, bandwidth_call_id
  • bandwidth_account_id, bandwidth_application_id
  • recording_channels

Development

Running tests

# Run all tests with coverage
pytest

# Run tests for a specific adapter
pytest tests/adapters/twilio/
pytest tests/adapters/freeswitch/
pytest tests/adapters/asterisk/
pytest tests/adapters/telnyx/
pytest tests/adapters/bandwidth/

# Run with verbose output
pytest -v

The test suite includes 157+ tests covering all adapters with configuration, builder, and webhook tests.

Code formatting

black .
ruff check .

Type checking

mypy core adapters

Adding New Adapters

To add support for a new telephony platform:

  1. Create a new directory in adapters/:

    adapters/
    └── yourplatform/
        ├── __init__.py
        ├── config.py      # Extend BaseConfig
        ├── builder.py     # Extend BaseVconBuilder
        └── webhook.py     # FastAPI endpoints
    
  2. Implement the platform-specific recording data class by extending BaseRecordingData

  3. Implement the builder by extending BaseVconBuilder and implementing _download_recording()

  4. Create the webhook endpoints in a create_app() function

  5. Register the adapter in main.py

Deployment

Docker

FROM python:3.11-slim

WORKDIR /app
COPY . .

# Install vcon library
RUN pip install git+https://github.com/vcon-dev/vcon-lib.git
RUN pip install -e .

EXPOSE 8080
CMD ["vcon-adapter", "twilio"]

Docker Compose (Multiple Adapters)

version: '3.8'
services:
  twilio-adapter:
    build: .
    ports:
      - "8080:8080"
    environment:
      - CONSERVER_URL=https://your-conserver.example.com/api/vcons
      - TWILIO_ACCOUNT_SID=${TWILIO_ACCOUNT_SID}
      - TWILIO_AUTH_TOKEN=${TWILIO_AUTH_TOKEN}
    command: ["vcon-adapter", "twilio"]

  telnyx-adapter:
    build: .
    ports:
      - "8084:8084"
    environment:
      - CONSERVER_URL=https://your-conserver.example.com/api/vcons
      - TELNYX_API_KEY=${TELNYX_API_KEY}
      - PORT=8084
    command: ["vcon-adapter", "telnyx"]

  bandwidth-adapter:
    build: .
    ports:
      - "8085:8085"
    environment:
      - CONSERVER_URL=https://your-conserver.example.com/api/vcons
      - BANDWIDTH_ACCOUNT_ID=${BANDWIDTH_ACCOUNT_ID}
      - BANDWIDTH_USERNAME=${BANDWIDTH_USERNAME}
      - BANDWIDTH_PASSWORD=${BANDWIDTH_PASSWORD}
      - PORT=8085
    command: ["vcon-adapter", "bandwidth"]

Production Checklist

  1. Enable webhook validation for your platform
  2. Store credentials securely (e.g., in a secrets manager)
  3. Use HTTPS for all endpoints
  4. Configure a persistent volume for the state file
  5. Set appropriate LOG_LEVEL (e.g., WARNING or ERROR for production)
  6. Consider running multiple adapter instances behind a load balancer

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vcon_telephony_adapters-0.2.0.tar.gz (50.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vcon_telephony_adapters-0.2.0-py3-none-any.whl (48.6 kB view details)

Uploaded Python 3

File details

Details for the file vcon_telephony_adapters-0.2.0.tar.gz.

File metadata

  • Download URL: vcon_telephony_adapters-0.2.0.tar.gz
  • Upload date:
  • Size: 50.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for vcon_telephony_adapters-0.2.0.tar.gz
Algorithm Hash digest
SHA256 69011a6941164156886018dee860d252151ceb86b3f1e87a6ee2ccc78abe6386
MD5 7ef0678ec1ebda3f3a17ca81fb4ff827
BLAKE2b-256 d48074e28903c9d8184ef245d3ad337bb8568259bf878734181fcb67976ef01b

See more details on using hashes here.

File details

Details for the file vcon_telephony_adapters-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for vcon_telephony_adapters-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d7dd012499e08bcb42632c9a4d00a90c16a8564d9e859173f662afc8fcc93b58
MD5 3b8a851d76b69c128622b42a0d1cd78a
BLAKE2b-256 3b2e3479e3b2d7009a9e8c2004ce2e8c355490e14f936500914899e35f291fd1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page