MCPcopy Create free account
hub / github.com/Roy3838/Observer / voice_callback

Function voice_callback

api/messaging.py:834–883  ·  view source on GitHub ↗

Webhook endpoint that Twilio calls when a voice call connects. Handles both incoming calls (whitelist them) and outgoing calls (speak message). Returns TwiML instructions. Validates Twilio signature to prevent spoofing attacks.

(
    request: Request,
    form_data: dict = Depends(validate_twilio_request)
)

Source from the content-addressed store, hash-verified

832
833@messaging_router.post("/webhooks/voice-callback", tags=["Webhooks"])
834async def voice_callback(
835 request: Request,
836 form_data: dict = Depends(validate_twilio_request)
837):
838 """
839 Webhook endpoint that Twilio calls when a voice call connects.
840 Handles both incoming calls (whitelist them) and outgoing calls (speak message).
841 Returns TwiML instructions.
842 Validates Twilio signature to prevent spoofing attacks.
843 """
844 try:
845 # Extract call info (form_data already validated and parsed)
846 call_sid = form_data.get("CallSid", "")
847 call_status = form_data.get("CallStatus", "")
848 direction = form_data.get("Direction", "")
849 from_number = form_data.get("From", "")
850
851 logger.info(f"Voice callback received: SID={call_sid}, Status={call_status}, Direction={direction}")
852
853 # Create TwiML response
854 response = VoiceResponse()
855
856 if direction == "inbound":
857 # Someone called YOUR number - whitelist them for phone (SMS/Voice)
858 await add_to_whitelist(from_number, channel="phone")
859 logger.info(f"Auto-whitelisted caller {from_number} via incoming call")
860
861 response.say(
862 "Your number is now whitelisted for 24 hours across SMS, WhatsApp, and voice calls. You can now receive messages from Observer AI.",
863 voice='alice',
864 language='en-US'
865 )
866 else:
867 # Outgoing call - speak the message from AI
868 message_text = pending_voice_calls.get(call_sid, "Alert from Observer AI")
869 response.say(message_text, voice='alice', language='en-US')
870
871 # Clean up the stored message
872 if call_sid in pending_voice_calls:
873 del pending_voice_calls[call_sid]
874
875 # Return TwiML as XML
876 return FastAPIResponse(content=str(response), media_type="application/xml")
877
878 except Exception as e:
879 logger.error(f"Error processing voice callback: {str(e)}")
880 # Return a fallback TwiML response
881 response = VoiceResponse()
882 response.say("An error occurred.", voice='alice')
883 return FastAPIResponse(content=str(response), media_type="application/xml")
884
885@messaging_router.post("/webhooks/voice-status", tags=["Webhooks"])
886async def voice_status_callback(

Callers

nothing calls this directly

Calls 3

add_to_whitelistFunction · 0.85
infoMethod · 0.80
errorMethod · 0.80

Tested by

no test coverage detected