I'm using python server sdk. How do i setup dispat...
# ask-ai
g
I'm using python server sdk. How do i setup dispatch rule so for every incoming call automaticly created a room. And i also get on which phone number call is maid ? I have a platform and each of my client would have different numbers, so i need to make sure i launch correct script for each client
t
Thanks for reaching out, Andrii. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Setting up dispatch rules in the Python Server SDK to automatically create rooms for incoming calls and grab the phone number the call was made to is pretty straightforward! Here are two friendly ways to do it: 1. Individual Rooms for Each Caller: • Create a unique room for every incoming call using
SIPDispatchRuleIndividual
. • The rooms get named with the caller's phone number plus a little random suffix to keep things unique. • You can also add a special prefix to the room name with the
roomPrefix
option if you like.
Copy code
async def create_individual_dispatch_rule():
    lk_api = LiveKitAPI(url=livekit_url, api_key=livekit_api_key, api_secret=livekit_api_secret)
    dispatch_rule_request = CreateSIPDispatchRuleRequest(
        trunk_ids=[inbound_trunk.sip_trunk_id],
        rule=SIPDispatchRule(
            dispatch_rule_individual=SIPDispatchRuleIndividual(room_prefix="call")
        ),
    )
    dispatch_rule = await lk_api.sip.create_sip_dispatch_rule(dispatch_rule_request)
2. Rooms Based on Called Number: • Create rooms based on the phone number the call was made to using
SIPDispatchRuleCallee
. • Rooms are named with the called phone number plus an optional prefix to keep things clear. • If you want, you can add a random suffix for each caller by setting
randomize
to true.
Copy code
async def create_callee_dispatch_rule():
    lk_api = LiveKitAPI(url=livekit_url, api_key=livekit_api_key, api_secret=livekit_api_secret)
    dispatch_rule_request = CreateSIPDispatchRuleRequest(
        trunk_ids=[inbound_trunk.sip_trunk_id],
        rule=SIPDispatchRule(
            dispatch_rule_callee=SIPDispatchRuleCallee(
                room_prefix="number-",
                randomize=False
            )
        ),
    )
    dispatch_rule = await lk_api.sip.create_sip_dispatch_rule(dispatch_rule_request)
So, depending on what feels right for your setup—whether you want to pinpoint the exact number that was called (go with
SIPDispatchRuleCallee
) or just want unique rooms for each caller (try
SIPDispatchRuleIndividual
)—you've got options that make it easy to manage your calls. Sources: SIP dispatch rule | LiveKit Docs | SIP dispatch rule | LiveKit Docs | Agents telephony integration | LiveKit Docs | Creating SIP Inbound Trunks and Dispatch Rules with Python SDK
g
i will use second option with SIPDispatchRuleCallee. could you pls share how is the python code look like with automatic room creation?
t
Hey there! Here's a friendly Python code example to help you set up
SIPDispatchRuleCallee
with automatic room creation. This should make things a bit easier for you:
Copy code
from livekit import api
from livekit.protocol import sip

async def create_callee_dispatch_rule():
    # Initialize the LiveKit API client
    livekit_api = api.LiveKitAPI(
        url="your-livekit-url",
        api_key="your-api-key", 
        api_secret="your-api-secret"
    )
    
    try:
        # Create a SIPDispatchRuleCallee for automatic room creation
        dispatch_rule_info = sip.SIPDispatchRuleInfo(
            rule=sip.SIPDispatchRule(
                dispatch_rule_callee=sip.SIPDispatchRuleCallee(
                    room_prefix="number-",  # Optional prefix for room names
                    pin="",                 # Optional PIN protection
                    randomize=False         # Set to True for unique rooms per caller
                )
            ),
            name="Callee Dispatch Rule",
            metadata="Routes calls based on called number",
            trunk_ids=[],  # Empty means all trunks
            hide_phone_number=False
        )
        
        # Create the dispatch rule
        request = sip.CreateSIPDispatchRuleRequest(
            dispatch_rule=dispatch_rule_info
        )
        
        response = await livekit_api.sip.create_sip_dispatch_rule(request)
        print(f"Created dispatch rule: {response.sip_dispatch_rule_id}")
        
        return response
        
    finally:
        await livekit_api.aclose()

# Usage example
import asyncio

async def main():
    # Let's create that dispatch rule!
    result = await create_callee_dispatch_rule()
    print(f"Dispatch rule created with ID: {result.sip_dispatch_rule_id}")

if __name__ == "__main__":
    asyncio.run(main())
Quick heads-up on the key settings: • `room_prefix`: This adds a little prefix to your room name, like "number-". • `randomize`: Flip this to
True
if you want a random suffix, so each caller gets a unique room. • `pin`: You can set an optional PIN if you want to add a bit of extra security. So, with this setup, LiveKit will automatically create rooms based on the number being called. For example, if the called number is
+15551234567
and you set
room_prefix="number-"
, the room name will end up as
number-+15551234567
. Pretty neat, right? Sources: SIP dispatch rule | LiveKit Docs | livekit-protocol/livekit/protocol/sip.py
g
no . i meant after dispatch rule created how is the simple python code look like to attah to these rooms?
t
Hey there! If you want to attach to rooms created by
SIPDispatchRuleCallee
, here’s a friendly Python example to help you connect to and keep an eye on those rooms:
Copy code
import asyncio
from livekit import api

