Call Recordings: Option to manually submit audio to AI for transcription, if enabled.

This commit is contained in:
fusionate 2024-05-21 14:59:23 -06:00
parent 7312b9ab67
commit 1f8542b9cc
No known key found for this signature in database
5 changed files with 212 additions and 30 deletions

View File

@ -17,7 +17,7 @@
The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com>
Portions created by the Initial Developer are Copyright (C) 2022
Portions created by the Initial Developer are Copyright (C) 2022-2024
the Initial Developer. All Rights Reserved.
Contributor(s):
@ -33,6 +33,7 @@ if ($domains_processed == 1) {
$sql .= " select domain_uuid, xml_cdr_uuid as call_recording_uuid, \n";
$sql .= " caller_id_name, caller_id_number, caller_destination, destination_number, \n";
$sql .= " record_name as call_recording_name, record_path as call_recording_path, \n";
$sql .= " record_transcription as call_recording_transcription, \n";
$sql .= " duration as call_recording_length, start_stamp as call_recording_date, direction as call_direction \n";
$sql .= " from v_xml_cdr \n";
$sql .= " where record_name is not null \n";
@ -45,4 +46,4 @@ if ($domains_processed == 1) {
}
?>
?>

View File

@ -42,6 +42,11 @@
$language = new text;
$text = $language->get();
//add the settings object
$settings = new settings(["domain_uuid" => $_SESSION['domain_uuid'], "user_uuid" => $_SESSION['user_uuid']]);
$transcribe_enabled = $settings->get('transcribe', 'enabled', 'false');
$transcribe_engine = $settings->get('transcribe', 'engine', '');
//set additional variables
$search = $_GET["search"] ?? '';
$show = $_GET["show"] ?? '';
@ -62,6 +67,12 @@
$obj->download($call_recordings);
}
break;
case 'transcribe':
if (permission_exists('call_recording_download')) {
$obj = new call_recordings;
$obj->transcribe($call_recordings);
}
break;
case 'delete':
if (permission_exists('call_recording_delete')) {
$obj = new call_recordings;
@ -119,7 +130,7 @@
//get the list
$sql = "select r.domain_uuid, d.domain_name, r.call_recording_uuid, r.call_direction, ";
$sql .= "r.call_recording_name, r.call_recording_path, r.call_recording_length, ";
$sql .= "r.call_recording_name, r.call_recording_path, r.call_recording_transcription, r.call_recording_length, ";
$sql .= "r.caller_id_name, r.caller_id_number, r.caller_destination, r.destination_number, ";
$sql .= "to_char(timezone(:time_zone, r.call_recording_date), 'DD Mon YYYY') as call_recording_date_formatted, \n";
$sql .= "to_char(timezone(:time_zone, r.call_recording_date), 'HH12:MI:SS am') as call_recording_time_formatted \n";
@ -149,6 +160,14 @@
$call_recordings = $database->select($sql, $parameters ?? null, 'all');
unset($sql, $parameters);
//detect if any transcriptions available
if ($transcribe_enabled == 'true' && !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; }
}
}
//count the results
$result_count = is_array($call_recordings) ? sizeof($call_recordings) : 0;
@ -177,10 +196,13 @@
echo "<div class='action_bar' id='action_bar'>\n";
echo " <div class='heading'><b>".$text['title-call_recordings']." </b></div>\n";
echo " <div class='actions'>\n";
if (permission_exists('call_recording_download') && $call_recordings) {
if (permission_exists('call_recording_download') && !empty($call_recordings)) {
echo button::create(['type'=>'button','label'=>$text['button-download'],'icon'=>$_SESSION['theme']['button_icon_download'],'id'=>'btn_download','name'=>'btn_download','style'=>'display: none;','collapse'=>'hide-xs','onclick'=>"list_action_set('download'); list_form_submit('form_list');"]);
}
if (permission_exists('call_recording_delete') && $call_recordings) {
if ($transcribe_enabled == 'true' && !empty($transcribe_engine) && !empty($call_recordings)) {
echo button::create(['type'=>'button','label'=>$text['button-transcribe'],'icon'=>'quote-right','id'=>'btn_transcribe','name'=>'btn_transcribe','style'=>'display: none;','collapse'=>'hide-xs','onclick'=>"list_action_set('transcribe'); list_form_submit('form_list');"]);
}
if (permission_exists('call_recording_delete') && !empty($call_recordings)) {
echo button::create(['type'=>'button','label'=>$text['button-delete'],'icon'=>$_SESSION['theme']['button_icon_delete'],'id'=>'btn_delete','name'=>'btn_delete','style'=>'display: none; margin-right: 15px;','collapse'=>'hide-xs','onclick'=>"modal_open('modal-delete','btn_delete');"]);
}
echo "<form id='form_search' class='inline' method='get'>\n";
@ -203,7 +225,7 @@
echo " <div style='clear: both;'></div>\n";
echo "</div>\n";
if (permission_exists('call_recording_delete') && $call_recordings) {
if (permission_exists('call_recording_delete') && !empty($call_recordings)) {
echo modal::create(['id'=>'modal-delete','type'=>'delete','actions'=>button::create(['type'=>'button','label'=>$text['button-continue'],'icon'=>'check','id'=>'btn_delete','style'=>'float: right; margin-left: 15px;','collapse'=>'never','onclick'=>"modal_close(); list_action_set('delete'); list_form_submit('form_list');"])]);
}
@ -291,6 +313,9 @@
if (permission_exists('call_recording_download')) {
echo button::create(['type'=>'button','title'=>$text['label-download'],'icon'=>$_SESSION['theme']['button_icon_download'],'link'=>'download.php?id='.urlencode($row['call_recording_uuid']).'&binary']);
}
if ($transcribe_enabled == 'true' && !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;"]);
}
}
echo " </td>\n";
}
@ -303,6 +328,15 @@
echo " </td>\n";
}
echo "</tr>\n";
if ($transcribe_enabled == 'true' && !empty($transcribe_engine) && !empty($row['call_recording_transcription'])) {
echo "<tr style='display: none;'><td></td></tr>\n"; // dummy row to maintain same background color for transcription row
echo "<tr id='transcription_".$row['call_recording_uuid']."' class='list-row' style='display: none;'>\n";
echo " <td style='padding: 10px 20px 15px 20px;' colspan='".$col_count."'>\n";
echo " <strong style='display: inline-block; font-size: 90%; margin-bottom: 10px;'>".$text['label-transcription']."...</strong><br />\n";
echo escape($row['call_recording_transcription'])."\n";
echo " </td>\n";
echo "</tr>\n";
}
$x++;
}
unset($call_recordings);

