forked from voxos-ai/bolna
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plivo_api_server.py
95 lines (71 loc) · 3.2 KB
/
plivo_api_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import os
import json
import requests
import uuid
from dotenv import load_dotenv
import redis.asyncio as redis
from fastapi import FastAPI, HTTPException, Query, Request
from fastapi.responses import PlainTextResponse
import plivo
app = FastAPI()
load_dotenv()
port = 8002
plivo_auth_id = os.getenv('PLIVO_AUTH_ID')
plivo_auth_token = os.getenv('PLIVO_AUTH_TOKEN')
plivo_phone_number = os.getenv('PLIVO_PHONE_NUMBER')
# Initialize Plivo client
plivo_client = plivo.RestClient(os.getenv('PLIVO_AUTH_ID'), os.getenv('PLIVO_AUTH_TOKEN'))
def populate_ngrok_tunnels():
response = requests.get("http://ngrok:4040/api/tunnels") # ngrok interface
telephony_url, bolna_url = None, None
if response.status_code == 200:
data = response.json()
for tunnel in data['tunnels']:
if tunnel['name'] == 'plivo-app':
telephony_url = tunnel['public_url']
elif tunnel['name'] == 'bolna-app':
bolna_url = tunnel['public_url'].replace('https:', 'wss:')
return telephony_url, bolna_url
else:
print(f"Error: Unable to fetch data. Status code: {response.status_code}")
@app.post('/call')
async def make_call(request: Request):
try:
call_details = await request.json()
agent_id = call_details.get('agent_id', None)
if not agent_id:
raise HTTPException(status_code=404, detail="Agent not provided")
if not call_details or "recipient_phone_number" not in call_details:
raise HTTPException(status_code=404, detail="Recipient phone number not provided")
telephony_host, bolna_host = populate_ngrok_tunnels()
print(f'telephony_host: {telephony_host}')
print(f'bolna_host: {bolna_host}')
# adding hangup_url since plivo opens a 2nd websocket once the call is cut.
# https://github.com/bolna-ai/bolna/issues/148#issuecomment-2127980509
call = plivo_client.calls.create(
from_=plivo_phone_number,
to_=call_details.get('recipient_phone_number'),
answer_url=f"{telephony_host}/plivo_connect?bolna_host={bolna_host}&agent_id={agent_id}",
hangup_url=f"{telephony_host}/plivo_hangup_callback",
answer_method='POST')
return PlainTextResponse("done", status_code=200)
except Exception as e:
print(f"Exception occurred in make_call: {e}")
raise HTTPException(status_code=500, detail="Internal Server Error")
@app.post('/plivo_connect')
async def plivo_connect(request: Request, bolna_host: str = Query(...), agent_id: str = Query(...)):
try:
bolna_websocket_url = f'{bolna_host}/chat/v1/{agent_id}'
response = '''
<Response>
<Stream bidirectional="true">{}</Stream>
<MultiPartyCall role="customer">mpc_name</MultiPartyCall>
</Response>
'''.format(bolna_websocket_url)
return PlainTextResponse(str(response), status_code=200, media_type='text/xml')
except Exception as e:
print(f"Exception occurred in plivo_connect: {e}")
@app.post('/plivo_hangup_callback')
async def plivo_hangup_callback(request: Request):
# add any post call hangup processing
return PlainTextResponse("", status_code=200)