From ec439999b3435152c41a9879353548e5e7c1acdb Mon Sep 17 00:00:00 2001 From: FusionPBX Date: Wed, 26 Nov 2025 06:18:56 -0700 Subject: [PATCH] Add call recordings to the transcribe queue --- app/call_recordings/call_recordings.php | 24 ++-- .../resources/classes/call_recordings.php | 116 ++++++++--------- app/xml_cdr/xml_cdr_details.php | 121 +++++++++++++----- 3 files changed, 157 insertions(+), 104 deletions(-) diff --git a/app/call_recordings/call_recordings.php b/app/call_recordings/call_recordings.php index 73f55f2ec9..2db96c69df 100644 --- a/app/call_recordings/call_recordings.php +++ b/app/call_recordings/call_recordings.php @@ -138,7 +138,7 @@ if ($transcribe_enabled && !empty($transcribe_engine) && !empty($call_recordings) && is_array($call_recordings)) { $transcriptions_exists = false; foreach ($call_recordings as $row) { - if (!empty($row['call_recording_transcription'])) { $transcriptions_exists = true; } +// if (!empty($row['call_recording_transcription'])) { $transcriptions_exists = true; } } } @@ -282,8 +282,8 @@ if (permission_exists('call_recording_download')) { echo button::create(['type'=>'button','title'=>$text['label-download'],'icon'=>$settings->get('theme', 'button_icon_download'),'link'=>'download.php?id='.urlencode($row['call_recording_uuid']).'&binary']); } - if (permission_exists('call_recording_transcribe') && $transcribe_enabled && !empty($transcribe_engine) && $transcriptions_exists === true) { - echo button::create(['type'=>'button','title'=>$text['label-transcription'],'icon'=>'quote-right','style'=>(empty($row['call_recording_transcription']) ? 'visibility:hidden;' : null),'onclick'=>"document.getElementById('transcription_".$row['call_recording_uuid']."').style.display = document.getElementById('transcription_".$row['call_recording_uuid']."').style.display == 'none' ? 'table-row' : 'none'; this.blur(); return false;"]); + if (permission_exists('call_recording_transcribe') && $transcribe_enabled && !empty($transcribe_engine) && !empty($row['call_recording_transcription'])) { + echo button::create(['type'=>'button','title'=>$text['label-transcription'],'icon'=>'quote-right','style'=>'','link'=>PROJECT_PATH.'/app/xml_cdr/xml_cdr_details.php?id='.urlencode($row['call_recording_uuid'])]); } } echo " \n"; @@ -297,15 +297,15 @@ echo " \n"; } echo "\n"; - if (permission_exists('call_recording_transcribe') && $transcribe_enabled && !empty($transcribe_engine) && !empty($row['call_recording_transcription'])) { - echo "\n"; // dummy row to maintain same background color for transcription row - echo "\n"; - echo " \n"; - echo " ".$text['label-transcription']."...
\n"; - echo escape($row['call_recording_transcription'])."\n"; - echo " \n"; - echo "\n"; - } + // if (permission_exists('call_recording_transcribe') && $transcribe_enabled && !empty($transcribe_engine) && !empty($row['call_recording_transcription'])) { + // echo "\n"; // dummy row to maintain same background color for transcription row + // echo "\n"; + // echo " \n"; + // echo " ".$text['label-transcription']."...
\n"; + // echo escape($row['call_recording_transcription'])."\n"; + // echo " \n"; + // echo "\n"; + // } $x++; } unset($call_recordings); diff --git a/app/call_recordings/resources/classes/call_recordings.php b/app/call_recordings/resources/classes/call_recordings.php index bf53eed18b..16635a1e69 100644 --- a/app/call_recordings/resources/classes/call_recordings.php +++ b/app/call_recordings/resources/classes/call_recordings.php @@ -209,7 +209,7 @@ class call_recordings { if (permission_exists($this->name . '_view')) { //add multi-lingual support $language = new text; - $text = $language->get(); + $text = $language->get(); //validate the token $token = new token; @@ -225,8 +225,6 @@ class call_recordings { //transcribe multiple recordings if ($transcribe_enabled && !empty($transcribe_engine) && is_array($records) && @sizeof($records) != 0) { - //add the transcribe object - $transcribe = new transcribe($this->settings); //build the array $x = 0; @@ -235,27 +233,30 @@ class call_recordings { if (!empty($record['checked']) && $record['checked'] == 'true' && is_uuid($record['uuid'])) { //get the call recording file name and path - $sql = "select call_recording_name, call_recording_path "; - $sql .= "from view_call_recordings "; - $sql .= "where call_recording_uuid = :call_recording_uuid "; - $sql .= "and call_recording_transcription is null "; + $sql = "select call_recording_name, call_recording_path "; + $sql .= "from view_call_recordings "; + $sql .= "where call_recording_uuid = :call_recording_uuid "; + $sql .= "and call_recording_transcription is null "; $parameters['call_recording_uuid'] = $record['uuid']; - $field = $this->database->select($sql, $parameters, 'row'); + $field = $this->database->select($sql, $parameters, 'row'); if ( is_array($field) && @sizeof($field) != 0 && file_exists($field['call_recording_path'] . '/' . $field['call_recording_name']) ) { - //audio to text - get the transcription from the audio file - $transcribe->audio_path = $field['call_recording_path']; - $transcribe->audio_filename = $field['call_recording_name']; - $record_transcription = $transcribe->transcribe(); - - //build call recording data array - if (!empty($record_transcription)) { - $array['xml_cdr'][$x]['xml_cdr_uuid'] = $record['uuid']; - $array['xml_cdr'][$x]['record_transcription'] = $record_transcription; - } + //add the recording to the transcribe queue + $array['transcribe_queue'][$x]['transcribe_queue_uuid'] = uuid(); + $array['transcribe_queue'][$x]['domain_uuid'] = $_SESSION['domain_uuid']; + $array['transcribe_queue'][$x]['hostname'] = gethostname(); + $array['transcribe_queue'][$x]['transcribe_status'] = 'pending'; + $array['transcribe_queue'][$x]['transcribe_application_name'] = 'call_recordings'; + $array['transcribe_queue'][$x]['transcribe_application_uuid'] = '56165644-598d-4ed8-be01-d960bcb8ffed'; + $array['transcribe_queue'][$x]['transcribe_audio_path'] = $field['call_recording_path']; + $array['transcribe_queue'][$x]['transcribe_audio_name'] = $field['call_recording_name']; + $array['transcribe_queue'][$x]['transcribe_target_table'] = 'xml_cdr'; + $array['transcribe_queue'][$x]['transcribe_target_key_name'] = 'xml_cdr_uuid'; + $array['transcribe_queue'][$x]['transcribe_target_key_uuid'] = $record['uuid']; + $array['transcribe_queue'][$x]['transcribe_target_column_name'] = 'record_transcription'; //increment the id $x++; @@ -270,17 +271,16 @@ class call_recordings { //add temporary permissions $p = permissions::new(); - $p->add('xml_cdr_edit', 'temp'); + $p->add('transcribe_queue_add', 'temp'); //remove record_path, record_name and record_length $this->database->app_name = 'xml_cdr'; $this->database->app_uuid = '4a085c51-7635-ff03-f67b-86e834422848'; $this->database->save($array, false); - $message = $this->database->message; unset($array); //remove the temporary permissions - $p->delete('xml_cdr_edit', 'temp'); + $p->delete('transcribe_queue_add', 'temp'); //set message message::add($text['message-audio_transcribed']); @@ -341,29 +341,29 @@ class call_recordings { if (!empty($storage_type) && $storage_type == 'base64' && !empty($row['call_recording_base64'])) { $sql .= ", call_recording_base64 "; } - $sql .= "from view_call_recordings "; - $sql .= "where call_recording_uuid = :call_recording_uuid "; + $sql .= "from view_call_recordings "; + $sql .= "where call_recording_uuid = :call_recording_uuid "; $parameters['call_recording_uuid'] = $this->recording_uuid; - $parameters['time_zone'] = $time_zone; - $row = $this->database->select($sql, $parameters, 'row'); + $parameters['time_zone'] = $time_zone; + $row = $this->database->select($sql, $parameters, 'row'); if (is_array($row) && @sizeof($row) != 0) { - $call_recording_uuid = $row['call_recording_uuid']; - $caller_id_name = $row['caller_id_name']; - $caller_id_number = $row['caller_id_number']; - $caller_destination = $row['caller_destination']; - $destination_number = $row['destination_number']; - $call_recording_name = $row['call_recording_name']; - $call_recording_path = $row['call_recording_path']; - $call_recording_date = $row['call_recording_date']; - $call_direction = $row['call_direction']; - $call_recording_year = $row['call_recording_year']; - $call_recording_month_name = $row['call_recording_month_name']; - $call_recording_month_number = $row['call_recording_month_number']; - $call_recording_day = $row['call_recording_day']; - $call_recording_time = $row['call_recording_time']; + $call_recording_uuid = $row['call_recording_uuid']; + $caller_id_name = $row['caller_id_name']; + $caller_id_number = $row['caller_id_number']; + $caller_destination = $row['caller_destination']; + $destination_number = $row['destination_number']; + $call_recording_name = $row['call_recording_name']; + $call_recording_path = $row['call_recording_path']; + $call_recording_date = $row['call_recording_date']; + $call_direction = $row['call_direction']; + $call_recording_year = $row['call_recording_year']; + $call_recording_month_name = $row['call_recording_month_name']; + $call_recording_month_number = $row['call_recording_month_number']; + $call_recording_day = $row['call_recording_day']; + $call_recording_time = $row['call_recording_time']; $call_recording_date_formatted = $row['call_recording_date_formatted']; $call_recording_time_formatted = $row['call_recording_time_formatted']; - $call_recording_base64 = $row['call_recording_base64']; + $call_recording_base64 = $row['call_recording_base64']; if (!empty($storage_type) && $storage_type == 'base64' && !empty($row['call_recording_base64'])) { file_put_contents($call_recording_path . '/' . $call_recording_name, base64_decode($row['call_recording_base64'])); } @@ -440,7 +440,7 @@ class call_recordings { //add multi-lingual support $language = new text; - $text = $language->get(); + $text = $language->get(); //validate the token $token = new token; @@ -483,26 +483,26 @@ class call_recordings { if (!empty($storage_type) && $storage_type == 'base64') { $sql .= ", call_recording_base64 "; } - $sql .= "from view_call_recordings "; - $sql .= "where call_recording_uuid in ('" . implode("','", $uuids) . "') "; + $sql .= "from view_call_recordings "; + $sql .= "where call_recording_uuid in ('" . implode("','", $uuids) . "') "; $parameters['time_zone'] = $time_zone; - $rows = $this->database->select($sql, $parameters, 'all'); + $rows = $this->database->select($sql, $parameters, 'all'); if (!empty($rows) && is_array($rows) && @sizeof($rows) != 0) { foreach ($rows as $row) { - $call_recording_uuid = $row['call_recording_uuid']; - $caller_id_name = $row['caller_id_name']; - $caller_id_number = $row['caller_id_number']; - $caller_destination = $row['caller_destination']; - $destination_number = $row['destination_number']; - $call_recording_name = $row['call_recording_name']; - $call_recording_path = $row['call_recording_path']; - $call_recording_date = $row['call_recording_date']; - $call_direction = $row['call_direction']; - $call_recording_year = $row['call_recording_year']; - $call_recording_month_name = $row['call_recording_month_name']; - $call_recording_month_number = $row['call_recording_month_number']; - $call_recording_day = $row['call_recording_day']; - $call_recording_time = $row['call_recording_time']; + $call_recording_uuid = $row['call_recording_uuid']; + $caller_id_name = $row['caller_id_name']; + $caller_id_number = $row['caller_id_number']; + $caller_destination = $row['caller_destination']; + $destination_number = $row['destination_number']; + $call_recording_name = $row['call_recording_name']; + $call_recording_path = $row['call_recording_path']; + $call_recording_date = $row['call_recording_date']; + $call_direction = $row['call_direction']; + $call_recording_year = $row['call_recording_year']; + $call_recording_month_name = $row['call_recording_month_name']; + $call_recording_month_number = $row['call_recording_month_number']; + $call_recording_day = $row['call_recording_day']; + $call_recording_time = $row['call_recording_time']; $call_recording_date_formatted = $row['call_recording_date_formatted']; $call_recording_time_formatted = $row['call_recording_time_formatted']; if (!empty($storage_type) && $storage_type == 'base64' && !empty($row['call_recording_base64'])) { diff --git a/app/xml_cdr/xml_cdr_details.php b/app/xml_cdr/xml_cdr_details.php index bd19213811..122a0d7831 100644 --- a/app/xml_cdr/xml_cdr_details.php +++ b/app/xml_cdr/xml_cdr_details.php @@ -84,47 +84,43 @@ unset($sql, $parameters, $row); //transcribe, if enabled - if ( - !empty($_GET['action']) && - $_GET['action'] == 'transcribe' && - $transcribe_enabled && - !empty($transcribe_engine) && - empty($record_transcription) && - !empty($record_path) && - !empty($record_name) && - file_exists($record_path.'/'.$record_name) - ) { - //add the transcribe object - $transcribe = new transcribe($settings); - //audio to text - get the transcription from the audio file - $transcribe->audio_path = $record_path; - $transcribe->audio_filename = $record_name; - $record_transcription = $transcribe->transcribe(); - //build call recording data array - if (!empty($record_transcription)) { - $array['xml_cdr'][0]['xml_cdr_uuid'] = $uuid; - $array['xml_cdr'][0]['record_transcription'] = $record_transcription; - } - //update the checked rows - if (is_array($array) && @sizeof($array) != 0) { + if (!empty($_GET['action']) && $_GET['action'] == 'transcribe' && + $transcribe_enabled && !empty($transcribe_engine) && + !empty($record_path) && !empty($record_name) && + file_exists($record_path.'/'.$record_name)) { + //add the recording to the transcribe queue + $array['transcribe_queue'][$x]['transcribe_queue_uuid'] = uuid(); + $array['transcribe_queue'][$x]['domain_uuid'] = $_SESSION['domain_uuid']; + $array['transcribe_queue'][$x]['hostname'] = gethostname(); + $array['transcribe_queue'][$x]['transcribe_status'] = 'pending'; + $array['transcribe_queue'][$x]['transcribe_application_name'] = 'call_recordings'; + $array['transcribe_queue'][$x]['transcribe_application_uuid'] = '56165644-598d-4ed8-be01-d960bcb8ffed'; + $array['transcribe_queue'][$x]['transcribe_audio_path'] = $record_path; + $array['transcribe_queue'][$x]['transcribe_audio_name'] = $record_name; + $array['transcribe_queue'][$x]['transcribe_target_table'] = 'xml_cdr'; + $array['transcribe_queue'][$x]['transcribe_target_key_name'] = 'xml_cdr_uuid'; + $array['transcribe_queue'][$x]['transcribe_target_key_uuid'] = $uuid; + $array['transcribe_queue'][$x]['transcribe_target_column_name'] = 'record_transcription'; + + //add the checked rows + if (is_array($array) && @sizeof($array) != 0) { //add temporary permissions - $p = permissions::new(); - $p->add('xml_cdr_edit', 'temp'); + $p = permissions::new(); + $p->add('transcribe_queue_add', 'temp'); //remove record_path, record_name and record_length - $database->save($array, false); - //$message = $database->message; - unset($array); + $database->save($array, false); + unset($array); //remove the temporary permissions - $p->delete('xml_cdr_edit', 'temp'); + $p->delete('transcribe_queue_add', 'temp'); //set message - message::add($text['message-audio_transcribed']); - + message::add($text['message-audio_transcribed']); } - //redirect + + //redirect header('Location: '.$_SERVER['PHP_SELF'].'?id='.$uuid); exit; } @@ -368,6 +364,28 @@ $summary_array['hangup_cause'] = escape($hangup_cause); } +//convert the transcription into a conversation + function conversational_html($transcription) { + $html = ''; + $previous_speaker = ''; + $i = 0; + foreach ($transcription as $segment) { + if ($previous_speaker != $segment['speaker']) { + if ($i > 0) { $html .= "\n"; } + $speaker_class = $segment['speaker'] === 'A' ? 'message-bubble-em' : 'message-bubble-me'; + $html .= "
"; + } + //$html .= " [{$segment['start']} - {$segment['end']}]"; + $html .= "".escape(trim($segment['text']))." "; + if ($previous_speaker != $segment['speaker']) { + $previous_speaker = $segment['speaker']; + } + $i++; + } + $html .= "
\n"; + return $html; + } + //get the header require_once "resources/header.php"; @@ -380,7 +398,7 @@ if (permission_exists('xml_cdr_call_log') && $call_log_enabled && isset($log_content) && !empty($log_content)) { echo button::create(['type'=>'button','label'=>$text['button-call_log'],'icon'=>$settings->get('theme', 'button_icon_search'),'style'=>'margin-left: 15px;','link'=>'xml_cdr_log.php?id='.$uuid]); } - if ($transcribe_enabled && !empty($transcribe_engine) && empty($record_transcription) && !empty($record_path) && !empty($record_name) && file_exists($record_path.'/'.$record_name)) { + if ($transcribe_enabled && !empty($transcribe_engine) && !empty($record_path) && !empty($record_name) && file_exists($record_path.'/'.$record_name)) { echo button::create(['type'=>'button','label'=>$text['button-transcribe'],'icon'=>'quote-right','id'=>'btn_transcribe','name'=>'btn_transcribe','collapse'=>'hide-xs','style'=>'margin-left: 15px;','onclick'=>"window.location.href='?id=".$uuid."&action=transcribe';"]); } echo "\n"; @@ -583,7 +601,42 @@ echo "\n"; } +//css styles + echo "\n"; + //transcription, if enabled + $transcription_array = json_decode($record_transcription, true); + $record_transcription = $transcription_array['segments']; + $record_transcription_html = conversational_html($record_transcription); if ($transcribe_enabled == 'true' && !empty($transcribe_engine) && !empty($record_transcription)) { echo "".$text['label-transcription']."
\n"; echo "
\n"; @@ -592,7 +645,7 @@ echo " ".$text['label-text']."\n"; echo " \n"; echo " \n"; - echo " ".escape($record_transcription)."\n"; + echo "
".$record_transcription_html."
\n"; echo " \n"; echo " "; echo "
\n";