# Exemple - surveiller une boîte à lettres mail

La librairie JavaScript des services d'automation ELO contient un module permettant d'envoyer et de recevoir des e-mails. Voici comment utiliser ELOas pour la surveillance d'une boîte de réception.

Information

Cet exemple n'est pas sensé simuler un archivage mail. Mais nous avons d'autres modules adéquats dans la liste des produits. Il doit servir de base pour „Autoresponder“, donc les programmes qui engendrent une action automatiquement suite à un mail (par exemple un utilisateur envoie un mail d'enregistrement, après quoi son compte est autorisé).

# Démarche générale

Avant qu'un ruleset puisse être créé pour le traitement des boîtes de réception, une connexion à la boîte de réception doit être créée dans le module mail. Etant donné qu'il existe beaucoup de différences et de possibilités, on ne peut pas travailler avec une liste de configuration simple. Il est nécessaire qu'une méthode connect soit créée pour chaque connexion à la boîte de réception. Celle-ci doit établir la connexion au serveur mail, sélectionner la boîte de réception et lire la liste des messages.

Chaque connexion à la boîte de réception contient un nom simple et court, par exemple GMAIL. Ce nom est requis à différents endroits et doit être compatible à l'identificateur, cela signifie qu'il doit commencer par une lettre et peut contenir d'autres lettres ou chiffres. Ce nom est requis à différents endroits dans le ruleset et dans l'implémentation JavaScript.

# Etablissement de la connexion

La librairie JavaScript apporte déjà une définition dans l'installation standard, pour une connexion avec le nom GMAIL. Nous allons l'utiliser pour cet exemple. Etant donné que le nom de connexion se retrouve dans les fonctions spéciales, vous pouvez définir plusieurs connexions en parallèle et les utiliser dans différents rulesets.

La fonction standard pour l'établissement de la connexion GMAIL ressemble à ceci:

connectImap_GMAIL: function() {
    var props = new Properties();
    props.setProperty("mail.imap.host", "imap.gmail.com");
    props.setProperty("mail.imap.port", "993");
    props.setProperty("mail.imap.connectiontimeout", "5000");
    props.setProperty("mail.imap.timeout", "5000");
    props.setProperty("mail.imap.socketFactory.class",
                      "javax.net.ssl.SSLSocketFactory");
    props.setProperty("mail.imap.socketFactory.fallback", "false");
    props.setProperty("mail.store.protocol", "imaps");
    var session = Session.getDefaultInstance(props);
    MAIL_STORE = session.getStore("imaps");
    MAIL_STORE.connect("imap.gmail.com",
                       "<BENUTZER>@gmail.com",
                       "<PASSWORT>");
    var folder = MAIL_STORE.getDefaultFolder();
    MAIL_INBOX = folder.getFolder("INBOX");
    MAIL_INBOX.open(Folder.READ_WRITE);
    MAIL_MESSAGES = MAIL_INBOX.getMessages();
    MAIL_DELETE_ARCHIVED = false;
},

L'exemple se connecte au serveur Googlemail "imap.gmail.com" sur le port "993" par le biais d'une connexion codée (mail.store.protocolimaps). Ces informations sont entrées dans un Property Object. Votre propre serveur mail requiert peut-être d'autres valeurs, celles-ci se trouvent dans les explicatifs concernant le serveur de messagerie.

Information

Si vous créez un compte google mail, vous devez tout d'abord l'autoriser pour un accès IMAP. Cela se fait sous Réglages > Transfert et POP/IMAP > Activer IMAP.

Cette authentification est effectuée par le biais de la commande MAIL_STORE.connect. Le nom de serveur doit être entré ainsi que l'utilisateur de la boîte de réception avec mot de passe.

Après l'authentification, c'est le classeur Boîte de réception qui est parcouru. Il est bien sûr possible de surveiller d'autres classeurs, par exemple Envoyé :

MAIL_INBOX = folder.getFolder("[Google Mail]/envoyé")

La commande MAIL_INBOX.getMessages() permet finalement de lire tous les mails du classeurs et de les lire dans la liste des messages internes. Cette liste est traitée ultérieurement, le ruleset est appelé une fois pour chaque entrée de cette liste.

La variable MAIL_DELETE_ARCHIVED détermine si le ruleset doit supprimer le message ou le marqué comme traité, après le traitement. Si son statut est "false" (comme dans le pré-réglage), le statut du message n'est pas modifié. C'est très pratique dans la phase de test, afin que l'on ne doivent pas sans cesse créer de nouveaux mails. Normalement, cette entrée devrait avoir la valeur "true".

# Créer un ruleset

Un simple ruleset permet de traiter le contenu de la boîte de réception se compose de deux parties: la définition de la recherche et le script permettant de traiter le mail.

La recherche est définie de la manière suivante :

<search>
<name>"MAILBOX_GMAIL"</name>
<value>"ARCPATH:¶IMAP"</value>
<mask>2</mask>
<max>200</max>
</search>

Le nom de recherche "MAILBOX_GMAIL" signale qu'il ne s'agit pas d'une recherche dans l'archive normale, mais d'une boîte de réception du nom de connexion GMAIL. Les documents ELO créés sont déposés dans l'armoire "IMAP" (par le biais de ARCPATH:¶IMAP) et sont créés avec le masque 2 (e-mail dans une archive ELO standard). Le nombre de résultats n'est pas pertinent en règle générale, mais il devrait être entré afin qu'il n'y ait pas de message d'erreur dans le créateur.

Le script d'exécution est déterminé par la fonction requise. Un cadre simple pourrait ressembler à ceci :

<script>
    log.debug("Process Mailbox: " + NAME);
    OBJDESC = mail.getBodyText(MAIL_MESSAGE);
    ELOOUTL1 = mail.getSender(MAIL_MESSAGE);
    ELOOUTL2 = mail.getRecipients(MAIL_MESSAGE, "¶");
    EM_WRITE_CHANGED = true;
    MAIL_ALLOW_DELETE = true;
</script>

Lors de l'exécution de script, le message est disponible dans les variables MAIL_MESSAGE. A partir de là, il est possible de lire des valeurs standards, par exemple le text du message, l'expéditeur et le destinataire. Afin que cela soit plus simple, le module mail met à disposition les routines d'aide getBodyText, getSender et getRecipients.

L'objet est adopté automatiquement dans la désignation (NAME). Le corps du message est écrit dans le texte supplémentaire et l'expéditeur et le destinataire sont transférés dans les champs de métadonnées correspondants. En dernier, le message est marqué comme traité ou supprimé par MAIL_ALLOW_DELETE.

L'exemple complet ressemble à ceci :

<ruleset>
<base>
<name>Mailbox</name>
<search>
<name>"MAILBOX_GMAIL"</name>
<value>"ARCPATH:¶IMAP"</value>
<mask>2</mask>
<max>200</max>
</search>
<interval>10M</interval>
</base>
<rule>
<name>List</name>
<condition></condition>
<script>
    log.debug("Process Mailbox: " + NAME);
    OBJDESC = mail.getBodyText(MAIL_MESSAGE);
    ELOOUTL1 = mail.getSender(MAIL_MESSAGE);
    ELOOUTL2 = mail.getRecipients(MAIL_MESSAGE, "¶");
    EM_WRITE_CHANGED = true;
    MAIL_ALLOW_DELETE = true;
</script>
</rule>
<rule>
<name>Global Error Rule</name>
<condition>OnError</condition>
<script></script>
</rule>
</ruleset>

# Traitement surveillé

L'exemple simple a un désavantage prépondérant: si un mail a déjà été marqué comme étant "traité" ou qu'il a été supprimé et que le processus est interrompu, avant que les données ont pu être enregistrées dans l'archive, un jeu de données reste tel quel, sans avoir été traité. Ce problème peut être évité complètement, si l'on travaille à deux niveaux: ce nouveau message est tout d'abord seulement enregistré dans ELO, mais il n'est pas encore supprimé. Si un mail se trouvant dans ELO est trouvé plus tard, il est supprimé.

Deux conditions sont importantes pour ce procédé: le mail doit être reconnaissable de façon univoque et une vérification doit être effectuée afin de savoir si elle existe déjà dans l'archive. Le premier point est très simple: chaque mail possède un ID de mail interne. Celui-ci peut être enregistré dans ELO dans un champs de métadonnées (par exemple dans le masque mail standard dans le champ ELOOUTL3, réservé pour l'ID du mail). Le deuxième point peut être traité très facilement grâce à une routine d'aide depuis le module ELOix : ix.lookupIndexByLine.

