Spaces:
Sleeping
Sleeping
| import asyncio | |
| import json | |
| from livekit import api | |
| from livekit.protocol.sip import CreateSIPParticipantRequest | |
| from typing import List | |
| from src.config import settings | |
| def normalize_phone_number(phone_num: str) -> str: | |
| """ | |
| Ensure phone number is in proper E.164 format with + prefix | |
| This is crucial for Twilio SIP termination | |
| """ | |
| # Remove any existing + prefix | |
| clean_num = phone_num.lstrip('+') | |
| # Add + prefix for E.164 format | |
| return f"+{clean_num}" | |
| async def make_call(num: str, roomname: str, prompt: str): | |
| """ | |
| Create SIP participant with properly formatted phone number | |
| """ | |
| livekit_api = api.LiveKitAPI( | |
| url=settings.LIVEKIT_URL, | |
| api_key=settings.LIVEKIT_API_KEY, | |
| api_secret=settings.LIVEKIT_API_SECRET | |
| ) | |
| identity = "user-id" | |
| participant_metadata = json.dumps({ | |
| "prompt": prompt, | |
| }) | |
| # Normalize the phone number to E.164 format | |
| normalized_number = normalize_phone_number(num) | |
| print(f"Calling normalized number: {normalized_number}") | |
| request = CreateSIPParticipantRequest( | |
| sip_trunk_id=settings.SIP_TRUNK, | |
| sip_call_to=normalized_number, # Use normalized E.164 format | |
| room_name=roomname, | |
| participant_identity=identity, | |
| participant_name="new Caller", | |
| participant_metadata=participant_metadata, | |
| krisp_enabled=True, | |
| ) | |
| try: | |
| participant = await livekit_api.sip.create_sip_participant(request) | |
| print(f"Successfully created participant for {normalized_number}: {participant}") | |
| return participant | |
| except Exception as e: | |
| print(f"Error creating SIP participant for {normalized_number}: {str(e)}") | |
| # Log the exact request for debugging | |
| print(f"Request details: trunk_id={settings.SIP_TRUNK}, call_to={normalized_number}") | |
| raise | |
| finally: | |
| await livekit_api.aclose() | |
| async def process_call_list(call_list: List[dict]): | |
| """ | |
| Process list of calls with proper error handling and logging | |
| """ | |
| room_name_base = "room-testing" | |
| for i, payload in enumerate(call_list): | |
| num = payload.get('number') | |
| prompt = payload.get('prompt') | |
| if not num or not isinstance(prompt, str): | |
| print(f"Invalid payload at index {i}: {payload}") | |
| continue | |
| try: | |
| # Create unique room name | |
| room_name = f"{room_name_base}_{num.replace('+', '').replace(' ', '')}" | |
| print(f"Processing call {i+1}/{len(call_list)} to {num}") | |
| await make_call(num, room_name, prompt) | |
| # Add delay between calls to avoid rate limiting | |
| if i < len(call_list) - 1: # Don't wait after the last call | |
| await asyncio.sleep(2) | |
| except Exception as e: | |
| print(f"Error making call to {num}: {str(e)}") | |
| # Continue with next call instead of stopping | |
| # Additional debugging function | |
| async def test_single_call(phone_number: str, test_prompt: str = "Hello, this is a test call"): | |
| """ | |
| Test function to make a single call with detailed logging | |
| """ | |
| print(f"Testing call to: {phone_number}") | |
| print(f"Original number: {phone_number}") | |
| normalized = normalize_phone_number(phone_number) | |
| print(f"Normalized number: {normalized}") | |
| room_name = f"test-room-{normalized.replace('+', '').replace(' ', '')}" | |
| try: | |
| result = await make_call(normalized, room_name, test_prompt) | |
| print(f"Test call successful: {result}") | |
| return result | |
| except Exception as e: | |
| print(f"Test call failed: {str(e)}") | |
| return None | |
| # Example usage for testing | |
| async def main(): | |
| # Test with your Airtel number | |
| airtel_number = "919994893896" # Your Airtel number | |
| jio_number = "919876543210" # Replace with your working Jio number | |
| print("Testing Airtel number:") | |
| await test_single_call(airtel_number, "Hello, this is a test call to Airtel") | |
| await asyncio.sleep(5) | |
| print("\nTesting Jio number for comparison:") | |
| await test_single_call(jio_number, "Hello, this is a test call to Jio") | |
| if __name__ == "__main__": | |
| asyncio.run(main()) |