diff --git a/api/routes/telephony.py b/api/routes/telephony.py index 5c57cc2..e5bc771 100644 --- a/api/routes/telephony.py +++ b/api/routes/telephony.py @@ -1209,6 +1209,33 @@ async def handle_cloudonix_status_callback( return {"status": "success"} +@router.post("/cloudonix/amd-callback/{workflow_run_id}") +async def handle_cloudonix_amd_callback( + workflow_run_id: int, + request: Request, +): + """Handle Cloudonix-specific Answering Machine Detection(AMD) callbacks. + Cloudonix sends AMD updates to the callback URL specified during call initiation. + """ + set_current_run_id(workflow_run_id) + + content_type = request.headers.get("content-type", "") + + if "application/json" in content_type: + callback_data = await request.json() + else: + form_data = await request.form() + callback_data = dict(form_data) + + call_id = callback_data["CallSid"] + answered_by = callback_data["AnsweredBy"] + + logger.info( + f"[run {workflow_run_id}] Received Cloudonix AMD status callback with answered-by {answered_by} for call ID {call_id}: {json.dumps(callback_data)}" + ) + + return {"status": answered_by} + @router.post("/vobiz/hangup-callback/workflow/{workflow_id}") async def handle_vobiz_hangup_callback_by_workflow( diff --git a/api/services/telephony/providers/cloudonix_provider.py b/api/services/telephony/providers/cloudonix_provider.py index 9269d7e..123c813 100644 --- a/api/services/telephony/providers/cloudonix_provider.py +++ b/api/services/telephony/providers/cloudonix_provider.py @@ -105,6 +105,11 @@ class CloudonixProvider(TelephonyProvider): """, "caller-id": from_number, # Required field } + data["machineDetection"] = "DetectMessageEnd" + data["asyncAmd"] = True + data["asyncAmdStatusCallback"] = f"{backend_endpoint}/api/v1/telephony/cloudonix/amd-callback/{workflow_run_id}" + data["asyncAmdStatusCallbackMethod"]= "POST" + # TODO: Cloudonix status callbacks are spammy, so commenting it out. Can send it to # some persistent logging system instead of transcational database.