# Telephony Integration Guide

#### How It Works

```
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Phone Callers  │────▶│  Your Voice     │────▶│  Digital Samba  │
│  (PSTN)         │     │  API Provider   │     │  Room           │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                              │
                              │ SIP Connection
                              ▼
                        ┌─────────────────┐
                        │  Your Middleware│
                        │  Application    │
                        └─────────────────┘
```

The integration consists of:

1. **Voice API Provider** - Handles phone calls, IVR prompts, and PSTN conferencing (e.g., Twilio, Sinch, Vonage, Plivo)
2. **SIP Trunk** - Connects your Voice API to Digital Samba
3. **Middleware Application** - Routes calls, manages PINs, and synchronises state between your Voice API and Digital Samba
4. **Digital Samba Room** - Video conferencing room with telephony enabled

### Prerequisites

Before starting your integration:

1. **Digital Samba Account** with API access
2. **Voice API Provider Account** with:
   * A phone number for incoming calls
   * Voice/conferencing API access
   * SIP trunking capability
3. **SIP Trunk Configuration** - Contact Digital Samba support to configure IP whitelisting and authentication for your SIP trunk

> **Important**: Before proceeding with implementation, contact Digital Samba support to set up your SIP trunk. Provide your SIP provider details and we will guide you through IP whitelisting and authentication configuration.

### Architecture Overview

#### System Components

```
┌────────────────────────────────────────────────────────────────────────┐
│                        Your Integration                                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  ┌──────────────┐      ┌──────────────────┐      ┌──────────────────┐  │
│  │  Voice API   │      │   Middleware     │      │   Digital Samba  │  │
│  │  Provider    │◀────▶│   Application    │◀────▶│   API            │  │
│  │              │      │                  │      │                  │  │
│  │ • Phone #    │      │ • Call routing   │      │ • Room creation  │  │
│  │ • IVR        │      │ • PIN validation │      │ • Phone user API │  │
│  │ • Conference │      │ • SIP control    │      │ • Webhooks       │  │
│  │ • SIP trunk  │      │ • State sync     │      │ • Mute control   │  │
│  └──────────────┘      └──────────────────┘      └──────────────────┘  │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
```

#### Call Flow Sequence

```
Phone User              Voice Provider          Your App            Digital Samba
    │                        │                     │                     │
    │ 1. Dial phone number   │                     │                     │
    │───────────────────────▶│                     │                     │
    │                        │ 2. Webhook: ICE     │                     │
    │                        │────────────────────▶│                     │
    │                        │                     │                     │
    │ 3. IVR: "Enter PIN"    │                     │                     │
    │◀───────────────────────│◀────────────────────│                     │
    │                        │                     │                     │
    │ 4. Enter PIN (e.g. 123)│                     │                     │
    │───────────────────────▶│ 5. DTMF callback    │                     │
    │                        │────────────────────▶│                     │
    │                        │                     │ 6. Validate PIN     │
    │                        │                     │───────┐             │
    │                        │                     │       │             │
    │                        │                     │◀──────┘             │
    │                        │ 7. Connect to conf  │                     │
    │                        │◀────────────────────│                     │
    │                        │                     │                     │
    │ 8. Joined conference   │                     │ 9. Phone user joined│
    │◀───────────────────────│                     │────────────────────▶│
    │                        │                     │                     │
    │ 10. Hear room audio    │                     │                     │
    │◀═══════════════════════│═════════════════════│═════════════════════│
    │                        │ (via SIP bridge)    │                     │
```

### Step 1: Configure Digital Samba Room

#### Create a Telephony-Enabled Room

When creating a room via the API, include the telephony configuration:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "My Telephony Room",
    "friendly_url": "telephony-room",
    "telephony_enabled": true,
    "telephony_phone_number": "+1234567890",
    "telephony_pin_dtmf": "WWW123#"
  }'
