Bonjour à tous,

Depuis plusieurs mois années (la vache, le temps passe super vite), nous utilisons un serveur de téléphonie basé sur Asterisk. Il s’agissait à l’origine de XiVO, qui depuis a forké pour devenir Wazo. Ce dernier est toujours géré par sa super équipe de développeurs habituelle basée au Québec. XiVO existe toujours mais ne correspond pas à nos attentes sur différents plans, mais ce n’est pas le sujet.

Au départ nous n’avions qu’un seul numéro provenant d’une ligne SIP Free, qu’il suffit d’activer depuis son espace abonné Freebox. Pour joindre différents postes, nous avons très vite été obligés de mettre en place un IVR, ou SVI. Plus clairement, il s’agit de ce qu’on appelle un Serveur Vocal Interactif, Interactive Voice Response.

L’objectif est d’expliquer à Asterisk, le moteur de téléphonie, ce qu’il va devoir faire dans tel ou tel cas. Pour cela, on lui expliquera tout cela avec une syntaxe bien spécifique. Je mets un peu les briques dans le désordre. Je ne vais pas expliquer spécialement les principes de base mais plutôt vous montrer comment j’ai réalisé ce que je souhaitais obtenir afin que vous puissiez vous en inspirer, voire améliorer ce que j’ai fait (qui contient probablement des erreurs dues à mon manque de pratique dans le domaine).

Pour l’occasion, je vous partage mon serveur vocal, un peu modifié pour le rendre plus digeste et surtout retirer les lignes inutiles. La logique de ce serveur vocal est simple, nous souhaitons que les appelants puissent nous contacter mais aussi, qu’en cas de besoin, nous puissions accéder à des fonctions avancées qui doivent nous être réservées, il faut donc les protéger, et quoi de mieux qu’un code à taper sur le téléphone.

Déroulé du serveur vocal

Un utilisateur (interne ou externe) appelle le serveur vocal. On lui joue alors un fichier audio expliquant les choix qu’il peut faire, l’un de ces choix étant d’accéder au menu protégé. Lorsque l’utilisateur fait ce choix, on lui demande un mot de passe composé de chiffres. A chaque échec ou dépassement du temps imparti on joue à nouveau le message qui demande la saisie du mot de passe. Une fois le bon code saisi, l’utilisateur entend alors le menu qui était protégé.

Voici un schéma de fonctionnement:

Comment cela se traduit ?

On va avoir besoin de créer un fichier de configuration. Dans l’interface de Wazo, en mode IPBX, il suffit de cliquer sur Fichiers de configuration, puis cliquer sur le +, et enfin, nommer judicieusement le fichier.

J’ai choisi de réaliser ces actions en trois étapes dans le même fichier (j’ai séparé les étapes dans ce billet pour faciliter la lecture) :

  1. Menu principal auquel on accède par défaut et qui propose les choix accessibles à tous;
  2. Menu de verrouillage appelé par un des choix du menu principal, c’est ce menu qui va permettre la saisie du code;
  3. Menu protégé auquel on ne peut accéder qu’après saisie du bon code dans le menu de verrouillage.

Le menu principal

Ce menu va accueillir tous les appelants. Dans le cas d’une entreprise, on pourrait imaginer quelque chose comme :

Bienvenue chez Tartempion Entreprise and Co. Pour contacter Jeanine de la compta, faites le 1. Pour contacter Christian, responsable de la machine à café, faites le 2. Pour accéder au menu verrouillé, faites le 3.

Pour bien faire, je considère qu’on a besoin de trois fichiers audio:

  1. Le premier, à ne jouer qu’une fois: « Bienvenue chez Tartempion Entreprise and Co. » ;
  2. Le message d’annonce des choix possibles: « Pour contacter Jeanine de la compta, faites le 1. Pour contacter Christian, responsable de la machine à café, faites le 2. Pour accéder au menu verrouillé, faites le 3. » ;
  3. Un message d’erreur, par exemple: « Choix incorrect, veuillez rééssayer. »

On va alors coder le démarrage de notre serveur vocal. Je mets en caractère gras des commentaires (le point virgule est nécessaire pour qu’Asterisk prenne en compte que c’est un commentaire) :

