Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ sip_svc = lkapi.sip

# Agent Dispatch
dispatch_svc = lkapi.agent_dispatch

# Connector Service
connector_svc = lkapi.connector
```

## Using Real-time SDK
Expand Down
3 changes: 3 additions & 0 deletions livekit-api/livekit/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
from livekit.protocol.room import *
from livekit.protocol.webhook import *
from livekit.protocol.sip import *
from livekit.protocol.connector_whatsapp import *
from livekit.protocol.connector_twilio import *

from .twirp_client import TwirpError, TwirpErrorCode
from .livekit_api import LiveKitAPI
Expand All @@ -54,6 +56,7 @@
"ingress_service",
"sip_service",
"agent_dispatch_service",
"connector_service",
"InferenceGrants",
"ObservabilityGrants",
"VideoGrants",
Expand Down
139 changes: 139 additions & 0 deletions livekit-api/livekit/api/connector_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from __future__ import annotations

import aiohttp

from livekit.protocol.connector_whatsapp import (
DialWhatsAppCallRequest,
DialWhatsAppCallResponse,
DisconnectWhatsAppCallRequest,
DisconnectWhatsAppCallResponse,
ConnectWhatsAppCallRequest,
ConnectWhatsAppCallResponse,
AcceptWhatsAppCallRequest,
AcceptWhatsAppCallResponse,
)
from livekit.protocol.connector_twilio import (
ConnectTwilioCallRequest,
ConnectTwilioCallResponse,
)
from ._service import Service
from .access_token import VideoGrants

SVC = "Connector"
"""@private"""


class ConnectorService(Service):
"""Client for LiveKit Connector Service API

Recommended way to use this service is via `livekit.api.LiveKitAPI`:

```python
from livekit import api
lkapi = api.LiveKitAPI()
connector_service = lkapi.connector
```
"""

def __init__(self, session: aiohttp.ClientSession, url: str, api_key: str, api_secret: str):
super().__init__(session, url, api_key, api_secret)

async def dial_whatsapp_call(
self, request: DialWhatsAppCallRequest
) -> DialWhatsAppCallResponse:
"""
Initiate an outbound WhatsApp call

Args:
request: DialWhatsAppCallRequest containing call parameters

Returns:
DialWhatsAppCallResponse with the WhatsApp call ID and room name
"""
return await self._client.request(
SVC,
"DialWhatsAppCall",
request,
self._auth_header(VideoGrants(room_create=True)),
DialWhatsAppCallResponse,
)

async def disconnect_whatsapp_call(
self, request: DisconnectWhatsAppCallRequest
) -> DisconnectWhatsAppCallResponse:
"""
Disconnect an active WhatsApp call

Args:
request: DisconnectWhatsAppCallRequest containing the call ID to disconnect

Returns:
DisconnectWhatsAppCallResponse (empty response)
"""
return await self._client.request(
SVC,
"DisconnectWhatsAppCall",
request,
self._auth_header(VideoGrants(room_create=True)),
DisconnectWhatsAppCallResponse,
)

async def connect_whatsapp_call(
self, request: ConnectWhatsAppCallRequest
) -> ConnectWhatsAppCallResponse:
"""
Connect a WhatsApp call with SDP information

Args:
request: ConnectWhatsAppCallRequest containing call ID and SDP

Returns:
ConnectWhatsAppCallResponse (empty response)
"""
return await self._client.request(
SVC,
"ConnectWhatsAppCall",
request,
self._auth_header(VideoGrants(room_create=True)),
ConnectWhatsAppCallResponse,
)

async def accept_whatsapp_call(
self, request: AcceptWhatsAppCallRequest
) -> AcceptWhatsAppCallResponse:
"""
Accept an inbound WhatsApp call

Args:
request: AcceptWhatsAppCallRequest containing call parameters and SDP

Returns:
AcceptWhatsAppCallResponse with the room name
"""
return await self._client.request(
SVC,
"AcceptWhatsAppCall",
request,
self._auth_header(VideoGrants(room_create=True)),
AcceptWhatsAppCallResponse,
)

async def connect_twilio_call(
self, request: ConnectTwilioCallRequest
) -> ConnectTwilioCallResponse:
"""
Connect a Twilio call to a LiveKit room

Args:
request: ConnectTwilioCallRequest containing call parameters

Returns:
ConnectTwilioCallResponse with the websocket URL for Twilio media stream
"""
return await self._client.request(
SVC,
"ConnectTwilioCall",
request,
self._auth_header(VideoGrants(room_create=True)),
ConnectTwilioCallResponse,
)
7 changes: 7 additions & 0 deletions livekit-api/livekit/api/livekit_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .ingress_service import IngressService
from .sip_service import SipService
from .agent_dispatch_service import AgentDispatchService
from .connector_service import ConnectorService
from typing import Optional


Expand Down Expand Up @@ -63,6 +64,7 @@ def __init__(
self._egress = EgressService(self._session, url, api_key, api_secret)
self._sip = SipService(self._session, url, api_key, api_secret)
self._agent_dispatch = AgentDispatchService(self._session, url, api_key, api_secret)
self._connector = ConnectorService(self._session, url, api_key, api_secret)

@property
def agent_dispatch(self) -> AgentDispatchService:
Expand All @@ -89,6 +91,11 @@ def sip(self) -> SipService:
"""Instance of the SipService"""
return self._sip

@property
def connector(self) -> ConnectorService:
"""Instance of the ConnectorService"""
return self._connector

async def aclose(self):
"""Close the API client

Expand Down
26 changes: 24 additions & 2 deletions livekit-protocol/generate_proto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ protoc \
$API_PROTOCOL/livekit_metrics.proto \
$API_PROTOCOL/livekit_sip.proto \
$API_PROTOCOL/livekit_analytics.proto \
$API_PROTOCOL/agent/livekit_agent_session.proto
$API_PROTOCOL/livekit_rtc.proto \
$API_PROTOCOL/agent/livekit_agent_session.proto \
$API_PROTOCOL/logger/options.proto \
$API_PROTOCOL/livekit_connector_whatsapp.proto \
$API_PROTOCOL/livekit_connector_twilio.proto \
$API_PROTOCOL/livekit_connector.proto


touch -a "$API_OUT_PYTHON/__init__.py"
Expand Down Expand Up @@ -69,11 +74,28 @@ mv "$API_OUT_PYTHON/livekit_sip_pb2.py" "$API_OUT_PYTHON/sip.py"
mv "$API_OUT_PYTHON/livekit_sip_pb2.pyi" "$API_OUT_PYTHON/sip.pyi"
mv "$API_OUT_PYTHON/livekit_metrics_pb2.py" "$API_OUT_PYTHON/metrics.py"
mv "$API_OUT_PYTHON/livekit_metrics_pb2.pyi" "$API_OUT_PYTHON/metrics.pyi"
mv "$API_OUT_PYTHON/livekit_rtc_pb2.py" "$API_OUT_PYTHON/rtc.py"
mv "$API_OUT_PYTHON/livekit_rtc_pb2.pyi" "$API_OUT_PYTHON/rtc.pyi"
mv "$API_OUT_PYTHON/livekit_connector_whatsapp_pb2.py" "$API_OUT_PYTHON/connector_whatsapp.py"
mv "$API_OUT_PYTHON/livekit_connector_whatsapp_pb2.pyi" "$API_OUT_PYTHON/connector_whatsapp.pyi"
mv "$API_OUT_PYTHON/livekit_connector_twilio_pb2.py" "$API_OUT_PYTHON/connector_twilio.py"
mv "$API_OUT_PYTHON/livekit_connector_twilio_pb2.pyi" "$API_OUT_PYTHON/connector_twilio.pyi"
mv "$API_OUT_PYTHON/livekit_connector_pb2.py" "$API_OUT_PYTHON/connector.py"
mv "$API_OUT_PYTHON/livekit_connector_pb2.pyi" "$API_OUT_PYTHON/connector.pyi"

mkdir -p "$API_OUT_PYTHON/agent_pb"
mv "$API_OUT_PYTHON/agent/livekit_agent_session_pb2.py" "$API_OUT_PYTHON/agent_pb/agent_session.py"
mv "$API_OUT_PYTHON/agent/livekit_agent_session_pb2.pyi" "$API_OUT_PYTHON/agent_pb/agent_session.pyi"

perl -i -pe 's|^(import (livekit_egress_pb2\|livekit_room_pb2\|livekit_webhook_pb2\|livekit_ingress_pb2\|livekit_models_pb2\|livekit_agent_pb2\|livekit_agent_dispatch_pb2\|livekit_analytics_pb2\|livekit_sip_pb2\|livekit_metrics_pb2\|livekit_agent_session_pb2))|from . $1|g' "$API_OUT_PYTHON"/**.py "$API_OUT_PYTHON"/**.pyi
mkdir -p "$API_OUT_PYTHON/logger_pb"
mv "$API_OUT_PYTHON/logger/options_pb2.py" "$API_OUT_PYTHON/logger_pb/options.py"
mv "$API_OUT_PYTHON/logger/options_pb2.pyi" "$API_OUT_PYTHON/logger_pb/options.pyi"

perl -i -pe 's|^(import (livekit_egress_pb2\|livekit_room_pb2\|livekit_webhook_pb2\|livekit_ingress_pb2\|livekit_models_pb2\|livekit_agent_pb2\|livekit_agent_dispatch_pb2\|livekit_analytics_pb2\|livekit_sip_pb2\|livekit_metrics_pb2\|livekit_rtc_pb2\|livekit_connector_whatsapp_pb2\|livekit_connector_twilio_pb2\|livekit_connector_pb2\|livekit_agent_session_pb2\|options_pb2))|from . $1|g' "$API_OUT_PYTHON"/**.py "$API_OUT_PYTHON"/**.pyi

perl -i -pe 's|livekit_(\w+)_pb2|${1}|g' "$API_OUT_PYTHON"/**.py "$API_OUT_PYTHON"/**.pyi

perl -i -pe 's|from logger import options_pb2 as ([^ ]+)|from .logger_pb import options as $1|g' "$API_OUT_PYTHON"/**.py "$API_OUT_PYTHON"/**.pyi

# fixes - error: ClassVar can only be used for assignments in class body [misc]
perl -i -pe 's|^(\w+_FIELD_NUMBER): _ClassVar\[int\]|$1: int|g' "$API_OUT_PYTHON/logger_pb/options.pyi"
31 changes: 31 additions & 0 deletions livekit-protocol/livekit/protocol/connector.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions livekit-protocol/livekit/protocol/connector.pyi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions livekit-protocol/livekit/protocol/connector_twilio.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions livekit-protocol/livekit/protocol/connector_twilio.pyi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading