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>
This commit is contained in:
2025-09-01 09:34:07 -07:00
parent 5b6011bdb8
commit ae92ea2c81
5 changed files with 1734 additions and 682 deletions

View File

@@ -1297,8 +1297,11 @@ class TWP_Webhooks {
$from = isset($params['From']) ? $params['From'] : '';
$workflow_id = isset($params['workflow_id']) ? intval($params['workflow_id']) : 0;
// Enhanced customer number detection for voicemails
$customer_number = $from;
// If From is not provided in the callback, try to get it from the call log
if (empty($from) && !empty($call_sid)) {
if (empty($customer_number) && !empty($call_sid)) {
global $wpdb;
$call_log_table = $wpdb->prefix . 'twp_call_log';
$call_record = $wpdb->get_row($wpdb->prepare(
@@ -1306,11 +1309,81 @@ class TWP_Webhooks {
$call_sid
));
if ($call_record && $call_record->from_number) {
$from = $call_record->from_number;
error_log('TWP Voicemail Callback: Retrieved from_number from call log: ' . $from);
$customer_number = $call_record->from_number;
error_log('TWP Voicemail Callback: Retrieved from_number from call log: ' . $customer_number);
}
}
// If we got a client identifier (browser phone), try to find the real customer number
if (!empty($customer_number) && strpos($customer_number, 'client:') === 0) {
error_log('TWP Voicemail Callback: Detected client identifier, looking for customer number');
try {
// Initialize Twilio API to find the customer call leg
$twilio_api = new TWP_Twilio_API();
$client = $twilio_api->get_client();
$call = $client->calls($call_sid)->fetch();
// Use similar logic to find_customer_call_leg but adapted for voicemail
$real_customer_number = null;
// Check if this call has a parent that contains a real phone number
if ($call->parentCallSid) {
try {
$parent_call = $client->calls($call->parentCallSid)->fetch();
if (strpos($parent_call->from, 'client:') === false && strpos($parent_call->from, '+') === 0) {
$real_customer_number = $parent_call->from;
} elseif (strpos($parent_call->to, 'client:') === false && strpos($parent_call->to, '+') === 0) {
$real_customer_number = $parent_call->to;
}
} catch (Exception $e) {
error_log("TWP Voicemail Callback: Could not fetch parent call: " . $e->getMessage());
}
}
// If no parent success, search related calls
if (!$real_customer_number) {
$related_calls = $client->calls->read(['status' => 'completed'], 20);
foreach ($related_calls as $related_call) {
if ($related_call->sid === $call_sid) continue;
// Check if calls are related
$is_related = false;
if ($call->parentCallSid && $related_call->parentCallSid === $call->parentCallSid) {
$is_related = true;
} elseif ($related_call->parentCallSid === $call_sid) {
$is_related = true;
} elseif ($related_call->sid === $call->parentCallSid) {
$is_related = true;
}
if ($is_related) {
if (strpos($related_call->from, 'client:') === false && strpos($related_call->from, '+') === 0) {
$real_customer_number = $related_call->from;
break;
} elseif (strpos($related_call->to, 'client:') === false && strpos($related_call->to, '+') === 0) {
$real_customer_number = $related_call->to;
break;
}
}
}
}
if ($real_customer_number) {
$customer_number = $real_customer_number;
error_log("TWP Voicemail Callback: Found real customer number: {$customer_number}");
} else {
error_log("TWP Voicemail Callback: WARNING - Could not find real customer number, keeping client identifier");
}
} catch (Exception $e) {
error_log("TWP Voicemail Callback: Error finding customer number: " . $e->getMessage());
}
}
// Update $from to use the detected customer number
$from = $customer_number;
// Debug what we extracted
error_log('TWP Voicemail Callback: recording_url=' . $recording_url . ', from=' . $from . ', workflow_id=' . $workflow_id . ', call_sid=' . $call_sid);