Aller au contenu

« Astreinte » : différence entre les versions

De INDYWiki
Anthony (discussion | contributions)
Anthony (discussion | contributions)
 
(23 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
== par le statut ==
Dans les réglages de l'extension qui accueille les appels :
#Réglages
#Transfert d'appels
#Choisir le statut de l'extension à activer pour enclencher le renvoi vers l'astreinte. Dans l'exemple '''Absent'''. Pas l'état '''Disponible''' évidemment.
#Dans "Transférer les appels externes à", choisir '''Numéro externe'''
#Saisir le numéro de l'astreinte
#Cocher '''Rebond'''
[[Fichier:2026-04-02 16h03 02.png]]
Limite / contrainte :
*si les astreintes tournent, avant chaque période d'astreinte, il faut faire ce cheminement pour que le bon numéro de mobile soit paramétré
*4 profils d'astreinte maximum
*Nécessite de manipuler l'application WEB
== Via script==
===Principe===
===Principe===
On paramètre le statut choisi pour l'astreinte en renvoi vers '''mon mobile'''. Un script viendra modifier le statut de l'extension cible ainsi que son numéro de contact mobile, prénom et nom. Ce script déclenchable par l'appel à un code court, paramétrable si on le souhaite sur une BLF.  
On paramètre le statut choisi pour l'astreinte en renvoi vers '''mon mobile'''. Un script viendra modifier le statut de l'extension cible ainsi que son numéro de contact mobile, prénom et nom. Ce script déclenchable par l'appel à un code court, paramétrable si on le souhaite sur une BLF.  
===Paramétrage du statut de l'extension vers '''mon mobile'''===
[[Fichier:2026-04-03 11h09 54.png|cadre|néant]]


===Déclaration du script===
===Déclaration du script===
[[Fichier:2026-04-02 17h11 35.png|vignette]]
[[Fichier:2026-04-02 17h11 35.png|vignette]]
Rendez-vous dans :
Rendez-vous dans :


Ligne 40 : Ligne 19 :




===Le script===
===Le script d'astreinte===


L'éxécution du script va modifier l'extension '''targetExtNum ''', il va le basculer sur le statut '''profileName ''', modifier son mobile de contact '''mobileElu ''', son nom et prénom.
L'éxécution du script va modifier l'extension '''targetExtNum ''', il va le basculer sur le statut '''profileName ''', modifier son mobile de contact '''mobileElu ''', son nom et prénom.
Ligne 46 : Ligne 25 :
Il faut donc seulement modifier les lignes surlignés dans le code ci-dessous :
Il faut donc seulement modifier les lignes surlignés dans le code ci-dessous :


<syntaxhighlight lang="csharp" line highlight="14-16,19-20">
<syntaxhighlight lang="csharp" line highlight="14-17">
using System;
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
Ligne 52 : Ligne 31 :
using CallFlow;
using CallFlow;
using System.Linq;
using System.Linq;
using System.Collections.Generic;


namespace dummy
namespace dummy
Ligne 58 : Ligne 36 :
     public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
     public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
     {
     {
        // ============================================================
        // CONFIGURATION — modifier uniquement ces lignes par script
        // ============================================================
        private const string TARGET_EXT  = "111";
        private const string MOBILE_EXT  = "0612345678";
        private const string PRENOM_EXT  = "Claude";
        private const string NOM_EXT      = "IA";
// ============================================================
       
private const string PROFILE_NAME = "Away";
     
         public override Task<bool> StartAsync()
         public override Task<bool> StartAsync()
         {
         {
            string targetExtNum = "100";
            string mobileElu = "0601020304";
            string profileName = "Away";
           
            // Nommage de l'astreinte
            string prenomElu = "ASTREINTE";
            string nomElu = "ELU";
             try
             try
             {
             {
                 IPhoneSystem ps = PhoneSystem.Root;
                 IPhoneSystem ps = PhoneSystem.Root;
                 Extension targetExt = ps.GetDNByNumber(targetExtNum) as Extension;
                 Extension ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);


                 if (targetExt != null)
                // 1. Nom / Prénom
                ext.FirstName = PRENOM_EXT;
                ext.LastName  = NOM_EXT;
 
                // 2. Numéro mobile
                ext.SetProperty("MOBILENUMBER", MOBILE_EXT);
 
                // 3. Trouver le profil Away
                FwdProfile targetProfile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        PROFILE_NAME, StringComparison.OrdinalIgnoreCase));
 
                 if (targetProfile != null)
                 {
                 {
                     // 1. Mise à jour du numéro de mobile
                     // AwayRoute, Internal, External sont read-only
                     targetExt.SetProperty("MOBILENUMBER", mobileElu);
                    // mais ce sont des références : on peut modifier
                    // leurs membres si ceux-ci sont accessibles en écriture
                     AwayRouting route = targetProfile.AwayRoute;


                     // 2. MISE À JOUR DU NOM
                     // Capturer les HoursDestination comme variables locales
                     targetExt.FirstName = prenomElu;
                    // (objets référence — la propriété est read-only,
                     targetExt.LastName = nomElu;
                    //  mais l'objet pointé est modifiable)
                     HoursDestination internalHours = route.Internal;
                     HoursDestination externalHours = route.External;


                     // 3. Changement du profil de statut
                     // Capturer AllHours (struct) → modifier → réassigner
                     var profile = targetExt.FwdProfiles.FirstOrDefault(p => p.Name.Equals(profileName, StringComparison.OrdinalIgnoreCase));
                     DestinationStruct destInternal = internalHours.AllHours;
                      
                    destInternal.To              = DestinationType.Boomerang;
                    if (profile != null)
                     destInternal.External        = MOBILE_EXT;
                     {
                     internalHours.AllHours        = destInternal;
                        targetExt.CurrentProfile = profile;
                    }


                     // 4. Sauvegarde globale
                     DestinationStruct destExternal = externalHours.AllHours;
                     targetExt.ResetCurrentProfileOverride();
                     destExternal.To              = DestinationType.Boomerang;
                     targetExt.Save();
                     destExternal.External        = MOBILE_EXT;
                    externalHours.AllHours        = destExternal;
                }


                     return Task.FromResult(true);
                // 4. Sauvegarder
                ext.Save();
 
                // 5. Recharger et basculer le profil
                ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                     return Task.FromResult(false);
 
                FwdProfile profile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        PROFILE_NAME, StringComparison.OrdinalIgnoreCase));
 
                if (profile != null)
                {
                    ext.CurrentProfile = profile;
                    ext.Save();
                 }
                 }
                return Task.FromResult(true);
             }
             }
             catch (Exception)
             catch (Exception)
             {
             {
                 // Erreur silencieuse
                 return Task.FromResult(false);
             }
             }
            return Task.FromResult(false);
         }
         }
     }
     }
Ligne 107 : Ligne 122 :
</syntaxhighlight>
</syntaxhighlight>


====Table de correspondance des profileName====
===Le script de retour à la normale===


{| class="wikitable"
<syntaxhighlight lang="csharp" line highlight="14-16">
|-
using System;
! Dans 3CX!! Dans le script
using System.Threading.Tasks;
|-
using TCX.Configuration;
| Disponible|| Available
using CallFlow;
|-
using System.Linq;
| Absent|| Away
 
|-
namespace dummy
| Ne pas déranger|| Out of office
{
|-
    public class ResetAstreinte : ScriptBase<ResetAstreinte>
| Custom 1|| Custom 1
    {
|-
        // ============================================================
| Custom 2|| Custom 2
        // CONFIGURATION — modifier uniquement ces lignes par script
|}
        // ============================================================
        private const string TARGET_EXT  = "111";
        private const string PRENOM_EXT  = "Accueil";
        private const string NOM_EXT      = "Mairie";
        // ============================================================
 
        public override Task<bool> StartAsync()
        {
            try
            {
                IPhoneSystem ps = PhoneSystem.Root;
                Extension ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);
 
                // 1. Remettre le nom générique
                ext.FirstName = PRENOM_EXT;
                ext.LastName  = NOM_EXT;
 
                // 2. Vider le numéro mobile
                ext.SetProperty("MOBILENUMBER", "");
 
                // 3. Résoudre le DN pour la messagerie vocale
                DN targetDN = ps.GetDNByNumber(TARGET_EXT);
 
                // 4. Remettre AwayRoute → messagerie vocale
                FwdProfile awayProfile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        "Away", StringComparison.OrdinalIgnoreCase));
 
                if (awayProfile != null)
                {
                    AwayRouting route = awayProfile.AwayRoute;
 
                    HoursDestination internalHours = route.Internal;
                    HoursDestination externalHours = route.External;


===Configuration concrète===
                    DestinationStruct destInternal = internalHours.AllHours;
                    destInternal.To              = DestinationType.VoiceMail;
                    destInternal.Internal        = targetDN;
                    destInternal.External        = "";
                    internalHours.AllHours        = destInternal;


Il faut choisir un statut autre que "Disponible" qui sera activé pour l'astreinte, "Custom 2" pour cet exemple
                    DestinationStruct destExternal = externalHours.AllHours;
                    destExternal.To              = DestinationType.VoiceMail;
                    destExternal.Internal        = targetDN;
                    destExternal.External        = "";
                    externalHours.AllHours        = destExternal;
                }


On a besoin de gérer deux astreintes. Le poste Accueil reçoit les appels en temps normal
                // 5. Sauvegarder
                ext.Save();


{| class="wikitable"
                // 6. Recharger et basculer vers Available
|+ Texte de la légende
                ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
|-
                if (ext == null)
|'''Marcel Patulacci''' || '''Jean-Michel Apeuprè'''|| '''Poste accueil ''' hors période d'astreinte
                    return Task.FromResult(false);
|-
| <syntaxhighlight lang="csharp" line highlight="3-5,8-9">
public override Task<bool> StartAsync()
        {
            string targetExtNum = "100";
            string mobileElu = "0699999999";
            string profileName = "Custom 2";  


            // Nommage de l'astreinte
                FwdProfile profile = ext.FwdProfiles
            string prenomElu = "Marcel";
                    .FirstOrDefault(p => p.Name.Equals(
            string nomElu = "Patulacci";  
                        "Available", StringComparison.OrdinalIgnoreCase));


            try
                if (profile != null)
</syntaxhighlight> || <syntaxhighlight lang="csharp" line highlight="3-5,8-9">
                {
public override Task<bool> StartAsync()
                    ext.CurrentProfile = profile;
        {
                    ext.Save();
            string targetExtNum = "100";  
                }
            string mobileElu = "0688888888";
            string profileName = "Custom 2";


             // Nommage de l'astreinte
                return Task.FromResult(true);
             string prenomElu = "Jean-Michel";  
            }
             string nomElu = "Apeuprè";
             catch (Exception)
             {
                return Task.FromResult(false);
             }
        }
    }
}
</syntaxhighlight>


            try
===Configuration concrète===
</syntaxhighlight>|| <syntaxhighlight lang="csharp" line highlight="3-5,8-9">
public override Task<bool> StartAsync()
        {
            string targetExtNum = "100";
            string mobileElu = "";
            string profileName = "Available";


            // Nommage de l'astreinte
On a besoin de gérer deux astreintes. Le poste Accueil reçoit les appels en temps normal
            string prenomElu = "Accueil";
            string nomElu = "";


            try
{| class="wikitable"
|+ Extraits de chaque script
|-
|'''Marcel Patulacci''' || '''Jean-Michel Apeuprè'''|| '''Poste accueil ''' hors période d'astreinte
|-
| <syntaxhighlight lang="csharp" line highlight="4-7">
public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
{
// modifier uniquement ces lignes :
private const string TARGET_EXT  = "111";
private const string MOBILE_EXT  = "0612345678";
private const string PRENOM_EXT  = "Marcel";
private const string NOM_EXT      = "Patulacci";
</syntaxhighlight> || <syntaxhighlight lang="csharp" line highlight="4-7">
public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
{
// Modifier uniquement ces lignes
private const string TARGET_EXT  = "111";
private const string MOBILE_EXT  = "0699999999";
private const string PRENOM_EXT  = "Jean-Michel";
private const string NOM_EXT      = "Apeuprè";
</syntaxhighlight>|| <syntaxhighlight lang="csharp" line highlight="4-6">
public class ResetAstreinte : ScriptBase<ResetAstreinte>
{
// Modifier uniquement ces lignes :
private const string TARGET_EXT  = "111";
private const string PRENOM_EXT  = "Accueil";
private const string NOM_EXT      = "Mairie";
</syntaxhighlight>
</syntaxhighlight>
|}
|}


Une fois les 3 scripts produits, passer à l'étape [[Astreinte#Déclaration_du_script|Déclaration du script]] qui va permettre d'affecter un code court à chaque script.
Exemple :
* *90 pour hors période d'astreinte
* *91 pour Jean-Michel
* *92 pour Marcel
On peut communiquer les codes aux personnes habilitées à gérer le système d'astreinte et aller jusqu'à paramétrer des BLF pour faciliter la vie d'une secrétaire par exemple.
{{Valide|v20}}
[[Catégorie:3CX]]
[[Catégorie:3CX]]

Dernière version du 27 mai 2026 à 15:56

Principe

On paramètre le statut choisi pour l'astreinte en renvoi vers mon mobile. Un script viendra modifier le statut de l'extension cible ainsi que son numéro de contact mobile, prénom et nom. Ce script déclenchable par l'appel à un code court, paramétrable si on le souhaite sur une BLF.

Déclaration du script

Rendez-vous dans :

Admin / Intégrations / Scripts d'appels / + Ajouter personnalisé
  1. Donner un nom au traitement de l'appel. Exemple : astreinte_weekend
  2. Créer un code de raccourci, ce qui permettra d'exécuter le script simplement en appelant ce code, et in fine par une BLF. Exemple : *99
  3. OK
  4. Coller dans le champ script le script paramétré ( voir section suivante )
  5. Sauvegarder
  6. Un message doit indiquer Compilation réussie !



Le script d'astreinte

L'éxécution du script va modifier l'extension targetExtNum , il va le basculer sur le statut profileName , modifier son mobile de contact mobileElu , son nom et prénom.

Il faut donc seulement modifier les lignes surlignés dans le code ci-dessous :

using System;
using System.Threading.Tasks;
using TCX.Configuration;
using CallFlow;
using System.Linq;

namespace dummy
{
    public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
    {
        // ============================================================
        // CONFIGURATION — modifier uniquement ces lignes par script
        // ============================================================
        private const string TARGET_EXT   = "111";
        private const string MOBILE_EXT   = "0612345678";
        private const string PRENOM_EXT   = "Claude";
        private const string NOM_EXT      = "IA";
		 // ============================================================
        
		private const string PROFILE_NAME = "Away";
       
        public override Task<bool> StartAsync()
        {
            try
            {
                IPhoneSystem ps = PhoneSystem.Root;
                Extension ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);

                // 1. Nom / Prénom
                ext.FirstName = PRENOM_EXT;
                ext.LastName  = NOM_EXT;

                // 2. Numéro mobile
                ext.SetProperty("MOBILENUMBER", MOBILE_EXT);

                // 3. Trouver le profil Away
                FwdProfile targetProfile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        PROFILE_NAME, StringComparison.OrdinalIgnoreCase));

                if (targetProfile != null)
                {
                    // AwayRoute, Internal, External sont read-only
                    // mais ce sont des références : on peut modifier
                    // leurs membres si ceux-ci sont accessibles en écriture
                    AwayRouting route = targetProfile.AwayRoute;

                    // Capturer les HoursDestination comme variables locales
                    // (objets référence — la propriété est read-only,
                    //  mais l'objet pointé est modifiable)
                    HoursDestination internalHours = route.Internal;
                    HoursDestination externalHours = route.External;

                    // Capturer AllHours (struct) → modifier → réassigner
                    DestinationStruct destInternal = internalHours.AllHours;
                    destInternal.To               = DestinationType.Boomerang;
                    destInternal.External         = MOBILE_EXT;
                    internalHours.AllHours        = destInternal;

                    DestinationStruct destExternal = externalHours.AllHours;
                    destExternal.To               = DestinationType.Boomerang;
                    destExternal.External         = MOBILE_EXT;
                    externalHours.AllHours        = destExternal;
                }

                // 4. Sauvegarder
                ext.Save();

                // 5. Recharger et basculer le profil
                ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);

                FwdProfile profile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        PROFILE_NAME, StringComparison.OrdinalIgnoreCase));

                if (profile != null)
                {
                    ext.CurrentProfile = profile;
                    ext.Save();
                }

                return Task.FromResult(true);
            }
            catch (Exception)
            {
                return Task.FromResult(false);
            }
        }
    }
}

Le script de retour à la normale

using System;
using System.Threading.Tasks;
using TCX.Configuration;
using CallFlow;
using System.Linq;

namespace dummy
{
    public class ResetAstreinte : ScriptBase<ResetAstreinte>
    {
        // ============================================================
        // CONFIGURATION — modifier uniquement ces lignes par script
        // ============================================================
        private const string TARGET_EXT   = "111";
        private const string PRENOM_EXT   = "Accueil";
        private const string NOM_EXT      = "Mairie";
        // ============================================================

        public override Task<bool> StartAsync()
        {
            try
            {
                IPhoneSystem ps = PhoneSystem.Root;
                Extension ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);

                // 1. Remettre le nom générique
                ext.FirstName = PRENOM_EXT;
                ext.LastName  = NOM_EXT;

                // 2. Vider le numéro mobile
                ext.SetProperty("MOBILENUMBER", "");

                // 3. Résoudre le DN pour la messagerie vocale
                DN targetDN = ps.GetDNByNumber(TARGET_EXT);

                // 4. Remettre AwayRoute → messagerie vocale
                FwdProfile awayProfile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        "Away", StringComparison.OrdinalIgnoreCase));

                if (awayProfile != null)
                {
                    AwayRouting route = awayProfile.AwayRoute;

                    HoursDestination internalHours = route.Internal;
                    HoursDestination externalHours = route.External;

                    DestinationStruct destInternal = internalHours.AllHours;
                    destInternal.To               = DestinationType.VoiceMail;
                    destInternal.Internal         = targetDN;
                    destInternal.External         = "";
                    internalHours.AllHours        = destInternal;

                    DestinationStruct destExternal = externalHours.AllHours;
                    destExternal.To               = DestinationType.VoiceMail;
                    destExternal.Internal         = targetDN;
                    destExternal.External         = "";
                    externalHours.AllHours        = destExternal;
                }

                // 5. Sauvegarder
                ext.Save();

                // 6. Recharger et basculer vers Available
                ext = ps.GetDNByNumber(TARGET_EXT) as Extension;
                if (ext == null)
                    return Task.FromResult(false);

                FwdProfile profile = ext.FwdProfiles
                    .FirstOrDefault(p => p.Name.Equals(
                        "Available", StringComparison.OrdinalIgnoreCase));

                if (profile != null)
                {
                    ext.CurrentProfile = profile;
                    ext.Save();
                }

                return Task.FromResult(true);
            }
            catch (Exception)
            {
                return Task.FromResult(false);
            }
        }
    }
}

Configuration concrète

On a besoin de gérer deux astreintes. Le poste Accueil reçoit les appels en temps normal

Extraits de chaque script
Marcel Patulacci Jean-Michel Apeuprè Poste accueil hors période d'astreinte
public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
{
 // modifier uniquement ces lignes :
private const string TARGET_EXT   = "111";
private const string MOBILE_EXT   = "0612345678";
private const string PRENOM_EXT   = "Marcel";
private const string NOM_EXT      = "Patulacci";
public class SetDynamicAstreinte : ScriptBase<SetDynamicAstreinte>
{
// Modifier uniquement ces lignes
private const string TARGET_EXT   = "111";
private const string MOBILE_EXT   = "0699999999";
private const string PRENOM_EXT   = "Jean-Michel";
private const string NOM_EXT      = "Apeuprè";
public class ResetAstreinte : ScriptBase<ResetAstreinte>
{
// Modifier uniquement ces lignes :
private const string TARGET_EXT   = "111";
private const string PRENOM_EXT   = "Accueil";
private const string NOM_EXT      = "Mairie";

Une fois les 3 scripts produits, passer à l'étape Déclaration du script qui va permettre d'affecter un code court à chaque script. Exemple :

  • *90 pour hors période d'astreinte
  • *91 pour Jean-Michel
  • *92 pour Marcel

On peut communiquer les codes aux personnes habilitées à gérer le système d'astreinte et aller jusqu'à paramétrer des BLF pour faciliter la vie d'une secrétaire par exemple.

Valide v20