Skip to content

Plan: Twilio Voice Integration for Phone Call Appointments

Implement Twilio Voice calling functionality to enable clinicians to make phone calls through the clinical app interface, completing the phone call appointment feature set that already has infrastructure in place.

Steps

  1. Backend: Create Twilio Voice service integration in apps/perci-platform-backend/functions/src/integrations/twilio/ - Implement TwilioVoiceApi.ts following the pattern of GetStreamApi.ts, add TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_API_KEY, TWILIO_API_SECRET secrets to secrets.ts, create token generation endpoint for client SDK

  2. Backend: Add phone call management endpoints in apps/perci-platform-backend/functions/src/bff-clinical/ - Create twilioRouter.ts with /twilio/access-token endpoint, add webhook handlers in apps/perci-platform-backend/functions/src/api/twilio/ for call status events (ringing, in-progress, completed, busy, failed), update endAppointmentCall.ts to store Twilio call metadata (duration, status) in Medplum appointment extensions

  3. Backend: Update clinician signup for Twilio provisioning in apps/perci-platform-backend/functions/src/api/clinicians/signUpClinician.ts - Generate Twilio identity (using clinician's Medplum Practitioner ID) for clinicians with videocall_own_manage permission, store identity in Practitioner.identifier with system http://twilio.com/voice/identity

  4. Frontend Clinical: Add twilio_voice package and service layer - Add twilio_voice: ^0.3.2+2 to apps/perci-platform-clinicians/pubspec.yaml, create lib/services/twilio_voice_service.dart to wrap SDK (initialize device, fetch token from backend, handle call lifecycle), implement graceful error handling that allows manual calling if Twilio fails

  5. Frontend Clinical: Update appointment call UI for Twilio integration in apps/perci-platform-clinicians/lib/pages/appointments/appointment_call_screen/ - Add conditional logic: use Twilio Voice SDK when callType == 'phone' and service available, otherwise show phone number for manual dialing, implement "Call now" button that initiates Twilio call, add call state UI (connecting, ringing, connected, busy, failed), display mute/unmute toggle and end call button, show call duration timer

  6. Deployment and configuration - Add Twilio secrets to Firebase (firebase functions:secrets:set), configure Twilio webhook URLs in Twilio Console pointing to https://<region>-<project>.cloudfunctions.net/api/v1/twilio/webhooks/call-status, update deployment.yaml with new secret references, test complete flow in staging environment

Further Considerations

  1. Twilio phone number pool - System will use a shared pool of Twilio phone numbers for all outbound calls. Backend should implement number selection logic (round-robin or least-recently-used) to distribute calls across available numbers.

  2. International calling - Should the system support international phone calls for members outside the UK, or restrict to UK numbers only? This impacts Twilio configuration and cost considerations.

  3. Error telemetry - Should Twilio call failures (busy, no-answer, failed) be tracked in Datadog or Slack alerts for monitoring call quality and success rates?