View File

@ -133,6 +133,96 @@ if (!class_exists('call_recordings')) {
}
}
/**
* transcribe call recordings
*/
public function transcribe($records) {
if (permission_exists($this->name.'_view')) {
//add multi-lingual support
$language = new text;
$text = $language->get();
//validate the token
$token = new token;
if (!$token->validate($_SERVER['PHP_SELF'])) {
message::add($text['message-invalid_token'],'negative');
header('Location: '.$this->location);
exit;
}
//add the settings object
$settings = new settings(["domain_uuid" => $_SESSION['domain_uuid'], "user_uuid" => $_SESSION['user_uuid']]);
$transcribe_enabled = $settings->get('transcribe', 'enabled', 'false');
$transcribe_engine = $settings->get('transcribe', 'engine', '');
//transcribe multiple recordings
if ($transcribe_enabled == 'true' && !empty($transcribe_engine) && is_array($records) && @sizeof($records) != 0) {
//add the transcribe object
$transcribe = new transcribe($settings);
//build the array
$x = 0;
foreach ($records as $record) {
//add to the array
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 ";
$parameters['call_recording_uuid'] = $record['uuid'];
$database = new database;
$field = $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;
}
//increment the id
$x++;
}
unset($sql, $parameters, $field);
}
}
//update the checked rows
if (is_array($array) && @sizeof($array) != 0) {
//add temporary permissions
$p = new permissions;
$p->add('xml_cdr_edit', 'temp');
//remove record_path, record_name and record_length
$database = new database;
$database->app_name = 'xml_cdr';
$database->app_uuid = '4a085c51-7635-ff03-f67b-86e834422848';
$database->save($array, false);
$message = $database->message;
unset($array);
//remove the temporary permissions
$p->delete('xml_cdr_edit', 'temp');
//set message
message::add($text['message-audio_transcribed']);
}
unset($records);
}
}
}
/**
* download the recordings
*/

