# CLAUDE.md - Twilio WordPress Plugin Documentation This file provides comprehensive guidance to Claude Code (claude.ai/code) when working with the Twilio WordPress Plugin codebase. ## ๐Ÿšจ CRITICAL: Testing & Deployment Environment **THIS PLUGIN RUNS ON A REMOTE SERVER IN A DOCKER CONTAINER - NOT LOCALLY** - **Production Server Path**: `/home/shadowdao/public_html/wp-content/plugins/twilio-wp-plugin/` - **Production URL**: `https://phone.cloud-hosting.io/` - **Development Path**: `/home/jknapp/code/twilio-wp-plugin/` - **Deployment Method**: Files synced via rsync from development to Docker container **IMPORTANT NOTES**: - NEVER assume local testing - all tests must work on remote server - Direct PHP tests work (`php test-twilio-direct.php send`) - WordPress admin context has issues that need investigation - The plugin requires Twilio PHP SDK v8.7.0 to function ## ๐Ÿ“ž Standardized Phone Number Variable Names **THESE NAMING CONVENTIONS MUST BE STRICTLY FOLLOWED:** ### Required Variable Names: - **`incoming_number`** = Phone number that initiated contact (sent SMS/call TO the system) - **`agent_number`** = Phone number used to reach a specific agent - **`customer_number`** = Phone number of customer calling into the system - **`workflow_number`** = Twilio number assigned to a specific workflow - **`queue_number`** = Twilio number assigned to a specific queue - **`default_number`** = Default Twilio number when none specified ### BANNED Variable Names (DO NOT USE): - โŒ `from_number` - Ambiguous, could be customer or system - โŒ `to_number` - Ambiguous, could be agent or system - โŒ `phone_number` - Too generic, must specify whose number - โŒ `$agent_phone` - Use `$agent_number` instead ### Test Numbers: - **Twilio Number**: `+19516215107` - **Test Agent Number**: `+19095737372` - **Fake Test Number**: `+19512345678` (DO NOT SEND SMS TO THIS) ### Legacy Webhook URLs: - **SMS**: `https://www.streamers.channel/wp-json/twilio-webhook/v1/sms` - **Voice**: `https://www.streamers.channel/wp-json/twilio-webhook/v1/voice` ## ๐Ÿ—๏ธ Plugin Architecture Overview ### Core Plugin Structure ``` twilio-wp-plugin/ โ”œโ”€โ”€ twilio-wp-plugin.php # Main plugin file (entry point) โ”œโ”€โ”€ includes/ # Core functionality classes โ”‚ โ”œโ”€โ”€ class-twp-core.php # Main plugin initialization โ”‚ โ”œโ”€โ”€ class-twp-activator.php # Database setup โ”‚ โ”œโ”€โ”€ class-twp-twilio-api.php # Twilio SDK wrapper โ”‚ โ”œโ”€โ”€ class-twp-webhooks.php # REST API endpoints โ”‚ โ”œโ”€โ”€ class-twp-tts-helper.php # TTS with ElevenLabs/Twilio โ”‚ โ””โ”€โ”€ ... # Other core classes โ”œโ”€โ”€ admin/ # Admin interface โ”‚ โ””โ”€โ”€ class-twp-admin.php # Admin pages & AJAX handlers โ”œโ”€โ”€ assets/ # Frontend resources โ”‚ โ”œโ”€โ”€ css/ # Stylesheets โ”‚ โ”œโ”€โ”€ js/ # JavaScript files โ”‚ โ””โ”€โ”€ audio/ # Audio resources โ””โ”€โ”€ CLAUDE.md # This documentation file ``` ## ๐Ÿ“ฆ Core Classes Documentation ### Main Classes (`includes/` directory) #### TWP_Core - **Purpose**: Main plugin initialization and hook registration - **Key Methods**: - `define_admin_hooks()`: Registers all admin AJAX actions - `define_public_hooks()`: Registers frontend hooks - `define_webhook_hooks()`: Registers REST API endpoints #### TWP_Activator - **Purpose**: Database table creation and plugin activation - **Tables Created**: 15 database tables (see Database Schema section) - **Key Methods**: - `ensure_tables_exist()`: Checks and creates missing tables - `migrate_tables()`: Handles schema migrations - `add_missing_columns()`: Updates table structures #### TWP_Twilio_API - **Purpose**: Wrapper for Twilio PHP SDK v8.7.0 - **Important**: Uses direct instantiation (`new TWP_Twilio_API()`) - **Key Methods**: - `make_call()`: Initiates outbound calls - `send_sms()`: Sends SMS messages - `update_call()`: Updates call state (hold/resume) - `create_queue_twiml()`: Generates queue TwiML #### TWP_Webhooks - **Purpose**: Handles all Twilio webhook endpoints - **Namespace**: `twilio-webhook/v1` - **Total Endpoints**: 26 REST API routes #### TWP_TTS_Helper (NEW) - **Purpose**: Text-to-Speech with ElevenLabs integration and caching - **Features**: - Automatic ElevenLabs detection - 30-day cache for generated audio - Fallback to Twilio voice - **Key Methods**: - `add_tts_to_twiml()`: Adds TTS to TwiML response - `generate_tts_audio()`: Pre-generates cached audio #### TWP_ElevenLabs_API - **Purpose**: Integration with ElevenLabs TTS service - **Configuration**: Uses `twp_elevenlabs_*` options - **Features**: Voice selection, model configuration, audio generation #### TWP_Workflow - **Purpose**: Call flow processing and TwiML generation - **Features**: IVR menus, queue routing, schedule checking #### TWP_Call_Queue - **Purpose**: Queue management and position tracking - **Features**: User-specific queues, hold queues, priority handling #### TWP_Agent_Manager - **Purpose**: Agent status and call acceptance - **Features**: Phone number validation, availability tracking #### TWP_Callback_Manager - **Purpose**: Callback request handling - **Features**: SMS confirmations, automatic processing #### TWP_Call_Logger - **Purpose**: Call logging and statistics - **Features**: Detailed call records, duration tracking #### TWP_Shortcodes - **Purpose**: WordPress shortcodes for frontend features - **Shortcode**: `[twp_browser_phone]` - Browser phone interface ## ๐Ÿ’พ Database Schema ### Complete Table List (15 tables) 1. `twp_phone_schedules` - Business hours definitions 2. `twp_call_queues` - Queue configurations (includes user-specific) 3. `twp_queued_calls` - Active calls in queues 4. `twp_workflows` - Call flow definitions 5. `twp_workflow_phones` - Phone-to-workflow mappings 6. `twp_call_log` - Complete call history 7. `twp_sms_log` - SMS message tracking 8. `twp_voicemails` - Voicemail recordings and transcriptions 9. `twp_agent_groups` - Agent group definitions 10. `twp_group_members` - User-to-group relationships 11. `twp_agent_status` - Real-time agent availability 12. `twp_callbacks` - Callback request queue 13. `twp_call_recordings` - Call recording metadata 14. `twp_user_extensions` - User extension numbers 15. `twp_queue_assignments` - User queue assignments ### Key Table Structures #### twp_call_queues (Enhanced) - Supports user-specific queues (`user_id` field) - Queue types: `general`, `personal`, `hold` - Extension support for direct dialing - TTS message configuration #### twp_queued_calls - Uses `enqueued_at` timestamp (migrated from `joined_at`) - No `customer_number` field (uses `from_number`/`to_number`) - Tracks agent assignment and status ## ๐Ÿ”Œ REST API Endpoints (Webhooks) ### Voice Endpoints - `/voice` - Main incoming call handler - `/browser-voice` - Browser phone calls - `/smart-routing` - Intelligent call routing - `/agent-screen` - Agent screening before connection - `/agent-confirm` - Agent confirmation handler - `/ring-group-result` - Handle ring group outcomes - `/agent-connect` - Connect accepted agents ### SMS Endpoints - `/sms` - Main SMS handler (includes "1" responses) - `/status` - Call/SMS status updates ### Queue Management - `/queue-wait` - Queue hold music and announcements - `/queue-action` - Queue-specific actions - `/ivr-response` - IVR menu selections ### Voicemail - `/voicemail-callback` - Voicemail recording handler - `/voicemail-complete` - Post-recording processing - `/voicemail-audio/{id}` - Audio playback proxy ### Recording - `/recording-status` - Recording status callbacks - `/recording-audio/{id}` - Recording playback proxy - `/transcription` - Transcription webhooks ### Callback System - `/callback-choice` - Customer callback selection - `/request-callback` - Callback request handler - `/callback-agent` - Agent-side callback - `/callback-customer` - Customer-side callback ### Outbound Calling - `/outbound-agent` - Basic outbound calls - `/outbound-agent-with-from` - Outbound with caller ID selection ### Utility - `/resume-call` - Resume held calls - `/smart-routing-fallback` - Routing error handler - `/browser-fallback` - Browser phone fallback ## ๐ŸŽ›๏ธ AJAX Endpoints (Admin & Frontend) ### Total: 68 AJAX Actions ### Categories: 1. **Schedule Management** (4 actions) 2. **Workflow Management** (5 actions) 3. **Phone Number Management** (5 actions) 4. **Queue Management** (6 actions) 5. **Agent Management** (11 actions) 6. **Call Control** (15 actions) 7. **Voicemail** (5 actions) 8. **Recording** (4 actions) 9. **SMS Management** (4 actions) 10. **ElevenLabs Integration** (3 actions) 11. **Browser Phone** (4 actions) 12. **Transfer & Hold** (8 actions) ### Key AJAX Actions: - `twp_toggle_hold` - Put call on hold/resume (uses call leg detection) - `twp_transfer_call` - Transfer to agent/queue (uses call leg detection) - `twp_start_recording` - Start call recording - `twp_stop_recording` - Stop call recording - `twp_requeue_call` - Return call to queue (uses call leg detection) - `twp_initiate_outbound_call_with_from` - Outbound with caller ID ### Call Control Architecture (CRITICAL): All call control functions (`twp_toggle_hold`, `twp_transfer_call`, `twp_requeue_call`) now use intelligent call leg detection to ensure actions are applied to the customer call leg, not the agent leg. This prevents customer disconnections in complex call topologies. ## ๐ŸŽจ Frontend Components ### JavaScript Files 1. **admin.js** (116KB) - Admin interface functionality 2. **browser-phone-frontend.js** (85KB) - Browser phone implementation 3. **twp-service-worker.js** (2.5KB) - Push notifications ### Browser Phone Features - Twilio Device SDK integration - Real-time call controls (hold, transfer, record) - Queue monitoring dashboard - Agent status management - Call history display - Visual call state indicators ### CSS Files - **admin.css** - Admin interface styling - **browser-phone-frontend.css** - Browser phone UI ## ๐Ÿ”ง Recent Fixes & Improvements ### CRITICAL: Outbound Call Issues RESOLVED (September 2025) - **Issue**: Hold, transfer, and requeue functions were applying actions to wrong call leg (agent instead of customer), causing customer disconnections - **Root Cause**: Complex call topologies in outbound calls create agent and customer call legs with different SIDs - **Solution**: New intelligent call leg detection system - **Functions Fixed**: `ajax_toggle_hold()`, `ajax_transfer_call()`, `ajax_requeue_call()` - **Result**: All functions now work correctly for both inbound and outbound calls without disconnecting customers ### Customer Number Detection Issues RESOLVED (September 2025) - **Issue**: Customer numbers showing as "client:agentname" instead of actual phone numbers in voicemail and call recording admin interfaces - **Root Cause**: Browser phone calls create complex call topologies where customer information is stored in different call legs - **Solution**: Enhanced customer number detection with fallback mechanisms - **Areas Fixed**: Voicemail callback handling and call recording customer identification - **Result**: Both inbound and outbound calls now properly identify real customer phone numbers ### Call Leg Detection System (NEW) - **Function**: `find_customer_call_leg($call_sid, $api)` in `TWP_Admin` class - **Purpose**: Identifies customer vs agent call legs in complex call topologies - **Detection Logic**: - Detects browser phone calls by checking for `client:` prefixes - Uses parent call relationships to find customer leg - Searches active calls for related customer connections - Comprehensive fallback mechanisms - **Logging**: Extensive debugging output for call relationship tracking ### Enhanced Customer Number Detection (NEW) - **Voicemail Callback Enhancement** (`TWP_Webhooks::handle_voicemail_callback()`): - Fallback logic retrieves customer numbers from call log when From parameter missing - Browser phone detection identifies `client:` calls and finds real customer numbers - Parent call analysis and related call search functionality - Comprehensive logging for customer number detection process - **Call Recording Enhancement** (`TWP_Admin::ajax_start_recording()`): - Browser phone detection using `client:` prefix identification - Integration with `find_customer_call_leg()` helper for proper customer identification - Smart number extraction from appropriate call legs (from/to field analysis) - Enhanced logging for recording customer number detection ### Browser Phone Call Support Enhanced - **Client Transfer Support**: Fixed "Invalid phone number format" errors for `client:` transfers - **Detection**: Automatically identifies `client:agentname` format calls - **Transfer Methods**: - Client transfers: `$dial->client($agent_name)` - Phone transfers: `$twiml->dial($target)` - Queue transfers: Uses customer leg for proper queue placement - **Customer Number Resolution**: Properly identifies real phone numbers in complex call topologies - **Admin Interface Fixes**: Voicemail and recording interfaces now show actual customer numbers instead of client identifiers ### Hold Functionality (Fixed) - **Issue**: `TWP_Twilio_API::get_instance()` error - **Fix**: Changed to direct instantiation + call leg detection - **Enhancement**: Added ElevenLabs TTS with caching - **Customer Impact**: Hold now affects customer (not agent) with proper music/messages ### Transfer System (Fixed) - **Issue**: Transfers were disconnecting customers in outbound calls - **Fix**: All transfer types now use correct customer call leg - **Types Supported**: Queue, client (browser phone), phone number transfers - **Enhancement**: Proper TwiML generation for each transfer type ### Requeue Functionality (Fixed) - **Issue**: Requeue was disconnecting customers instead of placing them back in queue - **Fix**: Uses customer call leg for queue placement - **Enhancement**: Maintains proper call tracking with customer SID - **Database**: Uses `enqueued_at` column when available, falls back to `joined_at` ### Recording Management (Fixed) - **Issue**: "Unknown subresource update" error - **Fix**: Proper SDK v8 syntax using call recordings subresource - **Fallback**: Tries `Twilio.CURRENT` if specific SID fails ### Queue Management (Fixed) - **Issue**: `Enqueue::waitUrl()` undefined method - **Fix**: Pass `waitUrl` as option: `$response->enqueue($queue_name, ['waitUrl' => $url])` ### TTS Integration (New) - **Feature**: ElevenLabs integration with intelligent caching - **Cache Duration**: 30 days for identical text - **Fallback**: Automatic fallback to Twilio voice - **Performance**: Cached audio loads instantly ## ๐Ÿš€ Twilio Integration Details ### SDK Version - **Required**: Twilio PHP SDK v8.7.0 - **Installation**: Via Composer or install script - **PHP Requirement**: PHP 8.0+ ### API Response Structure ```php // Success response [ 'success' => true, 'data' => [...] // Twilio response data ] // Error response [ 'success' => false, 'error' => 'Error message', 'code' => 400 ] ``` ### TwiML Generation Best Practices - Always use SDK classes for TwiML generation - Include proper XML headers when needed - Use TTS helper for voice synthesis - Implement proper error handling ### Recording Stop Methods (SDK v8) ```php // Method 1: Specific recording $client->calls($call_sid) ->recordings($recording_sid) ->update(['status' => 'stopped']); // Method 2: Single active recording $client->calls($call_sid) ->recordings('Twilio.CURRENT') ->update(['status' => 'stopped']); ``` ## ๐Ÿ› ๏ธ Development Guidelines ### Call Control Functions (CRITICAL) **ALWAYS use call leg detection for hold, transfer, and requeue operations:** ```php // Correct pattern for call control functions private function find_customer_call_leg($call_sid, $api) { // Detects browser phone vs regular calls // Uses parent call relationships // Searches active calls for customer leg // Returns correct SID for operations } // Usage in AJAX handlers $customer_call_sid = $this->find_customer_call_leg($call_sid, $twilio); $result = $api->update_call($customer_call_sid, ['twiml' => $twiml_xml]); ``` **Why This Matters:** - Outbound calls create separate agent and customer call legs - Applying actions to agent leg disconnects customer - Browser phone calls use `client:` identifiers - Customer leg must be identified for proper call control ### Database Operations - Always use `$wpdb` global - Sanitize with `sanitize_text_field()`, `intval()` - Use prepared statements: `$wpdb->prepare()` - Call `TWP_Activator::ensure_tables_exist()` before operations ### AJAX Handler Pattern ```php public function ajax_handler_name() { if (!$this->verify_ajax_nonce()) { wp_send_json_error('Invalid nonce'); return; } // Handler logic wp_send_json_success($data); } ``` ### Error Handling - Log errors with `error_log()` - Return structured error responses - Implement fallback mechanisms - Handle Twilio exceptions properly ### Naming Conventions - Classes: `TWP_Class_Name` - Tables: `twp_table_name` - Options: `twp_option_name` - AJAX actions: `twp_action_name` - Nonces: `twp_ajax_nonce` or `twp_frontend_nonce` ## ๐Ÿ“‹ Common Issues & Solutions ### Database Issues - **Missing Tables**: Run `TWP_Activator::ensure_tables_exist()` - **Schema Changes**: Check `add_missing_columns()` method - **Migration Issues**: Review `migrate_tables()` implementation ### Webhook Issues - **500 Errors**: Check PHP error logs - **TwiML Errors**: Verify XML structure - **Authentication**: Webhooks use `__return_true` permission ### API Issues - **Instantiation**: Use `new TWP_Twilio_API()` not singleton - **Phone Format**: Always use E.164 format (+1XXXXXXXXXX) - **Call SID**: Access via `$response['data']['sid']` ### Call Control Issues (Outbound Calls) - **Customer Disconnections**: Use `find_customer_call_leg()` before hold/transfer/requeue - **Wrong Call Leg**: Check error logs for "Call Leg Detection" messages - **Browser Phone Issues**: Look for `client:` prefix detection in logs - **Transfer Failures**: Verify customer call leg is being used for TwiML updates - **Customer Number Display**: Check for "TWP Voicemail Callback" or "TWP Recording" log entries for customer number detection - **Client Identifier Issues**: Search logs for "client:" identifier handling and real customer number detection ### Hold/Transfer Issues - **Hold Music**: Default URL provided, customizable via settings - **TTS Caching**: 30-day cache, auto-cleanup available - **Transfer**: Supports agent queues and phone numbers - **Call Topology**: Complex outbound calls require call leg detection ## ๐Ÿงช Testing Approach ### Unit Testing - PHPUnit for PHP code - Mock WordPress functions - Mock Twilio API responses ### Integration Testing - Test webhook endpoints - Verify database operations - Test complete call flows ### Manual Testing - Monitor Twilio Console - Check WordPress debug logs - Test with real phone numbers ## ๐Ÿ“š Key Features Implementation ### Agent System - **SMS Accept**: Agents text "1" to accept calls - **Real-time Status**: Available/busy/offline states - **Group Management**: Priority-based call distribution - **Personal Queues**: Agent-specific call queues ### Call Queue System - **Position Tracking**: Real-time queue position - **Timeout Handling**: Automatic callback offers - **Hold Queues**: Temporary call parking - **User Queues**: Personal agent queues ### Browser Phone - **Twilio Device**: Full SDK integration - **Call Controls**: Hold, transfer, record, mute - **Visual Interface**: Real-time status updates - **Queue Dashboard**: Monitor waiting calls ### Recording System - **Start/Stop**: Dynamic recording control - **Storage**: Database tracking with Twilio URLs - **Playback**: Authenticated proxy endpoints - **Transcription**: Automatic with callbacks ### ElevenLabs TTS - **Auto-detection**: Uses ElevenLabs when configured - **Caching**: 30-day cache for repeated phrases - **Fallback**: Seamless Twilio voice fallback - **Performance**: Instant cached audio delivery ## ๐Ÿ“ Configuration Requirements ### WordPress Settings - **Twilio Credentials**: Account SID, Auth Token - **TwiML App**: For browser phone functionality - **Phone Numbers**: At least one Twilio number - **Webhook URLs**: Configure in Twilio Console ### Optional Settings - **ElevenLabs**: API key and voice selection - **Hold Music**: Custom URL support - **SMS Notifications**: Agent alert numbers - **Business Hours**: Schedule configurations ## ๐Ÿ” Debugging Tips 1. **Enable WordPress Debug**: `WP_DEBUG = true` 2. **Check Error Logs**: `/wp-content/debug.log` 3. **Monitor Twilio Console**: Real-time webhook debugging 4. **Database Queries**: Use `$wpdb->last_error` 5. **Browser Console**: Check JavaScript errors 6. **Network Tab**: Monitor AJAX requests 7. **Call Leg Detection**: Look for "TWP Call Leg Detection" log entries 8. **Outbound Call Issues**: Check for agent vs customer call SID usage 9. **Browser Phone Debugging**: Search logs for "client:" identifier handling ## ๐Ÿ“– External Resources - **Twilio PHP SDK**: https://www.twilio.com/docs/libraries/reference/twilio-php/ - **WordPress REST API**: https://developer.wordpress.org/rest-api/ - **ElevenLabs API**: https://api.elevenlabs.io/docs - **Twilio TwiML**: https://www.twilio.com/docs/voice/twiml --- *Last Updated: September 2025* *Plugin Version: Production Ready* *Maintained for: phone.cloud-hosting.io*