```

#### Telephony Room Properties

| Property                 | Type    | Description                                                      |
| ------------------------ | ------- | ---------------------------------------------------------------- |
| `telephony_enabled`      | boolean | Enable telephony for this room                                   |
| `telephony_phone_number` | string  | The phone number for SIP to dial into your Voice API conference  |
| `telephony_pin_dtmf`     | string  | DTMF sequence for SIP to enter when connecting to the conference |

#### DTMF Sequence Format

The `telephony_pin_dtmf` field uses special characters:

| Character | Meaning                                    |
| --------- | ------------------------------------------ |
| `W`       | Wait 1 second (for IVR prompts)            |
| `w`       | Wait 0.5 seconds                           |
| `0-9`     | Dial digit                                 |
| `*`       | Dial asterisk                              |
| `#`       | Dial pound/hash (often used as terminator) |

**Example**: `WWW123#` means:

* Wait 3 seconds for IVR prompt
* Dial `123`
* Press `#` to confirm

### Step 2: Build Your Middleware Application

Your middleware application handles communication between your Voice API provider and Digital Samba.

#### Core Responsibilities

1. **Handle incoming calls** from your Voice API provider
2. **Play IVR prompts** and collect PIN input
3. **Route callers** to the correct conference based on PIN
4. **Manage SIP connection** to Digital Samba room
5. **Synchronise phone user state** with Digital Samba API
6. **Handle webhooks** from both Voice API and Digital Samba

#### Conference and PIN Management

Your application must maintain a mapping between:

* Digital Samba room IDs
* Voice API conference IDs
* PINs for phone callers
* PINs for SIP bridge connections

> **Important**: Voice API providers do not have inherent knowledge of conferences until you create them. You must build your own database and logic to:
>
> * Generate and assign PINs
> * Map PINs to conferences
> * Route callers based on PIN input

#### Example PIN Structure

```javascript
// Example conference mapping
const conferenceMapping = {
  conferences: {
    "conf_123": {
      digitalSambaRoomId: "a74d5723-6b98-45e3-8135-149e57fe9072",
      voiceApiConferenceId: "your-provider-conf-id",
      callerPins: ["1234", "5678", "9012"],  // PINs for phone users
      sipPin: "11",  // PIN for SIP bridge connection
      sipDtmfSequence: "WWW11#"
    }
  }
};
```

#### Identifying the SIP Connection

When the SIP bridge connects to your Voice API conference, you must identify it distinctly from regular phone callers. Common approaches:

1. **Reserved PIN** - Use a specific PIN only for SIP connections
2. **Display Name** - Check for a specific display name (e.g., starts with "SIP")
3. **Origination Type** - Check call metadata for SIP origin
4. **Domain** - Check if domain equals "SIP"

> **Critical**: Do NOT notify Digital Samba when the SIP bridge joins. The SIP connection is not a "real" phone user—it's the audio bridge between your Voice API conference and the Digital Samba room.

### Step 3: Digital Samba Phone User API

#### Notify When Phone Users Join

When a phone caller successfully joins your Voice API conference (after PIN validation and only after SIP is connected), notify Digital Samba:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants-joined \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "participants": [
      {
        "callId": "unique-call-identifier",
        "name": "Phone User 1",
        "callerNumber": "+1987654321",
        "externalId": "your-internal-user-id"
      }
    ]
  }'
```

**Request Parameters**

| Parameter      | Type   | Required | Description                                                 |
| -------------- | ------ | -------- | ----------------------------------------------------------- |
| `callId`       | string | Yes      | Unique identifier for this phone call (from your Voice API) |
| `name`         | string | No       | Display name for the phone user                             |
| `callerNumber` | string | No       | Phone number of the caller                                  |
| `externalId`   | string | No       | Your internal user identifier                               |

> **Note**: The `externalId` parameter is reserved for future functionality. It may be used to link phone participants with web participants who share the same external ID.

#### Notify When Phone Users Leave

When a phone caller disconnects:

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants-left \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "callIds": ["unique-call-identifier"]
  }'
```

#### Raise Hand for Phone User

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants/{callId}/raise-hand \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY
```

#### Lower Hand for Phone User

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/rooms/{room_id}/phone-participants/{callId}/lower-hand \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY
```

### Step 4: Configure Digital Samba Webhooks

Set up webhooks to receive events from Digital Samba rooms. This enables you to synchronise actions (like mute/unmute) with your Voice API.

#### Create a Webhook