View File

@ -6202,29 +6202,83 @@ $text['label-translate']['zh-cn'] = "";
$text['label-translate']['ja-jp'] = "";
$text['label-translate']['ko-kr'] = "";
$text['description-language']['en-us'] = "Select the language, voice and dialect.";
$text['description-language']['en-gb'] = "Select the language, voice and dialect.";
$text['description-language']['ar-eg'] = "";
$text['description-language']['de-at'] = "";
$text['description-language']['de-ch'] = "";
$text['description-language']['de-de'] = "";
$text['description-language']['es-cl'] = "";
$text['description-language']['es-mx'] = "";
$text['description-language']['fr-ca'] = "Sélectionnez la langue, la voix et le dialecte.";
$text['description-language']['fr-fr'] = "Sélectionnez la langue, la voix et le dialecte.";
$text['description-language']['he-il'] = "";
$text['description-language']['it-it'] = "";
$text['description-language']['nl-nl'] = "";
$text['description-language']['pl-pl'] = "";
$text['description-language']['pt-br'] = "";
$text['description-language']['pt-pt'] = "";
$text['description-language']['ro-ro'] = "";
$text['description-language']['ru-ru'] = "";
$text['description-language']['sv-se'] = "";
$text['description-language']['uk-ua'] = "";
$text['description-language']['zh-cn'] = "";
$text['description-language']['ja-jp'] = "";
$text['description-language']['ko-kr'] = "";
$text['button-transcribe']['en-us'] = "Transcribe";
$text['button-transcribe']['en-gb'] = "Transcribe";
$text['button-transcribe']['ar-eg'] = "نسخ";
$text['button-transcribe']['de-at'] = "transkribieren";
$text['button-transcribe']['de-ch'] = "transkribieren";
$text['button-transcribe']['de-de'] = "transkribieren";
$text['button-transcribe']['el-gr'] = "Αντιγράφω";
$text['button-transcribe']['es-cl'] = "transcribir";
$text['button-transcribe']['es-mx'] = "transcribir";
$text['button-transcribe']['fr-ca'] = "transcrire";
$text['button-transcribe']['fr-fr'] = "transcrire";
$text['button-transcribe']['he-il'] = "לְתַעֲתֵק";
$text['button-transcribe']['it-it'] = "trascrivere";
$text['button-transcribe']['nl-nl'] = "overschrijven";
$text['button-transcribe']['pl-pl'] = "rozpisać";
$text['button-transcribe']['pt-br'] = "transcrever";
$text['button-transcribe']['pt-pt'] = "transcrever";
$text['button-transcribe']['ro-ro'] = "Transcrie";
$text['button-transcribe']['ru-ru'] = "транскрибировать";
$text['button-transcribe']['sv-se'] = "transkribera";
$text['button-transcribe']['uk-ua'] = "переписати";
$text['button-transcribe']['tr-tr'] = "Uyarlamak";
$text['button-transcribe']['zh-cn'] = "录制";
$text['button-transcribe']['ja-jp'] = "転写する";
$text['button-transcribe']['ko-kr'] = "고쳐 쓰다";
$text['label-transcription']['en-us'] = "Transcription";
$text['label-transcription']['en-gb'] = "Transcription";
$text['label-transcription']['ar-eg'] = "النسخ";
$text['label-transcription']['de-at'] = "Transkription";
$text['label-transcription']['de-ch'] = "Transkription";
$text['label-transcription']['de-de'] = "Transkription";
$text['label-transcription']['el-gr'] = "Μεταγραφή";
$text['label-transcription']['es-cl'] = "Transcripción";
$text['label-transcription']['es-mx'] = "Transcripción";
$text['label-transcription']['fr-ca'] = "Transcription";
$text['label-transcription']['fr-fr'] = "Transcription";
$text['label-transcription']['he-il'] = "תַעֲתוּק";
$text['label-transcription']['it-it'] = "Trascrizione";
$text['label-transcription']['nl-nl'] = "Overschrijving";
$text['label-transcription']['pl-pl'] = "Transkrypcja";
$text['label-transcription']['pt-br'] = "Transcrição";
$text['label-transcription']['pt-pt'] = "Transcrição";
$text['label-transcription']['ro-ro'] = "Transcriere";
$text['label-transcription']['ru-ru'] = "Транскрипция";
$text['label-transcription']['sv-se'] = "Transcription";
$text['label-transcription']['uk-ua'] = "Транскрипція";
$text['label-transcription']['tr-tr'] = "Transkripsiyon";
$text['label-transcription']['zh-cn'] = "转录";
$text['label-transcription']['ja-jp'] = "転写";
$text['label-transcription']['ko-kr'] = "전사";
$text['message-audio_transcribed']['en-us'] = "Audio Transcribed";
$text['message-audio_transcribed']['en-gb'] = "Audio Transcribed";
$text['message-audio_transcribed']['ar-eg'] = "";
$text['message-audio_transcribed']['de-at'] = "";
$text['message-audio_transcribed']['de-ch'] = "";
$text['message-audio_transcribed']['de-de'] = "";
$text['message-audio_transcribed']['el-gr'] = "";
$text['message-audio_transcribed']['es-cl'] = "";
$text['message-audio_transcribed']['es-mx'] = "";
$text['message-audio_transcribed']['fr-ca'] = "";
$text['message-audio_transcribed']['fr-fr'] = "";
$text['message-audio_transcribed']['he-il'] = "";
$text['message-audio_transcribed']['it-it'] = "";
$text['message-audio_transcribed']['nl-nl'] = "";
$text['message-audio_transcribed']['pl-pl'] = "";
$text['message-audio_transcribed']['pt-br'] = "";
$text['message-audio_transcribed']['pt-pt'] = "";
$text['message-audio_transcribed']['ro-ro'] = "";
$text['message-audio_transcribed']['ru-ru'] = "";
$text['message-audio_transcribed']['sv-se'] = "";
$text['message-audio_transcribed']['uk-ua'] = "";
$text['message-audio_transcribed']['tr-tr'] = "";
$text['message-audio_transcribed']['zh-cn'] = "";
$text['message-audio_transcribed']['ja-jp'] = "";
$text['message-audio_transcribed']['ko-kr'] = "";
$text['button-setup']['en-us'] = "Setup";
$text['button-setup']['en-gb'] = "Setup";
@ -6304,4 +6358,4 @@ $text['button-hide']['zh-cn'] = "隐藏";
$text['button-hide']['ja-jp'] = "隠れる";
$text['button-hide']['ko-kr'] = "숨다";
?>
?>

View File

@ -905,17 +905,20 @@
btn_toggle = document.getElementById("btn_toggle");
btn_delete = document.getElementById("btn_delete");
btn_download = document.getElementById("btn_download");
btn_transcribe = document.getElementById("btn_transcribe");
if (checked == true) {
if (btn_copy) { btn_copy.style.display = "inline"; }
if (btn_toggle) { btn_toggle.style.display = "inline"; }
if (btn_delete) { btn_delete.style.display = "inline"; }
if (btn_download) { btn_download.style.display = "inline"; }
if (btn_transcribe) { btn_transcribe.style.display = "inline"; }
}
else {
if (btn_copy) { btn_copy.style.display = "none"; }
if (btn_toggle) { btn_toggle.style.display = "none"; }
if (btn_delete) { btn_delete.style.display = "none"; }
if (btn_download) { btn_download.style.display = "none"; }
if (btn_transcribe) { btn_transcribe.style.display = "none"; }
}
}
{/literal}