[menu-principal]                    ; On déclare un contexte pour le SVI.
exten = s,1,Set(CHANNEL=fr_FR)      ; Réglage du Channel en Français.
exten = s,2,Answer                  ; Le serveur décroche.

; On joue le message d'accueil de façon préemptive, puis on joue le message
; d'annonce des choix en autorisant la saisie pendant la lecture de sorte
; que l'utilisateur puisse gagner du temps.
exten = s,3,Playback(/chemin/vers/message_accueil)
exten = s,4,Background(/chemin/vers/message_choix)
exten = s,5,WaitExten(10)          ;On attend pendant 10 secondes.

; A partir de là, il faut commencer à traiter les saisies. On va pour cela
; reprendre l'exemple décrit plus haut, avec Jeanine possédant l'extension
; 701, Christian le 702 et le menu verrouillé sur le 3.
exten = 1,1,Goto(default,701,1)     ;Le 1 pour appeler Jeanine au 701.
exten = 2,1,Goto(default,702,1)     ;Le 2 pour appeler Christian au 702.
exten = 3,1,Goto(menu-verrou,s,1)   ;Le 3 pour le menu de verrouillage.

; On va maintenant traiter les erreurs de saisie. On va commencer par jouer
; de façon préemptive le message d'erreur, puis recommencer l'exécution à
; partir d'une instruction particulière, en l'occurrence la lecture des 
; différents choix possibles sans le message d'accueil.
exten = i,1,Playback(/chemin/vers/message_erreur)
exten = i,2,Goto(s,4)

; On a placé plus haut une condition de temps. Lorsque le temps est écoulé
; il faut également décrire quoi faire. Comme pour une erreur de choix on
; va se contenter de revenir à la lecture des choix.
exten = t,1,Goto(s,4)

Ceci est un exemple. Il faudra évidemment l’adapter à votre utilisation, vos utilisateurs, groupes ou files d’attente. J’ai essayé de faire un exemple qui puisse quand même être représentatif d’un vrai cas d’utilisation.

Le menu de verrouillage

Le menu de verrouillage n’a qu’un seul objectif : être le point de passage obligatoire pour accéder au menu protégé. Là encore j’ai choisi de le faire simple mais en restant fonctionnel pour que vous puissiez tester facilement sur votre installation.

Dans cette exemple, on a besoin de deux fichiers audio :

  1. Le message pour demander le code: « Saisissez le code secret. » ;
  2. Le message d’erreur de saisie du code: « Le code secret est incorrect, veuillez rééssayer. »
; On va commencer de la même façon que pour le menu principal.
; On commence par déclarer notre nouveau contexte.
; Avez-vous par ailleurs remarqué qu'il se nomme comme comme indiqué
; dans l'instruction concernant le choix 3 du menu principal ?
; En effet, si dans le menu principal on tape 3, alors on demande à aller
; à la priorité '1' de l'extension 's' du contexte nommé 'menu-verrou'
; autrement dit le premier 'Playback' de 'menu-verrou'.
; On va donc commencer par lire le message demandant de taper le code.
; Ensuite on va attendre 10 secondes, vous commencez à comprendre.

[menu-verrou]                
exten = s,1,Playback(/chemin/vers/message_taper_code)
exten = s,2,WaitExten(10)