```bash
curl --request POST \
  --url https://api.digitalsamba.com/api/v1/webhooks \
  --user YOUR_TEAM_ID:YOUR_DEVELOPER_KEY \
  --header 'Content-Type: application/json' \
  --data '{
    "endpoint": "https://your-app.com/webhooks/digitalsamba",
    "name": "Telephony Integration Webhook",
    "events": [
      "participant_joined",
      "participant_left",
      "session_started",
      "session_ended"
    ],
    "authorization_header": "your-webhook-secret"
  }'
```

#### Relevant Webhook Events

| Event                | Description                                         |
| -------------------- | --------------------------------------------------- |
| `participant_joined` | Triggered when any participant (web or phone) joins |
| `participant_left`   | Triggered when any participant leaves               |
| `session_started`    | Triggered when a room session begins                |
| `session_ended`      | Triggered when a room session ends                  |

#### Webhook Security

Always validate that webhook requests are legitimately from Digital Samba by checking the `Authorization` header matches your configured secret.

```javascript
// Example webhook validation
app.post('/webhooks/digitalsamba', (req, res) => {
  const authHeader = req.headers['authorization'];
  
  if (authHeader !== 'your-webhook-secret') {
    return res.status(401).send('Unauthorized');
  }
  
  // Process webhook
  const event = req.body;
  handleDigitalSambaEvent(event);
  
  res.status(200).send('OK');
});
```

### Step 5: Initiate SIP Connection

When a moderator in the Digital Samba room clicks "Connect Telephony" (requires the "Manage phone users" permission), Digital Samba initiates a SIP call to your Voice API.

#### What Happens

1. Digital Samba's SIP server calls the configured `telephony_phone_number`
2. Your Voice API answers and plays IVR
3. SIP sends the `telephony_pin_dtmf` sequence
4. Your application routes SIP to the correct conference
5. Room audio is now bridged to the PSTN conference

#### Important Timing

* Moderators should connect telephony **early in the session** if phone users are expected
* Phone users who call before SIP is connected will be in the Voice API conference but won't hear room audio
* Only notify Digital Samba of phone users **after** SIP has connected

### Step 6: Managing Phone Users in Room

Once connected, phone users appear in the Digital Samba participant list. Moderators can:

* **See phone users** in the participants panel
* **Mute/unmute phone users** via the menu
* **Remove phone users** from the room

#### Handling Mute/Unmute

When a moderator mutes a phone user in Digital Samba, you'll receive a webhook. Your middleware should then call your Voice API to mute that participant in the PSTN conference.

```javascript
// Example mute handler
function handleMuteEvent(event) {
  if (event.type === 'phone_participant_muted') {
    const callId = event.data.callId;
    
    // Call your Voice API to mute this participant
    voiceApi.muteParticipant(callId);
  }
}
```

### Integration Checklist

#### Before Development

* \[ ] Contact Digital Samba support to configure SIP trunk
* \[ ] Set up Voice API provider account with phone number
* \[ ] Understand your Voice API's webhook/callback structure
* \[ ] Plan your PIN/conference management strategy

#### Development

* \[ ] Create rooms with telephony enabled via API
* \[ ] Build middleware to handle Voice API callbacks
* \[ ] Implement IVR flow for PIN collection
* \[ ] Build PIN validation and conference routing
* \[ ] Integrate Digital Samba Phone User API
* \[ ] Set up webhook handlers for Digital Samba events
* \[ ] Implement mute/unmute synchronisation

#### Testing

* \[ ] Test phone dial-in flow end-to-end
* \[ ] Verify SIP connection with correct PIN/DTMF
* \[ ] Confirm phone users appear in Digital Samba room
* \[ ] Test mute/unmute from room to phone
* \[ ] Test phone user disconnect handling
* \[ ] Verify audio quality and latency

### API Reference

#### Phone Participants Endpoints

| Method | Endpoint                                                      | Description               |
| ------ | ------------------------------------------------------------- | ------------------------- |
| `POST` | `/api/v1/rooms/{room}/phone-participants-joined`              | Notify phone users joined |
| `POST` | `/api/v1/rooms/{room}/phone-participants-left`                | Notify phone users left   |
| `POST` | `/api/v1/rooms/{room}/phone-participants/{callId}/raise-hand` | Raise hand for phone user |
| `POST` | `/api/v1/rooms/{room}/phone-participants/{callId}/lower-hand` | Lower hand for phone user |

