From 8f4ea50452f41c5842919360ae593512b4468584 Mon Sep 17 00:00:00 2001 From: sorcier Date: Wed, 4 Nov 2026 11:51:21 +0100 Subject: [PATCH] fix(ivr): resolve dialplan conflict on *801-*899 and link debian sound prompts (v1.4.8) --- install.sh | 12 ++++++++++-- public/api.php | 2 +- public/index.php | 2 +- scripts/fix.sh | 8 ++++++++ scripts/update.sh | 8 ++++++++ src/ConfigGenerator.php | 18 +++++++----------- src/SystemChecker.php | 15 +++++++++++++++ version.json | 10 +++++----- 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/install.sh b/install.sh index 675be57..a76c159 100755 --- a/install.sh +++ b/install.sh @@ -88,8 +88,8 @@ if ! apt-get install -y asterisk; then apt-get install -y -t sid asterisk fi -# Sons Asterisk en français (exacts de la machine de dev) -apt-get install -y asterisk-core-sounds-fr asterisk-core-sounds-fr-wav asterisk-core-sounds-fr-gsm 2>/dev/null || true +# Sons Asterisk en français et anglais +apt-get install -y asterisk-core-sounds-fr asterisk-core-sounds-fr-wav asterisk-core-sounds-fr-gsm asterisk-core-sounds-en asterisk-core-sounds-en-gsm 2>/dev/null || true # Nginx, PHP-FPM et extensions requises apt-get install -y --no-install-recommends \ @@ -325,6 +325,14 @@ if ! grep -q 'voicemail.custom.conf' /etc/asterisk/voicemail.conf 2>/dev/null; t fi mkdir -p /var/spool/asterisk/voicemail/default /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh +for lang in fr en es; do + if [ -d "/usr/share/asterisk/sounds/$lang" ] && [ ! -e "/var/lib/asterisk/sounds/$lang" ]; then + ln -sf "/usr/share/asterisk/sounds/$lang" "/var/lib/asterisk/sounds/$lang" + fi +done +if [ ! -e "/usr/share/asterisk/sounds/custom" ]; then + ln -sf /var/lib/asterisk/sounds/custom /usr/share/asterisk/sounds/custom 2>/dev/null || true +fi chown -R asterisk:asterisk /etc/asterisk /var/spool/asterisk /var/lib/asterisk chmod 0664 /etc/asterisk/*.conf /etc/asterisk/*.custom.conf 2>/dev/null || true chmod 2750 /etc/asterisk/keys diff --git a/public/api.php b/public/api.php index b51e03d..a57905e 100644 --- a/public/api.php +++ b/public/api.php @@ -140,7 +140,7 @@ try { $installedVerData = file_exists("{$appDir}/version.json") ? json_decode((string)file_get_contents("{$appDir}/version.json"), true) : []; - $installedVer = $installedVerData['version'] ?? '1.4.7'; + $installedVer = $installedVerData['version'] ?? '1.4.8'; echo json_encode([ 'success' => true, diff --git a/public/index.php b/public/index.php index f878e3f..4f02386 100644 --- a/public/index.php +++ b/public/index.php @@ -18,7 +18,7 @@ $companyLogo = trim($branding['company_logo'] ?? ''); $hasBranding = !empty($companyName) || !empty($companyLogo); $appVerData = file_exists(__DIR__ . '/../version.json') ? json_decode((string)file_get_contents(__DIR__ . '/../version.json'), true) : []; -$appVersion = $appVerData['version'] ?? '1.4.7'; +$appVersion = $appVerData['version'] ?? '1.4.8'; ?> diff --git a/scripts/fix.sh b/scripts/fix.sh index 08a2799..5dfbc80 100755 --- a/scripts/fix.sh +++ b/scripts/fix.sh @@ -103,6 +103,14 @@ if ! grep -q 'voicemail.custom.conf' /etc/asterisk/voicemail.conf 2>/dev/null; t fi mkdir -p /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh /var/spool/asterisk/voicemail/default 2>/dev/null || true +for lang in fr en es; do + if [ -d "/usr/share/asterisk/sounds/$lang" ] && [ ! -e "/var/lib/asterisk/sounds/$lang" ]; then + ln -sf "/usr/share/asterisk/sounds/$lang" "/var/lib/asterisk/sounds/$lang" 2>/dev/null || true + fi +done +if [ ! -e "/usr/share/asterisk/sounds/custom" ]; then + ln -sf /var/lib/asterisk/sounds/custom /usr/share/asterisk/sounds/custom 2>/dev/null || true +fi chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/spool/asterisk /var/log/asterisk 2>/dev/null || true chmod -R 775 /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh /var/spool/asterisk 2>/dev/null || true chmod 2775 /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh /var/spool/asterisk /var/spool/asterisk/voicemail 2>/dev/null || true diff --git a/scripts/update.sh b/scripts/update.sh index 302df57..58f94ce 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -136,6 +136,14 @@ require_once "/var/www/nexus-pbx/src/SystemChecker.php"; App\SystemChecker::ensureAsteriskIncludes(); ' 2>/dev/null || true mkdir -p /var/spool/asterisk/voicemail/default /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh 2>/dev/null || true +for lang in fr en es; do + if [ -d "/usr/share/asterisk/sounds/$lang" ] && [ ! -e "/var/lib/asterisk/sounds/$lang" ]; then + ln -sf "/usr/share/asterisk/sounds/$lang" "/var/lib/asterisk/sounds/$lang" 2>/dev/null || true + fi +done +if [ ! -e "/usr/share/asterisk/sounds/custom" ]; then + ln -sf /var/lib/asterisk/sounds/custom /usr/share/asterisk/sounds/custom 2>/dev/null || true +fi chown -R asterisk:asterisk /var/spool/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh 2>/dev/null || true chmod 2775 /var/spool/asterisk /var/spool/asterisk/voicemail /var/lib/asterisk/sounds /var/lib/asterisk/moh 2>/dev/null || true setfacl -R -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh /var/spool/asterisk 2>/dev/null || true diff --git a/src/ConfigGenerator.php b/src/ConfigGenerator.php index 16dc99d..4c4b780 100644 --- a/src/ConfigGenerator.php +++ b/src/ConfigGenerator.php @@ -571,10 +571,6 @@ class ConfigGenerator $lines[] = " same => n,Hangup()"; } if ($groupCode !== '') { - $lines[] = "exten => _{$groupCode}.,1,NoOp(Interception d'appel dirigee vers \${EXTEN:" . strlen($groupCode) . "})"; - $lines[] = " same => n,Pickup(\${EXTEN:" . strlen($groupCode) . "}@from-internal)"; - $lines[] = " same => n,Hangup()"; - $lines[] = "exten => {$groupCode},1,NoOp(Interception d'appel de groupe)"; $lines[] = " same => n,Pickup()"; $lines[] = " same => n,Hangup()"; @@ -986,9 +982,10 @@ class ConfigGenerator $lines[] = ""; } - // Interphonie directe 1-à-1 (*80 + numéro de poste) + // Interphonie directe 1-à-1 (*80 + numéro de poste, ex: *80101 pour le poste 101) + // Pattern _*80XX. pour ne cibler que les numéros de postes (au moins 2 chiffres) et ne pas chevaucher *801 $lines[] = "; --- Interphonie directe 1-à-1 (*80 + numéro de poste) ---"; - $lines[] = "exten => _*80.,1,NoOp(Interphonie directe vers poste \${EXTEN:3})"; + $lines[] = "exten => _*80XX.,1,NoOp(Interphonie directe vers poste \${EXTEN:3})"; $lines[] = " same => n,Set(CHANNEL(language)={$sysLang})"; $lines[] = " same => n,Answer()"; $lines[] = " same => n,Playback(beep)"; @@ -997,13 +994,14 @@ class ConfigGenerator $lines[] = ""; } - // Accès direct aux IVR depuis l'interne via *8 + id + // Accès direct aux IVR depuis l'interne via *8 + id (*801, *802...) if (!empty($ivrs)) { - $lines[] = "; --- Test direct des SVI/IVR depuis l'interne ---"; + $lines[] = "; --- Test direct des SVI/IVR depuis l'interne (*801, *802...) ---"; foreach ($ivrs as $ivr) { $ivrSlug = $this->slugify($ivr['name']); $testCode = '*8' . str_pad((string)$ivr['id'], 2, '0', STR_PAD_LEFT); $lines[] = "exten => {$testCode},1,NoOp(Test SVI {$ivr['name']})"; + $lines[] = " same => n,Set(CHANNEL(language)={$sysLang})"; $lines[] = " same => n,Goto(ivr-{$ivrSlug},s,1)"; } $lines[] = ""; @@ -1500,6 +1498,7 @@ class ConfigGenerator $lines[] = "; --- Serveur Vocal Interactif : {$ivr['name']} ---"; $lines[] = "[ivr-{$ivrSlug}]"; $lines[] = "exten => s,1,NoOp(SVI {$ivr['name']})"; + $lines[] = " same => n,Set(CHANNEL(language)={$sysLang})"; $lines[] = " same => n,Answer()"; $lines[] = " same => n,Wait(1)"; $lines[] = " same => n,Set(IVR_INVALID_COUNT=0)"; @@ -1600,9 +1599,6 @@ class ConfigGenerator return implode("\n", $lines) . "\n"; } - /** - * Sauvegarde les anciens fichiers et écrit atomiquement pjsip.custom.conf et extensions.custom.conf - * avec les droits Debian asterisk:asterisk (0660). /** * Génère les classes Musique d'attente (MOH) personnalisées par site/catégorie */ diff --git a/src/SystemChecker.php b/src/SystemChecker.php index f481749..7298a71 100644 --- a/src/SystemChecker.php +++ b/src/SystemChecker.php @@ -225,6 +225,21 @@ class SystemChecker @mkdir('/var/spool/asterisk/voicemail/default', 0775, true); + // Liens vers les répertoires de sons Debian (/usr/share/asterisk/sounds -> /var/lib/asterisk/sounds) + @mkdir('/var/lib/asterisk/sounds', 0775, true); + @mkdir('/var/lib/asterisk/sounds/custom', 0775, true); + @mkdir('/var/lib/asterisk/moh', 0775, true); + foreach (['fr', 'en', 'es'] as $lang) { + $src = "/usr/share/asterisk/sounds/{$lang}"; + $dst = "/var/lib/asterisk/sounds/{$lang}"; + if (is_dir($src) && !file_exists($dst)) { + @symlink($src, $dst); + } + } + if (!file_exists('/usr/share/asterisk/sounds/custom')) { + @symlink('/var/lib/asterisk/sounds/custom', '/usr/share/asterisk/sounds/custom'); + } + // Synchroniser manager.conf avec le mot de passe AMI de la base SQLite si nécessaire (ex: après restauration de backup) $mgrConf = '/etc/asterisk/manager.conf'; if (is_file($mgrConf) && is_writable($mgrConf)) { diff --git a/version.json b/version.json index 3d1e0ae..e8aa84a 100644 --- a/version.json +++ b/version.json @@ -1,12 +1,12 @@ { - "version": "1.4.7", + "version": "1.4.8", "codename": "Helios", "release_date": "2026-11-04", "min_php_version": "8.2", "changelog": [ - "Détection ultra-robuste de l'état des téléphones IP (support SIPS, statuts sans qualify et fallback infaillible AstDB)", - "Réinitialisation immédiate du compteur d'attaques contrées Fail2ban lors du vidage du journal de sécurité", - "Synchronisation automatique des identifiants AMI (/etc/asterisk/manager.conf) après restauration d'une sauvegarde", - "Correction et fiabilisation de la messagerie vocale (*97 / *98) sur toute installation fraîche Debian" + "Correction du routage des codes de test direct SVI/IVR (*801, *802...) et suppression des conflits de préfixe avec l'interphonie (*80) et l'interception de groupe (*8)", + "Restauration automatique des liens de médiathèque audio Debian (/usr/share/asterisk/sounds/fr -> /var/lib/asterisk/sounds) sur toute installation fraîche", + "Définition systématique de la langue française dans les contextes SVI (CHANNEL(language)=fr) pour une lecture parfaite des annonces système", + "Amélioration de la robustesse de l'interphonie 1-à-1 avec ciblage strict des postes" ] }