class CalleeRoomHandler:
    def __init__(self, api_key: str, api_secret: str, host: str):
        self.livekit_api = api.LiveKitAPI(host, api_key, api_secret)
    
    async def connect_to_callee_room(self, called_number: str, room_prefix: str = "number-"):
        """Connect to a room created by SIPDispatchRuleCallee"""
        
        room_name = f"{room_prefix}{called_number}"
        
        try:
            # First, let's check if the room exists
            rooms = await self.livekit_api.room.list_rooms(
                api.ListRoomsRequest()
            )
            
            room_exists = any(room.name == room_name for room in rooms.rooms)
            
            if room_exists:
                print(f"Found callee room: {room_name}")
                
                # Now, let's see who’s in the room
                participants = await self.livekit_api.room.list_participants(
                    api.ListParticipantsRequest(room=room_name)
                )
                
                print(f"Participants in {room_name}: {len(participants.participants)}")
                
                return room_name
            else:
                print(f"Room {room_name} does not exist yet")
                return None
                
        except Exception as e:
            print(f"Oops! There was an error connecting to the callee room: {e}")
            raise

# Here’s a quick example of how to use this
async def main():
    handler = CalleeRoomHandler(
        api_key="your_api_key",
        api_secret="your_api_secret", 
        host="your_livekit_host"
    )
    
    # Let’s connect to a room using the called number
    called_number = "+15105550123"
    await handler.connect_to_callee_room(called_number)

if __name__ == "__main__":
    asyncio.run(main())
Key Steps: • Create the room name by combining the prefix and the called number (like
number-+15105550123
). • Check if the room exists using
list_rooms
. • Get the list of participants in the room with
list_participants
. This example shows you how to easily connect to and monitor rooms created by
SIPDispatchRuleCallee
. If you have any questions or want to dive deeper, just let me know—I’m here to help! Sources: telephony/sip_lifecycle.py | Dispatching agents | LiveKit Docs | SIP dispatch rule | LiveKit Docs
g
for 1 called_number i would have multiple clients call it. for each would be created a separate room how do i ensure with my python application that i receive information for each room created, immediatly connect to that room and listen to published track? and publish tracks myself? how do i ensure that multiple rooms are served on my server?
t
Hey there! If you want to handle multiple rooms created by
SIPDispatchRuleCallee
, connect to each one, listen to published tracks, and publish your own, here’s a friendly Python example to get you started:
Copy code
import asyncio
from livekit import api, rtc
from typing import List

class SIPRoomManager:
    def __init__(self, room_prefix: str = "number-", randomize: bool = False):
        self.room_prefix = room_prefix
        self.randomize = randomize
        self.active_rooms = {}

    def get_room_name(self, phone_number: str) -> str:
        return f"{self.room_prefix}{phone_number}"

    async def connect_to_callee_rooms(self, phone_numbers: List[str], identity_prefix: str = "bot"):
        tasks = []
        for phone_number in phone_numbers:
            room_name = self.get_room_name(phone_number)
            identity = f"{identity_prefix}-{phone_number.replace('+', '').replace('-', '')}"
            task = asyncio.create_task(self.connect_and_handle_room(room_name, identity))
            tasks.append(task)
        await asyncio.gather(*tasks)

    async def connect_and_handle_room(self, room_name: str, identity: str):
        room = rtc.Room()

        @room.on("track_subscribed")
        def on_track_subscribed(track, publication, participant):
            print(f"Track subscribed in {room_name}: {publication.sid}")

        token = (
            api.AccessToken()
            .with_identity(identity)
            .with_grants(api.VideoGrants(room_join=True, room=room_name))
            .to_jwt()
        )

        try:
            await room.connect("your-livekit-url", token)
            print(f"Connected to room: {room_name}")
            self.active_rooms[room_name] = room
            await self.publish_tracks_to_room(room)
            await self.monitor_room(room, room_name)
        except Exception as e:
            print(f"Oops, failed to connect to room {room_name}: {e}")

    async def publish_tracks_to_room(self, room):
        video_source = rtc.VideoSource(width=1280, height=720)
        video_track = rtc.LocalVideoTrack.create_video_track("video", video_source)
        audio_source = rtc.AudioSource(sample_rate=48000, num_channels=2)
        audio_track = rtc.LocalAudioTrack.create_audio_track("audio", audio_source)

        await room.local_participant.publish_track(video_track)
        await room.local_participant.publish_track(audio_track)
        print(f"Published tracks to room: {room.name}")

    async def monitor_room(self, room, room_name):
        try:
            while room.isconnected():
                await asyncio.sleep(1)
        except Exception as e:
            print(f"Room {room_name} monitoring error: {e}")
        finally:
            if room_name in self.active_rooms:
                del self.active_rooms[room_name]

# Example usage
async def main():
    room_manager = SIPRoomManager(room_prefix="number-", randomize=True)
    phone_numbers = ["+15551234567", "+15559876543"]
    await room_manager.connect_to_callee_rooms(phone_numbers, "sip-bot")

if __name__ == "__main__":
    asyncio.run(main())
Here’s what this does for you: • Creates room names based on the called number and a prefix, making it easy to organize. • Connects to each room and listens for any tracks being published. • Publishes your own audio and video tracks into the room. • Keeps an eye on room activity and handles disconnections smoothly. Hope this helps you manage multiple rooms effortlessly! If you have any questions or want to tweak this further, just give me a shout—I’m here to help! Sources: SIP APIs | LiveKit Docs | SIP dispatch rule | LiveKit Docs | examples/room_example.py | test/lktest/livekit.go