CRITICAL FIXES: - Fixed hold/resume functions to use proper Hold Queue system instead of empty TwiML - Enhanced customer number detection for voicemail and call recording interfaces - Resolved customer disconnections during hold/resume operations on outbound calls Hold/Resume System Improvements: - Updated ajax_toggle_hold() to use TWP_User_Queue_Manager for proper queue management - Fixed resume function to redirect calls back to appropriate queues (personal/shared) - Added comprehensive logging for hold queue operations and call leg detection - Enhanced hold experience with proper TTS messages and queue tracking Customer Number Detection Enhancements: - Enhanced handle_voicemail_callback() with fallback logic for missing From parameters - Added browser phone detection to identify client: calls and find real customer numbers - Enhanced call recording to use find_customer_call_leg() for proper customer identification - Fixed admin interfaces to show actual phone numbers instead of "client:agentname" Technical Improvements: - Integrated Hold Queue system with existing call leg detection infrastructure - Added proper TwiML generation for hold/resume operations - Enhanced error handling and logging for debugging complex call topologies - Maintains database consistency with queue position tracking 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
21 KiB
21 KiB
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 agentcustomer_number
= Phone number of customer calling into the systemworkflow_number
= Twilio number assigned to a specific workflowqueue_number
= Twilio number assigned to a specific queuedefault_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 actionsdefine_public_hooks()
: Registers frontend hooksdefine_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 tablesmigrate_tables()
: Handles schema migrationsadd_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 callssend_sms()
: Sends SMS messagesupdate_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 responsegenerate_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)
twp_phone_schedules
- Business hours definitionstwp_call_queues
- Queue configurations (includes user-specific)twp_queued_calls
- Active calls in queuestwp_workflows
- Call flow definitionstwp_workflow_phones
- Phone-to-workflow mappingstwp_call_log
- Complete call historytwp_sms_log
- SMS message trackingtwp_voicemails
- Voicemail recordings and transcriptionstwp_agent_groups
- Agent group definitionstwp_group_members
- User-to-group relationshipstwp_agent_status
- Real-time agent availabilitytwp_callbacks
- Callback request queuetwp_call_recordings
- Call recording metadatatwp_user_extensions
- User extension numberstwp_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 fromjoined_at
) - No
customer_number
field (usesfrom_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:
- Schedule Management (4 actions)
- Workflow Management (5 actions)
- Phone Number Management (5 actions)
- Queue Management (6 actions)
- Agent Management (11 actions)
- Call Control (15 actions)
- Voicemail (5 actions)
- Recording (4 actions)
- SMS Management (4 actions)
- ElevenLabs Integration (3 actions)
- Browser Phone (4 actions)
- 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 recordingtwp_stop_recording
- Stop call recordingtwp_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
- admin.js (116KB) - Admin interface functionality
- browser-phone-frontend.js (85KB) - Browser phone implementation
- 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)
inTWP_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
- Detects browser phone calls by checking for
- 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 detection using
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
- Client transfers:
- 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 tojoined_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
// 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)
// 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:
// 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
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
ortwp_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
- Enable WordPress Debug:
WP_DEBUG = true
- Check Error Logs:
/wp-content/debug.log
- Monitor Twilio Console: Real-time webhook debugging
- Database Queries: Use
$wpdb->last_error
- Browser Console: Check JavaScript errors
- Network Tab: Monitor AJAX requests
- Call Leg Detection: Look for "TWP Call Leg Detection" log entries
- Outbound Call Issues: Check for agent vs customer call SID usage
- 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