; Par GotoIf, comprenez 'Aller a telle instruction si [condition], sinon
; aller à telle autre instruction'. 
; On va ici recueillir une saisie utilisateur de 5 chiffres (le X étant
; un chiffre de n'importe quelle valeur) et on va la comparer à une
; valeur, ici '12345'. Ce qui se trouve après le '?' c'est l'action à
; accomplir sous la forme '?réussite:echec'. Ici, en cas de réussite on
; va aller à la première instruction du contexte 'menu-protege' et en cas
; d'échec à la priorité '3' du contexte dans lequel on est.
exten = _XXXXX,1,GotoIf($["${EXTEN}" = "12345"]?menu-protege,s,1:s,3)

; On joue le message indiquant l'erreur de saisie du code.
exten = s,3,Playback(/chemin/vers/erreur_code)

; Eventuellement, cette ligne permet aux appelants de retourner aux choix
; du menu principal. Dans le cas où on utiliserait cette ligne, il pourrait
; être intéressant d'ajouter un message parlé pour l'indiquer.
exten = *,1,Goto(menu-principal,s,4)

; Comme pour le contexte 'menu-principal', en cas d'erreur de saisie, on
; joue un message d'erreur et on revient à l'annonce demandant la saisie
; du mot de passe.
exten = i,1,Playback(/chemin/vers/erreur_code)
exten = i,2,Goto(s,1)

; Idem après le timeout.
exten = t,1,Goto(s,1)

Comme on peut le voir, ce menu est un peu plus compliqué. Il existe plusieurs façons de faire cela. De même, il existe des astuces pour alléger le code, mais ce n’est pas plus mal de tout détailler.

Le menu protégé

En gros, pour rester cohérent dans cet exemple, le menu protégé permet d’appeler le secrétariat et la direction, respectivement au 703 et 704. Il est formé de la même manière que le menu principal mais il délivre d’autre choix, tout simplement.

[menu-protege]
exten = s,4,Background(/chemin/vers/message_choix)
exten = s,5,WaitExten(10) ; On attend pendant 10 secondes.

; A partir de là, il faut commencer à traiter les saisies. On va pour cela
; reprendre l'exemple décrit plus haut, avec le secrétariat possédant
; l'extension 703, et le directeur le 704.
exten = 1,1,Goto(default,703,1) ; Le 1 pour appeler le secréatariat au 703.
exten = 2,1,Goto(default,704,1) ; Le 2 pour appeler directeur au 704.

; Comme pour le menu principal, en cas d'erreur ou de dépassement du délais,
; on revient au menu de départ.
exten = i,1,Playback(/chemin/vers/message_erreur)
exten = i,2,Goto(s,1)
exten = t,1,Goto(s,1)

La mise en place dans un fichier de configuration

Pour réaliser votre serveur vocal, il faut le stocker quelque part sur Wazo.

Comme évoqué plus haut, on va pour cela utiliser le fichier de configuration fraîchement créé les trois morceaux de dialplan les uns à la suite des autres.

Il faudra bien entendu adapter le chemin des fichiers audio, et les extensions.

On sauvegarde en cochant la case Recharger le dialplan, et c’est prêt.

Le dialplan d’Asterisk va se recharger complêtement et cette fois-ci en intégrant les différents contextes que l’on a créé.

Tester la configuration

C’est une étape importante. Si vous recevez un grand nombre d’appels, et surtout si vous êtes une entreprise, vous n’aurez pas envie de modifier votre serveur vocal en production ou modifier la destination de vos appels entrants.

Vous pouvez faire vos tests en interne, sans toucher vos appels entrants.

Toujours dans les fichiers de configurations, il en existe au moins un appelé xivo-extrafeatures.conf. Editez-le en ajoutant:

exten = 999,1,Goto(menu-principal,s,1)

Dans l’exemple ci-dessus, 999 représente le numéro qu’il faudra composer pour atteindre le serveur vocal. La partie entre parenthèses est modelée comme dans les modèles de diaplan plus haut sous la forme (contexte,extension,priorité). Par ailleurs, vous pouvez commencer votre test directement dans le menu de verrouillage ou dans le menu protégé en adaptant l’instruction Goto.

La mise en production

Lorsque vous êtes satisfait de votre SVI, alors mettez-le en production pour vos appels entrants. Dans la page Appels entrants, ajoutez ou modifiez comme suit:

Evidemment il faut avoir un trunk et un contexte entrant correctement configuré.

Renseignez votre SDA, le contexte entrant. Dans Destination, sélectionnez Personnalisée, ce qui fait apparaître le champ Commande.

Dans ce dernier, il suffit de former un Goto, comme dans le fichier de configuration.

Dans notre cas :

Goto(menu-principal,s,1)

Conclusion

On a vu dans ce billet la création et la mise en place d’un serveur vocal avec une fonction de verrouillage simple. C’est une fonctionnalité assez répandue. Ici elle est très simple mais il serait intéressant d’ajouter quelques détails, comme un message pour avertir que les appels sont enregistrés, ou des boucles permettant au serveur de mettre fin à un appel qui durerait trop longtemps, ou couper la possibilité d’accéder au menu protégé si on a effectué trop de tentatives, etc.