#### Room Creation with Telephony

Include these properties when creating or updating rooms:

```json
{
  "telephony_enabled": true,
  "telephony_phone_number": "+1234567890",
  "telephony_pin_dtmf": "WWW123#"
}
```

### Troubleshooting

#### SIP Connection Issues

| Issue                           | Possible Cause                  | Solution                                                 |
| ------------------------------- | ------------------------------- | -------------------------------------------------------- |
| SIP cannot connect              | IP not whitelisted              | Contact DS support to verify IP whitelist                |
| No audio after SIP connects     | Wrong DTMF sequence             | Verify PIN and timing in `telephony_pin_dtmf`            |
| SIP connects but no phone users | Phone users notified before SIP | Only call `phone-participants-joined` after SIP connects |

#### Common Mistakes

1. **Notifying Digital Samba when SIP joins** - The SIP bridge is not a phone user; do not send `phone-participants-joined` for it
2. **Phone users notified before SIP connects** - Phone users won't hear room audio until SIP is bridged; wait for SIP before notifying DS
3. **Missing DTMF terminator** - Many IVR systems require `#` to confirm PIN entry
4. **Insufficient wait time** - If IVR prompts are long, increase `W` characters in DTMF sequence

### Support

For assistance with your telephony integration:

* **SIP Trunk Configuration** : [Contact Digital Samba support](https://www.digitalsamba.com/embedded-support)
* **Platform Documentation**: [docs.digitalsamba.com](https://docs.digitalsamba.com/)
* **API Reference**: [developer.digitalsamba.com](https://developer.digitalsamba.com/)
* **Sinch Middleware demo middleware:** <https://github.com/digitalsamba/sinch-conference-middleware>

***

### Appendix: Example Application Architecture

```
┌──────────────────────────────────────────────────────────────────────────┐
│                         Middleware Application                           │
├──────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────────┐   │
│  │  Voice API      │    │  Conference     │    │  Digital Samba      │   │
│  │  Event Handler  │    │  Manager        │    │  Client             │   │
│  │                 │    │                 │    │                     │   │
│  │ /voice-events   │───▶│ • Create conf   │───▶│ • Phone user join   │   │
│  │                 │    │ • Validate PIN  │    │ • Phone user leave  │   │
│  │ • ICE callback  │    │ • Route caller  │    │ • Raise/lower hand  │   │
│  │ • DTMF input    │    │ • Track SIP     │    │                     │   │
│  │ • Call ended    │    │ • Track callers │    │                     │   │
│  └─────────────────┘    └─────────────────┘    └─────────────────────┘   │
│           │                      │                        ▲              │
│           │                      │                        │              │
│           ▼                      ▼                        │              │
│  ┌─────────────────────────────────────────────────────────────────┐     │
│  │                          Database                                 │   │
│  │                                                                   │   │
│  │  conferences: {room_id, voice_conf_id, caller_pins[], sip_pin}  │     │
│  │  active_calls: {call_id, conf_id, phone_number, is_sip}         │     │
│  └─────────────────────────────────────────────────────────────────┘     │
│                                                                          │
├──────────────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐                                                     │
│  │  DS Webhook     │◀────── Digital Samba webhook events                 │
│  │  Handler        │        (mute, unmute, session events)               │
│  │                 │                                                     │
│  │ /ds-webhooks    │───────▶ Voice API (mute participant, etc.)         │
│  └─────────────────┘                                                     │
└──────────────────────────────────────────────────────────────────────────┘
```

#### Data Flow Summary

1. **Incoming Call** → Voice API → Your App → Validate PIN → Join Conference
2. **SIP Connection** → Voice API Conference → Audio Bridge → Digital Samba Room
3. **Phone User Joins** → Your App → Digital Samba API (`phone-participants-joined`)
4. **Moderator Mutes** → Digital Samba → Webhook → Your App → Voice API Mute
5. **Phone User Leaves** → Voice API → Your App → Digital Samba API (`phone-participants-left`)
