diff --git a/simple_outbound_call.py b/simple_outbound_call.py index 2e8bea0..f818502 100644 --- a/simple_outbound_call.py +++ b/simple_outbound_call.py @@ -8,15 +8,16 @@ from vocode.models.agent import ( WebSocketUserImplementedAgentConfig, ) from vocode.models.message import BaseMessage +from vocode.telephony.zoom_dial_in import ZoomDialIn if __name__ == "__main__": - call = OutboundCall( - recipient=CallEntity( - phone_number="+11234567890", - ), + call = ZoomDialIn( + recipient=CallEntity(phone_number=""), caller=CallEntity( - phone_number="+11234567890", + phone_number="", ), + zoom_meeting_id="", + zoom_meeting_password="", agent_config=ChatGPTAgentConfig( initial_message=BaseMessage(text="the quick fox jumped over the lazy dog "), prompt_preamble="respond two sentences at a time", @@ -29,3 +30,5 @@ if __name__ == "__main__": ), ) call.start() + input("Press enter to end the call...") + call.end() diff --git a/vocode/models/telephony.py b/vocode/models/telephony.py index fbecaec..989bb97 100644 --- a/vocode/models/telephony.py +++ b/vocode/models/telephony.py @@ -14,7 +14,10 @@ class CreateInboundCall(BaseModel): agent_config: AgentConfig synthesizer_config: Optional[SynthesizerConfig] = None twilio_sid: str - conversation_id: Optional[str] = None + + +class EndOutboundCall(BaseModel): + call_id: str class CreateOutboundCall(BaseModel): @@ -25,3 +28,14 @@ class CreateOutboundCall(BaseModel): synthesizer_config: Optional[SynthesizerConfig] = None conversation_id: Optional[str] = None # TODO add IVR/etc. + + +class DialIntoZoomCall(BaseModel): + recipient: CallEntity + caller: CallEntity + zoom_meeting_id: str + zoom_meeting_password: Optional[str] + transcriber_config: Optional[TranscriberConfig] = None + agent_config: AgentConfig + synthesizer_config: Optional[SynthesizerConfig] = None + conversation_id: Optional[str] = None diff --git a/vocode/telephony/outbound_call.py b/vocode/telephony/outbound_call.py index 652869a..d70e540 100644 --- a/vocode/telephony/outbound_call.py +++ b/vocode/telephony/outbound_call.py @@ -2,11 +2,12 @@ from typing import Optional from vocode.models.agent import AgentConfig from vocode.models.synthesizer import SynthesizerConfig from vocode.models.transcriber import TranscriberConfig -from ..models.telephony import CallEntity, CreateOutboundCall +from ..models.telephony import CallEntity, CreateOutboundCall, EndOutboundCall import requests from .. import api_key, BASE_URL -VOCODE_OUTBOUND_CALL_URL = f"https://{BASE_URL}/create_outbound_call" +VOCODE_CREATE_OUTBOUND_CALL_URL = f"https://{BASE_URL}/create_outbound_call" +VOCODE_END_OUTBOUND_CALL_URL = f"https://{BASE_URL}/end_outbound_call" class OutboundCall: @@ -17,16 +18,18 @@ class OutboundCall: agent_config: AgentConfig, transcriber_config: Optional[TranscriberConfig] = None, synthesizer_config: Optional[SynthesizerConfig] = None, + conversation_id: Optional[str] = None, ): self.recipient = recipient self.caller = caller self.agent_config = agent_config self.transcriber_config = transcriber_config self.synthesizer_config = synthesizer_config + self.conversation_id = conversation_id - def start(self): - return requests.post( - VOCODE_OUTBOUND_CALL_URL, + def start(self) -> str: + response = requests.post( + VOCODE_CREATE_OUTBOUND_CALL_URL, headers={"Authorization": f"Bearer {api_key}"}, json=CreateOutboundCall( recipient=self.recipient, @@ -34,5 +37,19 @@ class OutboundCall: agent_config=self.agent_config, transcriber_config=self.transcriber_config, synthesizer_config=self.synthesizer_config, + conversation_id=self.conversation_id, ).dict(), ) + assert response.ok, response.text + data = response.json() + self.conversation_id = data["id"] + + def end(self) -> str: + response = requests.post( + VOCODE_END_OUTBOUND_CALL_URL, + headers={"Authorization": f"Bearer {api_key}"}, + json=EndOutboundCall( + call_id=self.conversation_id, + ).dict(), + ) + assert response.ok, response.text diff --git a/vocode/telephony/zoom_dial_in.py b/vocode/telephony/zoom_dial_in.py new file mode 100644 index 0000000..bf46f80 --- /dev/null +++ b/vocode/telephony/zoom_dial_in.py @@ -0,0 +1,53 @@ +from typing import Optional +from vocode.models.agent import AgentConfig +from vocode.models.synthesizer import SynthesizerConfig +from vocode.models.transcriber import TranscriberConfig +from vocode.telephony.outbound_call import OutboundCall +from ..models.telephony import CallEntity, DialIntoZoomCall +import requests +from .. import api_key, BASE_URL + +VOCODE_ZOOM_DIAL_IN_URL = f"https://{BASE_URL}/dial_into_zoom_call" + + +class ZoomDialIn(OutboundCall): + def __init__( + self, + recipient: CallEntity, + caller: CallEntity, + zoom_meeting_id: str, + zoom_meeting_password: str, + agent_config: AgentConfig, + transcriber_config: Optional[TranscriberConfig] = None, + synthesizer_config: Optional[SynthesizerConfig] = None, + conversation_id: Optional[str] = None, + ): + super().__init__( + recipient=recipient, + caller=caller, + agent_config=agent_config, + transcriber_config=transcriber_config, + synthesizer_config=synthesizer_config, + conversation_id=conversation_id, + ) + self.zoom_meeting_id = zoom_meeting_id + self.zoom_meeting_password = zoom_meeting_password + + def start(self) -> str: + response = requests.post( + VOCODE_ZOOM_DIAL_IN_URL, + headers={"Authorization": f"Bearer {api_key}"}, + json=DialIntoZoomCall( + recipient=self.recipient, + caller=self.caller, + zoom_meeting_id=self.zoom_meeting_id, + zoom_meeting_password=self.zoom_meeting_password, + agent_config=self.agent_config, + transcriber_config=self.transcriber_config, + synthesizer_config=self.synthesizer_config, + conversation_id=self.conversation_id, + ).dict(), + ) + assert response.ok, response.text + data = response.json() + self.conversation_id = data["id"]