# Connect Twilio to LiveKit Backend (Voice Agent)

This project uses **Twilio** for the phone number and **LiveKit** for the voice AI backend. When someone calls your Twilio number, the call is routed to LiveKit and your Python agent answers.

**Twilio number (configured):** `+14632175613`  
**Credentials:** Stored in `twilio-mcp-server/.env` (Account SID, Auth Token). Do not commit.

---

## How it works

1. Caller dials **+14632175613**.
2. **Twilio** receives the call and sends it to **LiveKit SIP** (origination URI).
3. **LiveKit** creates a room and a SIP participant, and applies your **dispatch rule**.
4. Your **Python agent** (BackEnd) gets a job and joins the room, then talks to the caller.

Your agent in `BackEnd/agent-starter-python` already supports SIP participants (telephony noise cancellation). No code changes are required there once Twilio and LiveKit are configured.

---

## 1. Twilio: Send calls to LiveKit

1. Open [Twilio Console](https://console.twilio.com/) → **Elastic SIP Trunking** → **Trunks** (or **Voice** → **Manage** → **Origination**).
2. Create or select a **SIP Trunk** for this number.
3. Set the **Origination SIP URI** to your **LiveKit SIP URI** with `;transport=tcp`:
   - Get your LiveKit SIP URI from: [LiveKit Cloud](https://cloud.livekit.io/) → your project → **Settings** → **SIP URI**.
   - It looks like: `sip:XXXXX.sip.livekit.cloud;transport=tcp`  
     (e.g. for URL `wss://test-voice-bot-fd6qy6cu.livekit.cloud` the SIP host is usually `test-voice-bot-fd6qy6cu.sip.livekit.cloud`).
4. Associate your phone number **+14632175613** with this trunk (Trunk → Phone Numbers).

Detailed steps: [LiveKit – Configuring Twilio trunk](https://docs.livekit.io/sip/quickstarts/configuring-twilio-trunk.md).

---

## 2. LiveKit Cloud: Accept calls and dispatch to the agent

1. Open [LiveKit Cloud](https://cloud.livekit.io/) → your project → **Telephony** → **SIP Trunks**.
2. **Create inbound trunk**
   - Name: e.g. `Twilio inbound`
   - Numbers: `+14632175613`
   - (Optional) Enable Krisp noise cancellation.
3. **Create dispatch rule**
   - **Telephony** → **Dispatch rules** → Create.
   - Attach it to the trunk you created.
   - Rule: e.g. put each call in a unique room with prefix `call-` (so the agent gets one participant per call).

After this, when someone calls +14632175613, LiveKit creates a room and your **Python agent** (running with the same LiveKit project credentials in `BackEnd/agent-starter-python/.env.local`) will join and handle the call.

---

## Outbound calls (Twilio call button)

The app has a **Twilio call** button that opens a popup where you enter a phone number and trigger an outbound call. The call is placed via **Twilio Programmable Voice**, and your existing Twilio → LiveKit inbound setup handles bridging the call into LiveKit so the agent can join.

**Requirements:**

1. **TwiML Bin (or webhook) that dials LiveKit**  
   In Twilio Console:
   - Create a **TwiML Bin** with contents like:

     ```xml
     <?xml version="1.0" encoding="UTF-8"?>
     <Response>
       <Dial>
         <Sip>sip:+14632175613@<your SIP endpoint>;transport=tcp</Sip>
       </Dial>
     </Response>
     ```

   - Replace `<your SIP endpoint>` with your LiveKit SIP host from LiveKit Cloud (e.g. `test-voice-bot-fd6qy6cu.sip.livekit.cloud`).
   - This is the same endpoint you used for inbound Twilio → LiveKit calls.

2. **Configure the Twilio number to use that TwiML**  
   - In **Phone Numbers → Manage → Active numbers**, open `+14632175613`.
   - Under **Voice configuration**, set “A call comes in” to use the TwiML Bin you created.

3. **Env vars for the frontend**  
   In the **frontend** `.env.local` (e.g. `FrontEnd/agent-starter-react/agent-starter-react/.env.local`) set:

   ```env
   TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   TWILIO_AUTH_TOKEN=your_auth_token_here
   TWILIO_PHONE_NUMBER=+14632175613
   TWILIO_TWIML_URL=https://handler.twilio.com/twiml/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   ```

   - `TWILIO_TWIML_URL` is the URL of the TwiML Bin from step 1.

The API route `POST /api/twilio/outbound-call` calls Twilio’s `calls.create` with `from = TWILIO_PHONE_NUMBER`, `to = <number you enter>`, and `url = TWILIO_TWIML_URL`. Twilio dials the user, then uses your TwiML to bridge the call into LiveKit.

---

## 3. Run the backend agent

From `BackEnd/agent-starter-python`:

```bash
cd BackEnd/agent-starter-python
uv run python src/agent.py
```

Use the same **LIVEKIT_URL**, **LIVEKIT_API_KEY**, and **LIVEKIT_API_SECRET** as in your LiveKit project (already in `.env.local`). The agent will accept both web and SIP (phone) participants.

---

## Summary

| Item        | Value / Location |
|------------|------------------|
| Twilio number | +14632175613 |
| Twilio credentials | `twilio-mcp-server/.env` (Account SID, Auth Token) |
| LiveKit backend | `BackEnd/agent-starter-python` (Python agent) |
| LiveKit config | `.env.local` (LIVEKIT_URL, API_KEY, API_SECRET) |
| Twilio → LiveKit | Set Twilio origination URI to LiveKit SIP URI |
| LiveKit → agent | Inbound trunk (+14632175613) + dispatch rule → room → agent joins |
