From d79c7b1cb900a607d936f643de81ddb400b84382 Mon Sep 17 00:00:00 2001 From: fusionate Date: Thu, 1 Aug 2024 10:27:15 -0600 Subject: [PATCH] Voicemail: Integrate message forward intro playback in web interface, and prepend intro on emailed audio file. --- app/email_queue/resources/jobs/email_send.php | 29 ++- .../resources/functions/delete_recording.lua | 1 + .../resources/functions/forward_add_intro.lua | 16 +- .../functions/forward_to_extension.lua | 6 +- .../resources/functions/send_email.lua | 61 +++++-- app/voicemails/app_languages.php | 80 ++++++++- .../resources/classes/voicemail.php | 169 +++++++++++++++++- app/voicemails/voicemail_messages.php | 33 +++- themes/default/app_config.php | 8 + themes/default/template.php | 15 +- 10 files changed, 374 insertions(+), 44 deletions(-) diff --git a/app/email_queue/resources/jobs/email_send.php b/app/email_queue/resources/jobs/email_send.php index 36e02227c3..962e617e08 100644 --- a/app/email_queue/resources/jobs/email_send.php +++ b/app/email_queue/resources/jobs/email_send.php @@ -376,12 +376,14 @@ //remove the email file after it has been sent if (is_array($email_queue_attachments) && @sizeof($email_queue_attachments) != 0) { - foreach($email_queue_attachments as $field) { + foreach ($email_queue_attachments as $field) { $email_attachment_path = $field['email_attachment_path']; $email_attachment_name = $field['email_attachment_name']; - if (file_exists($email_attachment_path.'/'.$email_attachment_name)) { - unlink($email_attachment_path.'/'.$email_attachment_name); - } + $email_attachment_name_no_prefix = str_replace(['msg_','intro_'], '', pathinfo($email_attachment_name, PATHINFO_BASENAME)); + @unlink($email_attachment_path.'/'.$email_attachment_name); + @unlink($email_attachment_path.'/intro_'.$email_attachment_name_no_prefix); + @unlink($email_attachment_path.'/msg_'.$email_attachment_name_no_prefix); + @unlink($email_attachment_path.'/intro_msg_'.$email_attachment_name_no_prefix); } } @@ -413,6 +415,25 @@ } } + if ($settings->get('voicemail', 'storage_type') == 'base64') { + //delay the delete by a few seconds + sleep(3); + + //remove message files after email sent + if (is_array($email_queue_attachments) && @sizeof($email_queue_attachments) != 0) { + foreach ($email_queue_attachments as $field) { + $email_attachment_path = $field['email_attachment_path']; + $email_attachment_name = $field['email_attachment_name']; + $email_attachment_name_no_prefix = str_replace(['msg_','intro_'], '', pathinfo($email_attachment_name, PATHINFO_BASENAME)); + @unlink($email_attachment_path.'/'.$email_attachment_name); + @unlink($email_attachment_path.'/intro_'.$email_attachment_name_no_prefix); + @unlink($email_attachment_path.'/msg_'.$email_attachment_name_no_prefix); + @unlink($email_attachment_path.'/intro_msg_'.$email_attachment_name_no_prefix); + } + } + } + + /* //build insert array $array['email_queue'][0]['email_queue_uuid'] = $email_queue_uuid; diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/delete_recording.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/delete_recording.lua index 1278cdceaf..7acc4a1694 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/delete_recording.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/delete_recording.lua @@ -44,6 +44,7 @@ --flush dtmf digits from the input buffer session:flushDigits(); --delete the file + os.remove(voicemail_dir.."/"..voicemail_id.."/intro_msg_"..uuid.."."..vm_message_ext); os.remove(voicemail_dir.."/"..voicemail_id.."/intro_"..uuid.."."..vm_message_ext); os.remove(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext); --delete from the database diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/forward_add_intro.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/forward_add_intro.lua index 07afe55940..1663a0b5d3 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/forward_add_intro.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/forward_add_intro.lua @@ -53,8 +53,7 @@ session:streamFile("tone_stream://L=1;%(1000, 0, 640)"); end - --set the file full path - message_location = voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext; + --set the full message intro path message_intro_location = voicemail_dir.."/"..voicemail_id.."/intro_"..uuid.."."..vm_message_ext; --record the message introduction @@ -100,13 +99,13 @@ local file = require "resources.functions.file" --get the content of the file - local file_content = assert(file.read_base64(message_intro_location)); + file_content = assert(file.read_base64(message_intro_location)); --save the merged file as base64 - local sql = [[UPDATE SET v_voicemail_messages - SET message_intro_base64 = :file_content - WHERE domain_uuid = :domain_uuid - AND voicemail_message_uuid = :uuid]]; + local sql = [[UPDATE v_voicemail_messages + SET message_intro_base64 = :file_content + WHERE domain_uuid = :domain_uuid + AND voicemail_message_uuid = :uuid]]; local params = {file_content = file_content, domain_uuid = domain_uuid, uuid = uuid}; if (debug["sql"]) then @@ -116,6 +115,9 @@ local dbh = Database.new('system', 'base64') dbh:query(sql, params) dbh:release() + + --delete intro file + os.remove(message_intro_location); end end diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/forward_to_extension.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/forward_to_extension.lua index d6ac517e2d..5c07b0f5f1 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/forward_to_extension.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/forward_to_extension.lua @@ -65,6 +65,7 @@ message_length = row["message_length"]; message_status = row["message_status"]; message_priority = row["message_priority"]; + message_intro_base64 = row["message_intro_base64"]; message_base64 = row["message_base64"]; end); end @@ -97,6 +98,7 @@ table.insert(sql, "domain_uuid, "); table.insert(sql, "voicemail_uuid, "); if (storage_type == "base64") then + table.insert(sql, "message_intro_base64, "); table.insert(sql, "message_base64, "); end table.insert(sql, "created_epoch, "); @@ -112,6 +114,7 @@ table.insert(sql, ":domain_uuid, "); table.insert(sql, ":forward_voicemail_uuid, "); if (storage_type == "base64") then + table.insert(sql, ":message_intro_base64, "); table.insert(sql, ":message_base64, "); end table.insert(sql, ":created_epoch, "); @@ -126,6 +129,7 @@ voicemail_message_uuid = voicemail_message_uuid; domain_uuid = domain_uuid; forward_voicemail_uuid = forward_voicemail_uuid; + message_intro_base64 = message_intro_base64; message_base64 = message_base64; created_epoch = created_epoch; caller_id_name = caller_id_name; @@ -157,7 +161,7 @@ mwi_notify(forward_voicemail_id.."@"..domain_name, new_messages, saved_messages) blf_notify(tonumber(new_messages) > 0, "voicemail+" .. forward_voicemail_id .. "@" .. domain_name) - --if local after email is true then copy the recording file + --if storage type is not base64 then copy the recording file if (storage_type ~= "base64") then mkdir(voicemail_dir.."/"..forward_voicemail_id); copy(voicemail_dir.."/"..voicemail_id.."/msg_"..uuid.."."..vm_message_ext, voicemail_dir.."/"..forward_voicemail_id.."/msg_"..voicemail_message_uuid.."."..vm_message_ext); diff --git a/app/switch/resources/scripts/app/voicemail/resources/functions/send_email.lua b/app/switch/resources/scripts/app/voicemail/resources/functions/send_email.lua index 819dc7fabc..1b89cac36e 100644 --- a/app/switch/resources/scripts/app/voicemail/resources/functions/send_email.lua +++ b/app/switch/resources/scripts/app/voicemail/resources/functions/send_email.lua @@ -144,16 +144,22 @@ --message_priority = row["message_priority"]; --get the recordings from the database if (storage_type == "base64") then - --set the voicemail message path + --set the voicemail intro and message paths message_location = voicemail_dir.."/"..id.."/msg_"..uuid.."."..vm_message_ext; + intro_location = voicemail_dir.."/"..id.."/intro_"..uuid.."."..vm_message_ext; - --save the recording to the file system + --save the recordings to the file system if (string.len(row["message_base64"]) > 32) then --include the file io local file = require "resources.functions.file" - --write decoded string to file + --write decoded message string to file file.write_base64(message_location, row["message_base64"]); + + --write decoded intro string to file, if any + if (string.len(row["message_intro_base64"]) > 32) then + file.write_base64(intro_location, row["message_intro_base64"]); + end end end end); @@ -229,6 +235,16 @@ --prepare file file = voicemail_dir.."/"..id.."/msg_"..uuid.."."..vm_message_ext; + --find the location of sox, if installed + sox = os.execute('which sox'); + + --combine intro, if exists, with message for emailing (only) + intro = voicemail_dir.."/"..id.."/intro_"..uuid.."."..vm_message_ext; + combined = voicemail_dir.."/"..id.."/intro_msg_"..uuid.."."..vm_message_ext; + if (file_exists(intro) and sox ~= nil and sox ~= '') then + os.execute(sox.." "..intro.." "..file.." "..combined); + end + --prepare the subject if (subject ~= nil) then subject = subject:gsub("${caller_id_name}", caller_id_name); @@ -308,13 +324,22 @@ smtp_from = smtp_from_name.."<"..smtp_from..">"; end - --send the email - send_mail(headers, - smtp_from, - voicemail_mail_to, - {subject, body}, - (voicemail_file == "attach") and file - ); + --send the email with, or without, including the intro + if (file_exists(combined)) then + send_mail(headers, + smtp_from, + voicemail_mail_to, + {subject, body}, + (voicemail_file == "attach") and combined + ); + else + send_mail(headers, + smtp_from, + voicemail_mail_to, + {subject, body}, + (voicemail_file == "attach") and file + ); + end end --whether to keep the voicemail message and details local after email @@ -331,19 +356,31 @@ freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "; params:" .. json.encode(params) .. "\n"); end dbh:query(sql, params); - --delete voicemail recording file + --delete voicemail recording files if (file_exists(file)) then os.remove(file); end + if (file_exists(intro)) then + os.remove(intro); + end + if (file_exists(combined)) then + os.remove(combined); + end --set message waiting indicator message_waiting(id, domain_uuid); --clear the variable db_voicemail_uuid = ''; elseif (storage_type == "base64") then - --delete voicemail recording file + --delete voicemail recording files if (file_exists(file)) then os.remove(file); end + if (file_exists(intro)) then + os.remove(intro); + end + if (file_exists(combined)) then + os.remove(combined); + end end end diff --git a/app/voicemails/app_languages.php b/app/voicemails/app_languages.php index 546c7770c8..b2ec53e0ba 100644 --- a/app/voicemails/app_languages.php +++ b/app/voicemails/app_languages.php @@ -2547,4 +2547,82 @@ $text['label-listen']['zh-cn'] = "听"; $text['label-listen']['ja-jp'] = "聞く"; $text['label-listen']['ko-kr'] = "듣다"; -?> +$text['label-introduction']['en-us'] = "Intro"; +$text['label-introduction']['en-gb'] = "Intro"; +$text['label-introduction']['ar-eg'] = "مقدمة"; +$text['label-introduction']['de-at'] = "Einführung"; +$text['label-introduction']['de-ch'] = "Einführung"; +$text['label-introduction']['de-de'] = "Einführung"; +$text['label-introduction']['el-gr'] = "Εισαγωγή"; +$text['label-introduction']['es-cl'] = "Introducción"; +$text['label-introduction']['es-mx'] = "Introducción"; +$text['label-introduction']['fr-ca'] = "Introduction"; +$text['label-introduction']['fr-fr'] = "Introduction"; +$text['label-introduction']['he-il'] = "מבוא"; +$text['label-introduction']['it-it'] = "introduzione"; +$text['label-introduction']['nl-nl'] = "Invoering"; +$text['label-introduction']['pl-pl'] = "Wstęp"; +$text['label-introduction']['pt-br'] = "Introdução"; +$text['label-introduction']['pt-pt'] = "Introdução"; +$text['label-introduction']['ro-ro'] = "Introducere"; +$text['label-introduction']['ru-ru'] = "Введение"; +$text['label-introduction']['sv-se'] = "Introduktion"; +$text['label-introduction']['uk-ua'] = "вступ"; +$text['label-introduction']['tr-tr'] = "giriiş"; +$text['label-introduction']['zh-cn'] = "介绍"; +$text['label-introduction']['ja-jp'] = "導入"; +$text['label-introduction']['ko-kr'] = "소개"; + +$text['label-message']['en-us'] = "Message"; +$text['label-message']['en-gb'] = "Message"; +$text['label-message']['ar-eg'] = "رسالة"; +$text['label-message']['de-at'] = "Nachricht"; +$text['label-message']['de-ch'] = "Nachricht"; +$text['label-message']['de-de'] = "Nachricht"; +$text['label-message']['el-gr'] = "Μήνυμα"; +$text['label-message']['es-cl'] = "Mensaje"; +$text['label-message']['es-mx'] = "Mensaje"; +$text['label-message']['fr-ca'] = "Message"; +$text['label-message']['fr-fr'] = "Message"; +$text['label-message']['he-il'] = "הוֹדָעָה"; +$text['label-message']['it-it'] = "Messaggio"; +$text['label-message']['nl-nl'] = "Bericht"; +$text['label-message']['pl-pl'] = "Wiadomość"; +$text['label-message']['pt-br'] = "Mensagem"; +$text['label-message']['pt-pt'] = "Mensagem"; +$text['label-message']['ro-ro'] = "Mesaj"; +$text['label-message']['ru-ru'] = "Сообщение"; +$text['label-message']['sv-se'] = "Meddelande"; +$text['label-message']['uk-ua'] = "повідомлення"; +$text['label-message']['tr-tr'] = "İleti"; +$text['label-message']['zh-cn'] = "信息"; +$text['label-message']['ja-jp'] = "メッセージ"; +$text['label-message']['ko-kr'] = "메시지"; + +$text['message-emails_resent']['en-us'] = "Emails Resent"; +$text['message-emails_resent']['en-gb'] = "Emails Resent"; +$text['message-emails_resent']['ar-eg'] = "إعادة إرسال رسائل البريد الإلكتروني"; +$text['message-emails_resent']['de-at'] = "Erneut gesendete E-Mails"; +$text['message-emails_resent']['de-ch'] = "Erneut gesendete E-Mails"; +$text['message-emails_resent']['de-de'] = "Erneut gesendete E-Mails"; +$text['message-emails_resent']['el-gr'] = "Emails Resent"; +$text['message-emails_resent']['es-cl'] = "Correos electrónicos reenviados"; +$text['message-emails_resent']['es-mx'] = "Correos electrónicos reenviados"; +$text['message-emails_resent']['fr-ca'] = "E-mails renvoyés"; +$text['message-emails_resent']['fr-fr'] = "E-mails renvoyés"; +$text['message-emails_resent']['he-il'] = "מיילים נשלחו מחדש"; +$text['message-emails_resent']['it-it'] = "Email reinviate"; +$text['message-emails_resent']['nl-nl'] = "E-mails opnieuw verzonden"; +$text['message-emails_resent']['pl-pl'] = "E-maile wysłane ponownie"; +$text['message-emails_resent']['pt-br'] = "E-mails reenviados"; +$text['message-emails_resent']['pt-pt'] = "E-mails reenviados"; +$text['message-emails_resent']['ro-ro'] = "E-mailuri retransmise"; +$text['message-emails_resent']['ru-ru'] = "Письма повторно отправлены"; +$text['message-emails_resent']['sv-se'] = "E-postmeddelanden har skickats på nytt"; +$text['message-emails_resent']['uk-ua'] = "Листи повторно надіслано"; +$text['message-emails_resent']['tr-tr'] = "E-postalar Yeniden Gönderildi"; +$text['message-emails_resent']['zh-cn'] = "电子邮件已重新发送"; +$text['message-emails_resent']['ja-jp'] = "再送信メール"; +$text['message-emails_resent']['ko-kr'] = "이메일 재전송"; + +?> \ No newline at end of file diff --git a/app/voicemails/resources/classes/voicemail.php b/app/voicemails/resources/classes/voicemail.php index 53d64d0edb..ae987df7a4 100644 --- a/app/voicemails/resources/classes/voicemail.php +++ b/app/voicemails/resources/classes/voicemail.php @@ -321,7 +321,8 @@ $row['message_length_label'] = ($message_minutes > 0 ? $message_minutes.' min' : null).($message_seconds > 0 ? ' '.$message_seconds.' s' : null); $row['created_date'] = date("j M Y g:i a",$row['created_epoch']); } - } else { + } + else { $result = []; } return $result; @@ -669,6 +670,9 @@ //delete the recording $file_path = $_SESSION['switch']['voicemail']['dir']."/default/".$_SESSION['domain_name']."/".$this->voicemail_id; if (is_uuid($this->voicemail_message_uuid)) { + foreach (glob($file_path."/intro_msg_".$this->voicemail_message_uuid.".*") as $file_name) { + unlink($file_name); + } foreach (glob($file_path."/intro_".$this->voicemail_message_uuid.".*") as $file_name) { unlink($file_name); } @@ -869,6 +873,30 @@ $voicemail_message_file_mime = mime_content_type($voicemail_message_path.'/msg_'.$message['voicemail_message_uuid'].'.'.$voicemail_message_file_ext); } + //determine voicemail intro file path + if ( + !empty($message['message_intro_base64']) && + !file_exists($voicemail_message_path.'/intro_'.$message['voicemail_message_uuid'].'.wav') && + !file_exists($voicemail_message_path.'/intro_'.$message['voicemail_message_uuid'].'.mp3') + ) { + $voicemail_intro_decoded = base64_decode($message['message_intro_base64']); + file_put_contents($voicemail_message_path.'/intro_'.$message['voicemail_message_uuid'].'.'.$voicemail_message_file_ext, $voicemail_intro_decoded); + $voicemail_intro_file = 'intro_'.$message['voicemail_message_uuid'].'.'.$voicemail_message_file_ext; + } + else { + $voicemail_intro_file = 'intro_'.$message['voicemail_message_uuid'].'.'.$voicemail_message_file_ext; + } + + //combine voicemail intro and message files + $sox = system('which sox'); + if (file_exists($voicemail_message_path.'/'.$voicemail_intro_file) && !empty($sox)) { + $voicemail_combined_file = 'intro_msg_'.$message['voicemail_message_uuid'].'.'.$voicemail_message_file_ext; + exec($sox.' '.$voicemail_message_path.'/'.$voicemail_intro_file.' '.$voicemail_message_path.'/'.$voicemail_message_file.' '.$voicemail_message_path.'/'.$voicemail_combined_file); + if (file_exists($voicemail_message_path.'/'.$voicemail_combined_file)) { + $message['message_combined_base64'] = base64_encode(file_get_contents($voicemail_message_path.'/'.$voicemail_combined_file)); + } + } + //replace body variables if (!empty($template['template_body'])) { $template['template_body'] = str_replace('${caller_id_name}', $message['caller_id_name'], $template['template_body']); @@ -884,7 +912,7 @@ $template['template_body'] = str_replace('${sip_to_user}', $message['voicemail_id'], $template['template_body']); $template['template_body'] = str_replace('${dialed_user}', $message['voicemail_id'], $template['template_body']); if (!empty($message['voicemail_file'])) { - if ($message['voicemail_file'] == 'attach' && file_exists($voicemail_message_path.'/'.$voicemail_message_file)) { + if ($message['voicemail_file'] == 'attach' && (file_exists($voicemail_message_path.'/'.$voicemail_combined_file) || file_exists($voicemail_message_path.'/'.$voicemail_message_file))) { $template['template_body'] = str_replace('${message}', $text['label-attached'], $template['template_body']); } else if ($message['voicemail_file'] == 'link') { @@ -903,7 +931,7 @@ $template['template_body'] .= $message['caller_id_number']."
\n"; $template['template_body'] .= $message['message_date']."
\n"; if (!empty($message['voicemail_file'])) { - if ($message['voicemail_file'] == 'attach' && file_exists($voicemail_message_path.'/'.$voicemail_message_file)) { + if ($message['voicemail_file'] == 'attach' && (file_exists($voicemail_message_path.'/'.$voicemail_combined_file) || file_exists($voicemail_message_path.'/'.$voicemail_message_file))) { $template['template_body'] .= "
\n".$text['label-attached']; } else if ($message['voicemail_file'] == 'link') { @@ -932,15 +960,15 @@ $array['email_queue'][0]['insert_user'] = $this->user_uuid; //add voicemail file details (and/or base64) to queue attachments - if (!empty($message['voicemail_file']) && $message['voicemail_file'] == 'attach' && file_exists($voicemail_message_path.'/'.$voicemail_message_file)) { + if (!empty($message['voicemail_file']) && $message['voicemail_file'] == 'attach' && (file_exists($voicemail_message_path.'/'.$voicemail_combined_file) || file_exists($voicemail_message_path.'/'.$voicemail_message_file))) { $array['email_queue_attachments'][0]['email_queue_attachment_uuid'] = uuid(); $array['email_queue_attachments'][0]['domain_uuid'] = $this->domain_uuid; $array['email_queue_attachments'][0]['email_queue_uuid'] = $email_queue_uuid; $array['email_queue_attachments'][0]['email_attachment_type'] = $voicemail_message_file_ext; $array['email_queue_attachments'][0]['email_attachment_path'] = $voicemail_message_path; - $array['email_queue_attachments'][0]['email_attachment_name'] = $voicemail_message_file; - $array['email_queue_attachments'][0]['email_attachment_base64'] = $message['message_base64']; - $array['email_queue_attachments'][0]['email_attachment_cid'] = !empty($message['message_base64']) ? uuid() : null; + $array['email_queue_attachments'][0]['email_attachment_name'] = $voicemail_combined_file ?? $voicemail_message_file; + $array['email_queue_attachments'][0]['email_attachment_base64'] = $message['message_combined_base64'] ?? $message['message_base64']; + $array['email_queue_attachments'][0]['email_attachment_cid'] = !empty($message['message_combined_base64']) || !empty($message['message_base64']) ? uuid() : null; $array['email_queue_attachments'][0]['email_attachment_mime_type'] = $voicemail_message_file_mime; $array['email_queue_attachments'][0]['insert_date'] = 'now()'; $array['email_queue_attachments'][0]['insert_user'] = $this->user_uuid; @@ -964,6 +992,8 @@ //remove temp file from base64 output if (!empty($message['message_base64']) && file_exists($voicemail_message_path.'/'.$voicemail_message_file)) { @unlink($voicemail_message_path.'/'.$voicemail_message_file); + @unlink($voicemail_message_path.'/'.$voicemail_intro_file); + @unlink($voicemail_message_path.'/'.$voicemail_combined_file); } } @@ -1106,6 +1136,127 @@ $this->message_waiting(); } + /** + * download the voicemail message intro + * @param string domain_name if domain name is not passed, then will be used from the session variable (if available) to generate the voicemail file path + */ + public function message_intro_download(string $domain_name = '') { + + //check domain name + if (empty($domain_name)) { + $domain_name = $_SESSION['domain_name'] ?? ''; + } + + //check if for valid input + if (!is_numeric($this->voicemail_id) + || !is_uuid($this->voicemail_uuid) + || !is_uuid($this->domain_uuid) + || !is_uuid($this->voicemail_message_uuid) + ) { + return false; + } + + //change the message status + $this->message_saved(); + + //set source folder path + $path = realpath($this->settings->get('switch','voicemail','/var/lib/freeswitch/storage/voicemail').'/default/'.$domain_name).'/'.$this->voicemail_id; + + //prepare base64 content from db, if enabled + if ($this->settings->get('voicemail','storage_type','') == 'base64') { + $sql = "select message_intro_base64 "; + $sql .= "from "; + $sql .= "v_voicemail_messages as m, "; + $sql .= "v_voicemails as v "; + $sql .= "where "; + $sql .= "m.voicemail_uuid = v.voicemail_uuid "; + $sql .= "and v.voicemail_id = :voicemail_id "; + $sql .= "and m.voicemail_uuid = :voicemail_uuid "; + $sql .= "and m.domain_uuid = :domain_uuid "; + $sql .= "and m.voicemail_message_uuid = :voicemail_message_uuid "; + $parameters['voicemail_id'] = $this->voicemail_id; + $parameters['voicemail_uuid'] = $this->voicemail_uuid; + $parameters['domain_uuid'] = $this->domain_uuid; + $parameters['voicemail_message_uuid'] = $this->voicemail_message_uuid; + $message_intro_base64 = $this->database->select($sql, $parameters, 'column'); + if ($message_intro_base64 != '') { + $message_intro_decoded = base64_decode($message_intro_base64); + file_put_contents($path.'/intro_'.$this->voicemail_message_uuid.'.ext', $message_intro_decoded); + $finfo = finfo_open(FILEINFO_MIME_TYPE); //determine mime type (requires PHP >= 5.3.0, must be manually enabled on Windows) + $file_mime = finfo_file($finfo, $path.'/intro_'.$this->voicemail_message_uuid.'.ext'); + finfo_close($finfo); + switch ($file_mime) { + case 'audio/x-wav': + case 'audio/wav': + $file_ext = 'wav'; + break; + case 'audio/mpeg': + case 'audio/mp3': + $file_ext = 'mp3'; + break; + } + rename($path.'/intro_'.$this->voicemail_message_uuid.'.ext', $path.'/intro_'.$this->voicemail_message_uuid.'.'.$file_ext); + } + unset($sql, $parameters, $message_intro_base64, $message_intro_decoded); + } + + //prepare and stream the file + if (file_exists($path.'/intro_'.$this->voicemail_message_uuid.'.wav')) { + $file_path = $path.'/intro_'.$this->voicemail_message_uuid.'.wav'; + } + else if (file_exists($path.'/intro_'.$this->voicemail_message_uuid.'.mp3')) { + $file_path = $path.'/intro_'.$this->voicemail_message_uuid.'.mp3'; + } + else { + return false; + } + + if (empty($file_path)) { + return false; + } + + $fd = fopen($file_path, "rb"); + if ($this->type == 'bin') { + header("Content-Type: application/force-download"); + header("Content-Type: application/octet-stream"); + header("Content-Type: application/download"); + header("Content-Description: File Transfer"); + $file_ext = pathinfo($file_path, PATHINFO_EXTENSION); + switch ($file_ext) { + case "wav": header('Content-Disposition: attachment; filename="intro_'.$this->voicemail_message_uuid.'.wav"'); break; + case "mp3": header('Content-Disposition: attachment; filename="intro_'.$this->voicemail_message_uuid.'.mp3"'); break; + case "ogg": header('Content-Disposition: attachment; filename="intro_'.$this->voicemail_message_uuid.'.ogg"'); break; + } + } + else { + $file_ext = pathinfo($file_path, PATHINFO_EXTENSION); + switch ($file_ext) { + case "wav": header("Content-Type: audio/x-wav"); break; + case "mp3": header("Content-Type: audio/mpeg"); break; + case "ogg": header("Content-Type: audio/ogg"); break; + } + } + header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 + header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // date in the past + if ($this->type == 'bin') { + header("Content-Length: ".filesize($file_path)); + } + ob_end_clean(); + + //content-range + if (isset($_SERVER['HTTP_RANGE']) && $this->type != 'bin') { + $this->range_download($file_path); + } + + fpassthru($fd); + + //if base64, remove temp file + if ($this->settings->get('voicemail','storage_type','') == 'base64') { + @unlink($path.'/intro_'.$this->voicemail_message_uuid.'.'.$file_ext); + } + + } + /** * download the voicemail message * @param string domain_name if domain name is not passed, then will be used from the session variable (if available) to generate the voicemail file path @@ -1384,7 +1535,9 @@ //get all wav and mp3 voicemail files $mp3_files = glob("$voicemail_location/$domain_name/*/msg_*.mp3"); $wav_files = glob("$voicemail_location/$domain_name/*/msg_*.wav"); - $domain_voicemail_files = array_merge($mp3_files, $wav_files); + $mp3_intro_files = glob("$voicemail_location/$domain_name/*/intro_*.mp3"); + $wav_intro_files = glob("$voicemail_location/$domain_name/*/intro_*.wav"); + $domain_voicemail_files = array_merge($mp3_files, $wav_files, $mp3_intro_files, $wav_intro_files); //delete individually foreach ($domain_voicemail_files as $file) { diff --git a/app/voicemails/voicemail_messages.php b/app/voicemails/voicemail_messages.php index 3072de60b1..18b420b2be 100644 --- a/app/voicemails/voicemail_messages.php +++ b/app/voicemails/voicemail_messages.php @@ -66,8 +66,15 @@ $voicemail->voicemail_id = $_REQUEST['id']; $voicemail->voicemail_uuid = $_REQUEST['voicemail_uuid']; $voicemail->voicemail_message_uuid = $_REQUEST['uuid']; - if (!$voicemail->message_download($domain_name)) { - echo "unable to download voicemail"; + if (isset($_REQUEST['intro'])) { + if (!$voicemail->message_intro_download($domain_name)) { + echo "unable to download voicemail intro"; + } + } + else { + if (!$voicemail->message_download($domain_name)) { + echo "unable to download voicemail"; + } } unset($voicemail); exit; @@ -107,6 +114,10 @@ $voicemail_messages = $_POST['voicemail_messages']; } +//add multi-lingual support + $language = new text; + $text = $language->get(); + //process the http post data by action if (!empty($action) && !empty($voicemail_messages)) { @@ -203,7 +214,7 @@ } //set message if ($messages_resent != 0) { - message::add($text['message-toggle'].': '.$messages_resent); + message::add($text['message-emails_resent'].': '.$messages_resent); } } break; @@ -243,10 +254,6 @@ exit; } -//add multi-lingual support - $language = new text; - $text = $language->get(); - //get the html values and set them as variables $order_by = $_GET["order_by"] ?? ''; $order = $_GET["order"] ?? ''; @@ -440,7 +447,15 @@ echo " ".escape($row['caller_id_number'])." \n"; echo " "; echo ""; - echo button::create(['type'=>'button','title'=>$text['label-play'].' / '.$text['label-pause'],'icon'=>$_SESSION['theme']['button_icon_play'],'id'=>'recording_button_'.escape($row['voicemail_message_uuid']),'onclick'=>"recording_play('".escape($row['voicemail_message_uuid'])."','".$row['voicemail_id'].'|'.$row['voicemail_uuid']."','message');"]); + if ( + ($_SESSION['voicemail']['storage_type']['text'] == 'base64' && !empty($row['message_intro_base64'])) || + file_exists($_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domain_name'].'/'.$field['voicemail_id'].'/intro_'.$row['voicemail_message_uuid'].'.wav') || + file_exists($_SESSION['switch']['voicemail']['dir'].'/default/'.$_SESSION['domain_name'].'/'.$field['voicemail_id'].'/intro_'.$row['voicemail_message_uuid'].'.mp3') + ) { + echo ""; + echo button::create(['type'=>'button','title'=>$text['label-play'].' / '.$text['label-pause'].' '.$text['label-introduction'],'icon'=>$_SESSION['theme']['button_icon_comment'],'id'=>'recording_button_intro_'.escape($row['voicemail_message_uuid']),'onclick'=>"recording_play('intro_".escape($row['voicemail_message_uuid'])."','".$row['voicemail_id'].'|'.$row['voicemail_uuid']."','message_intro');"]); + } + echo button::create(['type'=>'button','title'=>$text['label-play'].' / '.$text['label-pause'].' '.$text['label-message'],'icon'=>$_SESSION['theme']['button_icon_play'],'id'=>'recording_button_'.escape($row['voicemail_message_uuid']),'onclick'=>"recording_play('".escape($row['voicemail_message_uuid'])."','".$row['voicemail_id'].'|'.$row['voicemail_uuid']."','message');"]); echo button::create(['type'=>'button','title'=>$text['label-download'],'icon'=>$_SESSION['theme']['button_icon_download'],'link'=>"voicemail_messages.php?action=download&id=".urlencode($row['voicemail_id'])."&voicemail_uuid=".escape($row['voicemail_uuid'])."&uuid=".escape($row['voicemail_message_uuid'])."&t=bin&r=".uuid(),'onclick'=>"$(this).closest('tr').children('td').css('font-weight','normal');"]); if ( (!empty($_SESSION['voicemail']['transcribe_enabled']['boolean']) && $_SESSION['voicemail']['transcribe_enabled']['boolean'] == 'true' && !empty($row['message_transcription'])) || @@ -521,4 +536,4 @@ //include the footer require_once "resources/footer.php"; -?> +?> \ No newline at end of file diff --git a/themes/default/app_config.php b/themes/default/app_config.php index 66ecddd068..9d24cbe2fc 100644 --- a/themes/default/app_config.php +++ b/themes/default/app_config.php @@ -2407,6 +2407,14 @@ $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true"; $apps[$x]['default_settings'][$y]['default_setting_description'] = "information icon"; $y++; + $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "d53be7ff-f44a-42e8-93f7-bae334539e95"; + $apps[$x]['default_settings'][$y]['default_setting_category'] = "theme"; + $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "button_icon_comment"; + $apps[$x]['default_settings'][$y]['default_setting_name'] = "text"; + $apps[$x]['default_settings'][$y]['default_setting_value'] = "fas fa-comment-dots"; + $apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true"; + $apps[$x]['default_settings'][$y]['default_setting_description'] = "comment icon"; + $y++; $apps[$x]['default_settings'][$y]['default_setting_uuid'] = "814ed631-a315-4bde-a822-4038432ae2a6"; $apps[$x]['default_settings'][$y]['default_setting_category'] = "theme"; $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "keyboard_shortcut_check_all_enabled"; diff --git a/themes/default/template.php b/themes/default/template.php index bf7bf5cf83..39943d4bda 100644 --- a/themes/default/template.php +++ b/themes/default/template.php @@ -777,6 +777,7 @@ audio_clock = setInterval(function () { update_progress(player_id); }, 20); $('[id*=recording_button]').not('[id*=recording_button_' + player_id + ']').html(""); + $('[id*=recording_button_intro]').not('[id*=recording_button_' + player_id + ']').html(""); $('[id*=recording_progress_bar]').not('[id*=recording_progress_bar_' + player_id + ']').css('display', 'none'); $('audio').each(function(){ @@ -789,7 +790,12 @@ else { recording_audio.pause(); recording_id_playing = ''; - document.getElementById('recording_button_' + player_id).innerHTML = ""; + if (player_id.substring(0,6) == 'intro_') { + document.getElementById('recording_button_' + player_id).innerHTML = ""; + } + else { + document.getElementById('recording_button_' + player_id).innerHTML = ""; + } clearInterval(audio_clock); } } @@ -806,7 +812,12 @@ if (document.getElementById('recording_progress_bar_' + player_id)) { document.getElementById('recording_progress_bar_' + player_id).style.display='none'; } - document.getElementById('recording_button_' + player_id).innerHTML = ""; + if (player_id.substring(0,6) == 'intro_') { + document.getElementById('recording_button_' + player_id).innerHTML = ""; + } + else { + document.getElementById('recording_button_' + player_id).innerHTML = ""; + } clearInterval(audio_clock); }