Le script modifié ressemble à ceci :

<script>
    log.debug("Process Mailbox: " + NAME);
    //   // lorsque le message est déjà dans l'archive: alors supprimer.
    var msgId = MAIL_MESSAGE.messageID;
    if (ix.lookupIndexByLine(EM_SEARCHMASK, "ELOOUTL3", msgId) != 0) {
        log.debug("le mail existe déjà dans l'archive,
                  ignorer ou supprimer");
        MAIL_ALLOW_DELETE = true;
    }   else {
        OBJDESC = mail.getBodyText(MAIL_MESSAGE);
        ELOOUTL1 = mail.getSender(MAIL_MESSAGE);
        ELOOUTL2 = mail.getRecipients(MAIL_MESSAGE, "¶");
        ELOOUTL3 = msgId;
        EM_WRITE_CHANGED = true;
    }
</script>

# Marquer au lieu de supprimer

Dans l'implémentation standard, un mail traité est supprimé de la boîte de réception. Ce n'est pas souhaité dans quelques cas. Il est également possible d'effectuer un marquage. Un candidat possible est le drapeau "lu". Un mail traité est placé sur "lu" par ELOas et se différencie ainsi d'un nouveau mail. Dans ce cas, d'autres méthodes doivent être définies dans la mail JavaScript Library, en plus de la méthode connectImap :

nextImap_GMAIL(): cette fonction permute vers le prochain message. Dans cet exemple, elle doit vérifier si un mail a déjà été marqué comme lu, et le passer si nécessaire.

finalizeImap_GMAIL(): cette fonction marque le message traité. Dans l'implémentation standard, le message est supprimé. Dans notre exemple, il doit seulement être marqué comme lu.

# nextImap_GMAIL

Cette fonction permute vers le prochain message. Elle passe de façon séquentielle par le biais de la liste des messages, la position actuelle est enregistrée dans la variable MAIL_POINTER. Si un message a déjà été marqué comme lu, elle est passée. Celle-ci est activée lors du premier message non-lu (il est copié dans la variable MAIL_MESSAGE) et la valeur true est livrée. S'il n'existe pas d'autres messages, un false est livré. ELOas termine alors le traitement de ce ruleset et bascule vers le suivant.

nextImap_GMAIL: function() {
    for (;;) {
        if (MAIL_POINTER >= MAIL_MESSAGES.length) {
            return false;
        }
        MAIL_MESSAGE = MAIL_MESSAGES[MAIL_POINTER];
        var flags = MAIL_MESSAGE.getFlags();
        if (flags.contains(Flags.Flag.SEEN)) {
            MAIL_POINTER++;
            continue;
        }
        MAIL_ALLOW_DELETE = false;
        MAIL_POINTER++;
        return true;
    }
    return false;
},

Une initialisation est effectuée, la variable MAIL_ALLOW_DELETE est placée sur false. Si un traitement est effectué dans le ruleset, celui-ci devrait placer la variable sur true. Dans ce cas, le mail est marqué dans la méthode finaliselmap en tant que traité.

# finalizeImap_GMAIL

La fonction finalizeImap_GMAIL doit marqué un mail comme traité, cela se fait en plaçant le drapeau SEEN. Elle peut seulement être placée si la méthode Connect le permet (MAIL_DELETE_ARCHIVED) et que le ruleset a placé le mail actuel comme étant archivé (MAIL_ALLOW_DELETE).

finalizeImap_GMAIL: function() {
    if (MAIL_DELETE_ARCHIVED &amp;&amp; MAIL_ALLOW_DELETE) {
        message.setFlag(Flags.Flag.SEEN, true);
    }
},
Dernière mise à jour: 27 septembre 2023 à 11:29