Files
twilio-wp-plugin/CLAUDE.md
jknapp ae92ea2c81 Fix hold/resume functionality and customer number detection
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>
2025-09-01 09:34:07 -07:00

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 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

// 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 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


Last Updated: September 2025 Plugin Version: Production Ready Maintained for: phone.cloud-hosting.io