Feature: add Paging & Intercom groups (Téléavertissement) with auto-answer headers, Asterisk Page application, and interactive member selection

This commit is contained in:
sorcier committed 2026-11-02 17:01:02 +01:00
1 parent 33ad75d571
commit 2bd1ae0777
5 files changed
+610

No files matched your search

+72
View File
@@ -481,6 +481,7 @@ class ConfigGenerator
$sysLang = trim((string)($settings['system_language'] ?? 'fr')) ?: 'fr';
$extensions = $this->db->query('SELECT * FROM extensions WHERE enabled = 1 ORDER BY extension ASC')->fetchAll();
$groups = $this->db->query('SELECT * FROM groups ORDER BY extension ASC')->fetchAll();
$pagingGroups = $this->db->query('SELECT * FROM paging_groups WHERE enabled = 1 ORDER BY CAST(extension AS INTEGER) ASC')->fetchAll();
$extGroups = $this->db->query('SELECT * FROM extension_groups ORDER BY id ASC')->fetchAll();
$trunks = $this->db->query('SELECT * FROM trunks WHERE enabled = 1 ORDER BY id ASC')->fetchAll();
$ivrs = $this->db->query('SELECT * FROM ivrs ORDER BY name ASC')->fetchAll();
@@ -908,6 +909,60 @@ class ConfigGenerator
}
}
// Groupes de téléavertissement & Interphonie (Paging)
if (!empty($pagingGroups)) {
$lines[] = "; --- Groupes de téléavertissement & Interphonie (Paging) ---";
foreach ($pagingGroups as $pg) {
$pExt = trim((string)$pg['extension']);
$pName = str_replace('"', '', trim((string)$pg['name']));
$pDuplex = !empty($pg['duplex']);
$pBusyMode = trim((string)($pg['busy_mode'] ?? 'skip'));
$pBeep = !empty($pg['play_beep']);
$pTimeout = max(10, min(600, (int)($pg['timeout'] ?? 120)));
$members = json_decode((string)$pg['members'], true) ?: [];
$members = array_values(array_filter(array_map('trim', $members)));
$lines[] = "exten => {$pExt},1,NoOp(Teleavertissement Groupe {$pExt} - {$pName})";
$lines[] = " same => n,Set(CHANNEL(language)={$sysLang})";
$lines[] = " same => n,Answer()";
if ($pBeep) {
$lines[] = " same => n,Playback(beep)";
}
if (empty($members)) {
$lines[] = " same => n,Playback(beeperr)";
$lines[] = " same => n,Hangup()";
} else {
$devStr = implode('&', array_map(fn($m) => "PJSIP/{$m}", $members));
// Options Page():
// b(sub-paging-call^s^1) : configure les en-têtes SIP d'auto-réponse (Auto-Answer) sur chaque branche
// q : muet (pas de musique de fond confbridge)
// d : duplex (interphonie bidirectionnelle) si activé, sinon simplex (haut-parleur seul)
// s : skip channels if state != NOT_INUSE (évite d'interrompre un appel en cours si busy_mode = skip)
$pageOpts = "b(sub-paging-call^s^1)q";
if ($pDuplex) {
$pageOpts .= "d";
}
if ($pBusyMode === 'skip') {
$pageOpts .= "s";
}
$lines[] = " same => n,Set(PAGE_DEVICES={$devStr})";
$lines[] = " same => n,Page(\${PAGE_DEVICES},{$pageOpts},{$pTimeout})";
$lines[] = " same => n,Hangup()";
}
$lines[] = "";
}
// Interphonie directe 1-à-1 (*80 + numéro de poste)
$lines[] = "; --- Interphonie directe 1-à-1 (*80 + numéro de poste) ---";
$lines[] = "exten => _*80.,1,NoOp(Interphonie directe vers poste \${EXTEN:3})";
$lines[] = " same => n,Set(CHANNEL(language)={$sysLang})";
$lines[] = " same => n,Answer()";
$lines[] = " same => n,Playback(beep)";
$lines[] = " same => n,Page(PJSIP/\${EXTEN:3},b(sub-paging-call^s^1)qd,120)";
$lines[] = " same => n,Hangup()";
$lines[] = "";
}
// Accès direct aux IVR depuis l'interne via *8 + id
if (!empty($ivrs)) {
$lines[] = "; --- Test direct des SVI/IVR depuis l'interne ---";
@@ -1159,6 +1214,19 @@ class ConfigGenerator
$lines[] = " same => n,Hangup()";
$lines[] = "";
// 2a. Sous-routine d'interphonie / Auto-Answer Téléavertissement (Paging)
$lines[] = "; --- Sous-routine d'interphonie / Auto-Answer Téléavertissement ---";
$lines[] = "[sub-paging-call]";
$lines[] = "exten => s,1,NoOp(Preparation entetes SIP Auto-Answer pour Paging)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,Alert-Info)=info=alert-autoanswer\\;delay=0)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,Alert-Info)=<http://www.notused.com>\\;info=alert-autoanswer\\;delay=0)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,Call-Info)=\\;answer-after=0)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,P-Auto-Answer)=normal)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,Answer-After)=0)";
$lines[] = " same => n,Set(PJSIP_HEADER(add,SIP-Auto-Answer)=true)";
$lines[] = " same => n,Return()";
$lines[] = "";
// 2a-bis. Contexte [app-scam-tarpit] (Pièges à Scammers : Musique d'attente en boucle & Fausse voix en boucle infinie)
$lines[] = "; --- Pièges à Scammers & Démarchage (Tarpit Anti-Spam) ---";
$lines[] = "[app-scam-tarpit]";
@@ -1908,6 +1976,10 @@ class ConfigGenerator
if (preg_match('/^\d+$/', $dest)) {
return "Goto(from-internal,{$dest},1)";
}
if (str_starts_with($dest, 'page-')) {
$pageExt = substr($dest, 5);
return "Goto(from-internal,{$pageExt},1)";
}
if (str_starts_with($dest, 'ext-')) {
$ext = substr($dest, 4);
return "Goto(from-internal,{$ext},1)";