Files
Claude 4af4be94a4
All checks were successful
Create Release / build (push) Successful in 6s
Add FCM push notifications, queue alerts, caller ID fixes, and auto-revert agent status
Server-side:
- Add push credential auto-creation for FCM incoming call notifications
- Add queue alert FCM notifications (data-only for background delivery)
- Add queue alert cancellation on call accept/disconnect
- Fix caller ID to show caller's number instead of Twilio number
- Fix FCM token storage when refresh_token is null
- Add pre_call_status tracking to revert agent status 30s after call ends
- Add SSE fallback polling for mobile app connectivity

Mobile app:
- Add Android telecom permissions and phone account registration
- Add VoiceFirebaseMessagingService for incoming call push handling
- Add insistent queue alert notifications with custom sound
- Fix caller number display on active call screen
- Add caller ID selection dropdown on dashboard
- Add phone numbers endpoint and provider support
- Add unit tests for CallInfo, QueueState, and CallProvider
- Remove local.properties from tracking, add .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:11:02 -08:00
..

TWP Softphone — Mobile App

Flutter-based VoIP softphone client for the Twilio WordPress Plugin. Uses the Twilio Voice SDK (WebRTC) to make and receive calls via the Android Telecom framework.

Requirements

  • Flutter 3.29+ (tested with 3.41.4)
  • Android device/tablet (API 26+)
  • TWP WordPress plugin installed and configured on server
  • Twilio account with Voice capability

Quick Start

cd mobile
flutter pub get
flutter build apk --debug
adb install build/app/outputs/flutter-apk/app-debug.apk

Server Setup

The app connects to your WordPress site running the TWP plugin. The server must have:

  1. TWP Plugin installed and activated
  2. Twilio credentials configured (Account SID, Auth Token)
  3. At least one Twilio phone number purchased
  4. A WordPress user with agent permissions

SSE (Server-Sent Events) — Apache + PHP-FPM

The app uses SSE for real-time updates (queue changes, agent status). On Apache with PHP-FPM, mod_proxy_fcgi buffers output by default, which breaks SSE streaming.

Fix — Create a config file on the web server:

echo 'ProxyPassMatch "^/wp-json/twilio-mobile/v1/stream/events$" "unix:/run/php-fpm/www.sock|fcgi://localhost/path/to/wordpress/index.php" flushpackets=on' > /etc/httpd/conf.d/twp-sse.conf
httpd -t && systemctl restart httpd

Adjust the paths:

  • Socket path must match your PHP-FPM config (check grep fcgi /etc/httpd/conf.d/php.conf)
  • Document root must match your WordPress installation path

Diagnosis — If the green connection dot stays red:

# Check current PHP-FPM proxy config
grep -r "fcgi\|php-fpm" /etc/httpd/conf.d/

# Check if flushpackets is configured
grep -r "flushpackets" /etc/httpd/conf.d/

# Test SSE endpoint (should stream data continuously, not hang)
curl -N -H "Authorization: Bearer YOUR_TOKEN" \
  https://your-site.com/wp-json/twilio-mobile/v1/stream/events

Notes:

  • flushpackets=on is a ProxyPassMatch directive — it cannot go in .htaccess
  • If using nginx instead of Apache, the X-Accel-Buffering: no header (already in the PHP code) handles this automatically
  • The app automatically falls back to 5-second polling if SSE fails, so the app still works without this config — just with higher latency

App Setup (Android)

First Launch

  1. Open the app and enter your server URL (e.g., https://phone.cloud-hosting.io)
  2. Log in with your WordPress credentials
  3. Grant permissions when prompted:
    • Microphone (required for calls)
    • Phone/Call (required for Android Telecom integration)

Phone Account

Android requires a registered and enabled phone account for VoIP apps. The app registers automatically, but enabling must be done manually:

  1. If prompted, tap "Open Settings" to go to Android's Phone Account settings
  2. Find "TWP Softphone" in the list and toggle it ON
  3. Return to the app

If you skipped this step, tap the orange warning card on the dashboard.

Path: Settings → Apps → Default apps → Phone → Calling accounts → TWP Softphone

Making Calls

  1. Tap the phone FAB (bottom right) to open the dialer
  2. Enter the phone number
  3. Caller ID is auto-selected from your Twilio numbers
  4. Tap Call — the Android system call screen (InCallUI) handles the active call

Receiving Calls

Incoming calls appear via Android's native call UI. Answer/reject using the standard Android interface.

Note: FCM push notifications are required for receiving calls when the app is in the background. This requires google-services.json in android/app/.

Queue Management

  • View assigned queues on the dashboard
  • Tap a queue with waiting calls to see callers
  • Tap Accept to take a call from the queue

Agent Status

Toggle between Available, Busy, and Offline using the status bar at the top of the dashboard.

Development

Project Structure

lib/
├── config/          # App configuration
├── models/          # Data models (CallInfo, QueueState, AgentStatus, User)
├── providers/       # State management (AuthProvider, CallProvider, AgentProvider)
├── screens/         # UI screens (Login, Dashboard, Settings, ActiveCall)
├── services/        # API/SDK services (VoiceService, SseService, ApiClient, AuthService)
├── widgets/         # Reusable widgets (Dialpad, QueueCard, AgentStatusToggle)
└── main.dart        # App entry point

Running Tests

flutter test

34 tests covering CallInfo, QueueState, and CallProvider.

Building

# Debug APK
flutter build apk --debug

# Release APK (requires signing config)
flutter build apk --release

ADB Deployment (WiFi)

# Connect to device
adb connect DEVICE_IP:PORT

# Install
adb install -r build/app/outputs/flutter-apk/app-debug.apk

# Launch
adb shell am start -n io.cloudhosting.twp.twp_softphone/.MainActivity

# View logs
adb logcat -s flutter

Key Dependencies

Package Purpose
twilio_voice Twilio Voice SDK (WebRTC calling)
provider State management
dio HTTP client (REST API, SSE)
firebase_messaging FCM push for incoming calls
flutter_secure_storage Secure token storage

Troubleshooting

Problem Solution
Green dot stays red SSE buffering — see Server Setup
"No registered phone account" Enable phone account in Android Settings (see Phone Account)
Calls fail with "Invalid callerId" Server webhook needs phone number validation — check handle_browser_voice in class-twp-webhooks.php
App hangs on login Check server is reachable: curl https://your-site.com/wp-json/twilio-mobile/v1/auth/login
No incoming calls Ensure FCM is configured (google-services.json) and phone account is enabled