Fix extension transfer system and browser phone compatibility
Major Fixes: - Fixed extension transfers going directly to voicemail for available agents - Resolved browser phone call disconnections during transfers - Fixed voicemail transcription placeholder text issue - Added Firefox compatibility with automatic media permissions Extension Transfer Improvements: - Changed from active client dialing to proper queue-based system - Fixed client name generation consistency (user_login vs display_name) - Added 2-minute timeout with automatic voicemail fallback - Enhanced agent availability detection for browser phone users Browser Phone Enhancements: - Added automatic microphone/speaker permission requests - Improved Firefox compatibility with explicit getUserMedia calls - Fixed client naming consistency across capability tokens and call acceptance - Added comprehensive error handling for permission denials Database & System Updates: - Added auto_busy_at column for automatic agent status reversion - Implemented 1-minute auto-revert system for busy agents with cron job - Updated database version to 1.6.2 for automatic migration - Fixed voicemail user_id association for extension voicemails Call Statistics & Logging: - Fixed browser phone calls not appearing in agent statistics - Enhanced call logging with proper agent_id association in JSON format - Improved customer number detection for complex call topologies - Added comprehensive debugging for call leg detection Voicemail & Transcription: - Replaced placeholder transcription with real Twilio API integration - Added manual transcription request capability for existing voicemails - Enhanced voicemail callback handling with user_id support - Fixed transcription webhook processing for extension voicemails Technical Improvements: - Standardized client name generation across all components - Added ElevenLabs TTS integration to agent connection messages - Enhanced error handling and logging throughout transfer system - Fixed TwiML generation syntax errors in dial() methods 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ class TWP_User_Queue_Manager {
|
||||
'user_id' => $user_id,
|
||||
'extension' => $extension,
|
||||
'max_size' => 10,
|
||||
'timeout_seconds' => 300, // 5 minutes for logged-in users
|
||||
'timeout_seconds' => 120, // 2 minutes timeout
|
||||
'voicemail_prompt' => sprintf('You have reached %s. Please leave a message after the tone.', $user->display_name),
|
||||
'is_hold_queue' => 0
|
||||
),
|
||||
@@ -288,23 +288,49 @@ class TWP_User_Queue_Manager {
|
||||
), ARRAY_A);
|
||||
|
||||
if (!$current_queue) {
|
||||
return array('success' => false, 'error' => 'Call not found in queue');
|
||||
}
|
||||
|
||||
// Move call to hold queue
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'twp_queued_calls',
|
||||
array(
|
||||
// Call not in queue yet (browser phone calls), create a new entry
|
||||
error_log("TWP: Call not in queue, creating hold queue entry for SID: {$call_sid}");
|
||||
|
||||
// Check if enqueued_at column exists
|
||||
$calls_table = $wpdb->prefix . 'twp_queued_calls';
|
||||
$columns = $wpdb->get_col("DESCRIBE $calls_table");
|
||||
|
||||
$insert_data = array(
|
||||
'queue_id' => $extension_data['hold_queue_id'],
|
||||
'position' => 1 // Reset position in hold queue
|
||||
),
|
||||
array('id' => $current_queue['id']),
|
||||
array('%d', '%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
return array('success' => false, 'error' => 'Failed to transfer to hold queue');
|
||||
'call_sid' => $call_sid,
|
||||
'from_number' => '', // Will be populated by Twilio webhooks
|
||||
'to_number' => '', // Will be populated by Twilio webhooks
|
||||
'position' => 1,
|
||||
'status' => 'waiting'
|
||||
);
|
||||
|
||||
if (in_array('enqueued_at', $columns)) {
|
||||
$insert_data['enqueued_at'] = current_time('mysql');
|
||||
} else {
|
||||
$insert_data['joined_at'] = current_time('mysql');
|
||||
}
|
||||
|
||||
$result = $wpdb->insert($calls_table, $insert_data);
|
||||
|
||||
if ($result === false) {
|
||||
return array('success' => false, 'error' => 'Failed to create hold queue entry');
|
||||
}
|
||||
} else {
|
||||
// Move existing call to hold queue
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'twp_queued_calls',
|
||||
array(
|
||||
'queue_id' => $extension_data['hold_queue_id'],
|
||||
'position' => 1 // Reset position in hold queue
|
||||
),
|
||||
array('id' => $current_queue['id']),
|
||||
array('%d', '%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
return array('success' => false, 'error' => 'Failed to transfer to hold queue');
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
@@ -340,7 +366,9 @@ class TWP_User_Queue_Manager {
|
||||
), ARRAY_A);
|
||||
|
||||
if (!$held_call) {
|
||||
return array('success' => false, 'error' => 'Call not found in hold queue');
|
||||
// Call might not be in database (browser phone), but we can still resume it
|
||||
error_log("TWP: Call not found in hold queue database, will resume anyway for SID: {$call_sid}");
|
||||
// Continue with resume process even without database entry
|
||||
}
|
||||
|
||||
// Determine target queue
|
||||
@@ -356,20 +384,22 @@ class TWP_User_Queue_Manager {
|
||||
$target_queue_id
|
||||
));
|
||||
|
||||
// Move call to target queue
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'twp_queued_calls',
|
||||
array(
|
||||
'queue_id' => $target_queue_id,
|
||||
'position' => $next_position
|
||||
),
|
||||
array('id' => $held_call['id']),
|
||||
array('%d', '%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
return array('success' => false, 'error' => 'Failed to resume from hold');
|
||||
// Move call to target queue if it exists in database
|
||||
if ($held_call) {
|
||||
$result = $wpdb->update(
|
||||
$wpdb->prefix . 'twp_queued_calls',
|
||||
array(
|
||||
'queue_id' => $target_queue_id,
|
||||
'position' => $next_position
|
||||
),
|
||||
array('id' => $held_call['id']),
|
||||
array('%d', '%d'),
|
||||
array('%d')
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
return array('success' => false, 'error' => 'Failed to resume from hold');
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
|
Reference in New Issue
Block a user