A l'écoute des mails (Listener) Dernière Modification le : 2024-01-13Le ZIP des Ressources Un changement majeur et profond a eu lieu, et on la voit de la façon la plus flagrante au niveau de la Logistique. Certes, nos fournisseurs voulaient bien, il y a quelques années, nous informer d'un numéro de suivi sur l'interface Internet que nous leur offrons. Il y a alors alors correspondance 1 à 1 entre l'information logistique du fournisseur et le dossier du client. L'information migre et le client est informé par nous de l'expédition de la commande. Ca, c'était avant... Aujourd'hui, le fournisseur a fourni votre adresse email au transporteur (ex: UPS) qui vous informe par mail, et, s'en tient là. De même, il voulait encore bien cliquer sur un lien pour confirmer un délai. Aujourd'hui il vous envoie un A/R, avec un PDF en PJ et c'est tout! De même nos clients prennent le pli d'attendre que l'information apparaisse sur leur téléprompteur (aka. messagerie). Vous risquez de passer un temps fou à pallier à ce problème alors que de nouvelles solutions existent. Mettre le Serveur à l'écoute de la boite Mail IBM décrit un Listener qui semble écouter, trier, classer des demandes de support (avec gestion de ticket) Lire →. On identifie plusieurs étapes: récupérer les mails, les filtrer/trier, digérer, créer une action, répondre au client. Certaines sont banales, d'autres assez spécifiques. Par exemple reconnaitre un numéro de suivi chez GLS, dépendra de la langue, pourra changer au grès des modifications chez GLS, des pays, etc. La personalisation d'un package "clé en main" ne me parait pas évidente. Les points durs sont le rapatriement de la boite mail, le détachement des pièces jointes, la 'lecture' des PDF (ex: commandes, accusés de réception de commande...), le filtrage, sa sensibilité et sa spécificité. Télécharger sa boite POP3 (Synchronisation) Il y a pléthore d'outils commerciaux... On peut aussi instrumentaliser Outlook, qui est lourd et fait crasher le serveur. J'évite... Un point dur est le détachement des pièces jointes, point sur lequels les solutions proposées ne sont pas toujours très claires. On veut rapatrier les mails, les sauvegarder, les 'lire', y compris les pièces jointes: c'est possible! Les transporteurs (ex: UPS) envoient des mails sans pièce jointe. Un bon vieux (trop vieux ?) composant comme Dypso POP3, ferait l'affaire. Lire → Je mets le composant, aujourd'hui disparu, dans le ZIP de ressources. Télécharger →. On trouve encore le manuel. Ca marche pour la logistique, mais on ne peut pas extraire les pièces jointes, ni lire plus de 20 mails présents sur le serveur: il faut consulter souvent. Fetch ou getmail6 sont uniquement pour Linux. Un vieux getmail par Tim Charron a les fonctions qui m'interressent Lire et Télécharger → . Il peut extraire automatiquement les fichiers binaires codés MIME ou UU lors du téléchargement. Ne fonctionne qu'avec POP3. On peut contourner le problème en renvoyant automatiquement sur une boite mail aveugle, en POP3. En mode Desktop, l'utilisation de Thunderbird pour la synchronisation et de l'extension FiltaQilla pour le filtrage et/ou extraction des pièces jointes est une alternative viable, économe en temps de programmation initial. Les fonctionnalités du filtrage sont larges mais parfois un peu limite Mon Listener fait appel à de nombreuses techniques: CURL, MUNPACK, UUDECODE, PDFTOTXT, TESSERACT, etc.. Je pense même à intégrer Chat GPT et DEEP-L. Commencons par relever la boite aux lettres... CURL, encore et toujours C'est un outil versatile! Gratuit, robuste, intégré à Windows, populaire dans le monde Linux: il fait aussi POP3 , IMAP et ...Gmail (? à vérifier...). Lire le Manuel →. La commande intégrée de Windows a quelques rares limitations, donc, si c'est possible, on installera la dernière version. Télécharger → On initialise nos valeurs... A noter que Curl ne crée pas les fichiers de sortie en tant que de besoin, il faut les avoir créé d'entrée de jeu. Set objFSO = CreateObject("Scripting.FileSystemObject") sDossierComptesFolderPath = "C:\Users\MonServeur\Documents\POP3\Comptes\" '// à personnaliser sMessagesPresentsFileName = "Messages_presents_sur_le_serveur_distant.txt" sAlreadyDownloadedFileName = "Already_Downloaded.txt" sATelechargerFileName = "A_Telecharger.txt" ' // On définit les comptes à surveiller. Dim ArComptes (10, 4) ArComptes (0,0) = "granuloshop" 'Nom de dossier ArComptes (0,1) = "pop3.free.fr" 'serveur ArComptes (0,2) = "granuloshop" 'utilisateur ArComptes (0,3) = "xxxxxxx" 'mot de passe ArComptes (1,0) = "manager" ArComptes (1,1) = "mail.granuloshop.com" ArComptes (1,2) = "manager@granuloshop.com" ArComptes (1,3) = "xxxxxxx" ' // etc. For i = 0 to 9 If ArComptes (i,0) <> "" then If NOT objFSO.FolderExists(sDossierComptesFolderPath & ArComptes (i,0) & "\") then objFSO.CreateFolder sDossierComptesFolderPath & ArComptes (i,0) & "\" If NOT objFSO.FolderExists(sDossierComptesFolderPath & ArComptes (i,0) & "\") then objFSO.CreateFolder sDossierComptesFolderPath & ArComptes (i,0) & ""\Inbox\" If NOT objFSO.FolderExists(sDossierComptesFolderPath & ArComptes (i,0) & "\") then objFSO.CreateFolder sDossierComptesFolderPath & ArComptes (i,0) & "\Mails\" ' // CURL ne créera pas les fichiers de sortie: il faut s'assurer qu'ils existent avant tout ' // CURL va redocumenter le fichier de messages présents sur le serveur distant If NOT objFSO.FileExists(sDossierComptesFolderPath & ArComptes (i,0) & "\" & sMessagesPresentsFileName) then objFSO.CreateTextFile sDossierComptesFolderPath & ArComptes (i,0) & "\" & sMessagesPresentsFileName ' // Eventuellement, si on souhaite un log pour debugger ... ' // If NOT objFSO.FileExists(sDossierComptesFolderPath & ArComptes (i,0) & "\curl_log.txt") then objFSO.CreateTextFile sDossierComptesFolderPath & ArComptes (i,0) & "\curl_log.txt" End If Next Une fois au plus, on pourra vouloir consulter les services proposés par le serveur distant, en particulier la capacité à enrichir la liste des messages présents d'un identifiant unique: le nom est UIDL. Voici la commande: curl.exe -l -v -u username:password pop3://pop.free.fr On va conserver l'historique afin de réduire les requêtes au serveur distant: ' // on reconstitue l'historique, si besoin. Si le téléchargement précédent a planté, on ne repart pas de Zéro For i = 0 to 9 If ArComptes (i,0) <> "" then sHistorique = "" sFilePath = sDossierComptesFolderPath & ArComptes (i,0) & "\Already_Downloaded.txt" Set objOpen = objFSO.OpenTextFile(sFilePath, 1, true) ' // 1 = ForReading, true créera le fichier si besoin If NOT objOpen.AtEndOfStream then sHistorique = objOpen.ReadAll objOpen.Close Set objOpen = nothing Set Folder = objFSO.GetFolder (sDossierComptesFolderPath & ArComptes (i,0) & "\InBox\") for each File in Folder.Files If NOT InStr(sHistorique, Replace (File.Name, ".eml", "")) AND File.Size > 0 then sHistorique = Replace (File.Name, ".eml", "") & VbCrLf & sHistorique Next Set objFile = objFSO.OpenTextFile(sDossierComptesFolderPath & ArComptes (i,0) & "\Already_Downloaded.txt", 2, true) ' // 2 = ForWriting, true créera le fichier si besoin objFile.Write sHistorique objFile.Close Set objFile = nothing End If Next Curl va interroger le serveur distant, qui va donner une liste de message présents avec un identifiant unique. sBat = "" For i = 0 to 9 If ArComptes (i,0) <> "" then sBat = sBat & VbCrLf & """curl.exe"" -X ""UIDL"" -v -o """ & sDossierComptesFolderPath & ArComptes (i,0) & "\" & sMessagesPresentsFileName & """ -u " & ArComptes (i,2) & ":" & ArComptes (i,3) & " pop3://" & ArComptes (i,1) End If Next sCurlBatListFilePath = "C:\Users\MonServeur\Documents\POP3\Curl_Bat.bat" ' // a personaliser Set objFile = objFSO.OpenTextFile(sCurlBatListFilePath, 2,true) ' // 2= ForWriting objFile.Write sBat objFile.Close Set objFile = nothing Command = """" & sCurlBatListFilePath & """" oShell.Run Command, 0, True On dispose maintenant de la liste des messages, chacun avec un identifiant unique. On construit une liste de messages à télécharger, en excluant ceux qui ont déjà été téléchargés. "curl.exe -o """ & sDossierComptesFolderPath & ArComptes (i,0) & "\InBox\" & sUID & ".eml"" -u " & ArComptes (i,2) & ":" & ArComptes (i,3) & " pop3://" & ArComptes (i,1) & "/" & sNumero Dans la commande CURL: -o désigne le dossier et le nom attribué au mail. On veille à ne pas avoir de caractères interdits -u désigne l'utilisateur suivi de : et le mot de passe- ensuite, le protocole et le serveur suivi du numéro d'ordre du message (non pas son Indentifiant Unique...) Exemple: pop3://free.fr/Numero POP3 est un protocole assez rustique et ancien, il reste accessible avec la commande TELNET. ' // on reconstitue l'historique, si besoin. Si le telechargement precedent a planté, on ne repart pas de Zéro For i = 0 to 9 If ArComptes (i,0) <> "" then sHistorique = "" sFilePath = sDossierComptesFolderPath & ArComptes (i,0) & "\Already_Downloaded.txt" Set objOpen = objFSO.OpenTextFile(sFilePath, 1,true) ' // ForReading = 1 , true va créer le fichier si besoin If NOT objOpen.AtEndOfStream then sHistorique = objOpen.ReadAll objOpen.Close Set objOpen = nothing Set Folder =objFSO.GetFolder (sDossierComptesFolderPath & ArComptes (i,0) & "\InBox\") for each File in Folder.Files If NOT InStr(sHistorique, Replace (File.Name, ".eml", "")) AND File.Size > 0 then sHistorique = Replace (File.Name, ".eml", "") & VbCrLf & sHistorique Next Set objFile = objFSO.OpenTextFile(sDossierComptesFolderPath & ArComptes (i,0) & "\Already_Downloaded.txt", 2,true) ' // ForWriting =2 objFile.Write sHistorique ' & VbCrLf objFile.Close Set objFile = nothing sA_telecharger = "" sFilePath = sDossierComptesFolderPath & ArComptes (i,0) & "\Messages_presents_sur_le_serveur.txt" Set objOpen = objFSO.OpenTextFile(sFilePath, 1,true) ' // ForReading = 1 ObjOpen.Close Set objOpen = nothing If NOT objOpen.AtEndOfStream then Do While NOT objOpen.AtEndOfStream sLine = trim(objOpen.ReadLine) If sLine <> "" then If InStr(sLine, " ") > 0 then nMessage = nMessage + 1 sNumero = "" sNumero = Trim (Left(sLine, InStr(sLine, " ") -1)) sUID = replace (sLine, sNumero, "") sUID = trim(replace (sUID, " ", "")) sUID = Normalize(sUID) if sNumero <> "" AND InStr(sHistorique, sUID) = 0 then if sBat <> "" then sBat = sBat & VbCrLf StrBat = StrBat & "curl.exe -o """ & sDossierComptesFolderPath & ArComptes (i,0) & "\InBox\" & sUID & ".eml"" -u " & ArComptes (i,2) & ":" & ArComptes (i,3) & " pop3://" & ArComptes (i,1) & "/" & sNumero if sA_telecharger <> "" then sA_telecharger = sA_telecharger & VbCrLf sA_telecharger = sA_telecharger & sUID End If End If End If Loop End If End If Next Sauvegardons notre ligne de commande pour déverminage éventuel. Puis on y va! Set objFile = objFSO.OpenTextFile(sCurlBatMessagesFilePath, 2,true) ' // ForWriting=2 objFile.Write sBat objFile.Close Set objFile = nothing Command = """" & sCurlBatMessagesFilePath & """" if sBat <> "" then oShell.Run Command, 0, True On renomme les mails pour plus de lisibilité Avec POP3, les mails sont identifiés par un GUID, unique certes, mais illisible: ce n'est pas pratique pour l'inévitable débogage! Donc, à coté de nos dossiers Inbox, nous créons des dossiers Mails, où le nom de fichier est lisible est permet de vérifier les fonctions de filtrage, par exemple. On renomme à partir du domaine de l'expéditeur et du titre. Il est utile de mettre le nom de domaine de l'expéditeur en tête du nom de fichier, suivi du titre. Il faut prendre soin de corriger ce nom de fichier pour qu'il soit licite (au sens de Windows/DOS). Par ailleurs pour éviter d'avoir à vérifier pour chaque petit programme que je suis amené à utiliser, je convertis les caratères non-ANSI en ANSI, comme cela on est tranquille. On trouve ici une liste de charactères à éviter: Lire →. Une discussion complete est disponible sur Stackoverflow Lire → et cette réference par Microsoft Lire → Tout caractère dont le code UNICODE est inférieur à 128 est ASCII Pour les charactères du deuxieme bloc de ISO/IEC 8859-1 on met une substitution, s'il y en a d'évidente. Sinon, on ne fait rien, le charactères sera éliminé plus loin... Lire Wikipedia → Ensuite on élimine tout caractère qui n'est pas dans cette liste où l'on a pris soin de laisser l'espace blanc, qui se trouve ici entre ! et ] (et de retirer le &, la virgule et le point)[abcdefghijklmnopqrstuvwxyzz0123456789+=_-)(*%#! ] Les noms de fichiers sur les systèmes Windows ne peuvent pas contenir les caractères suivants : \<>:\"/|?*. Le VBS est disponible dans le ZIP de Ressoures. Télécharger → ' // Cette fonction substitue et élimine des caractères en vue de faire des noms de fichiers lisibles à partir du titre d'un email Function StripChars(sT) ' // https://www.experts-exchange.com/questions/24454280/Best-way-to-remove-non-ascii-characters.html '// LIKE ne fonctionne pas en VBS Dim intCount ' // Pour les caractères du deuxieme bloc de ISO/IEC 8859-1 on met des substitutions, s'il y en a. Sinon, on ne fait rien, le caracteres sera elimine plus loin... ' // https://en.wikipedia.org/wiki/ISO/IEC_8859-1 ' // caractères qui n'ont pas de sustitution "¤" "§" "¦" "¨" "ª" "¬" "®" "¶" sT = Replace(sT, "¡","!") : sT = Replace(sT, "¢","c") : sT = Replace(sT, "£","GBP") : sT = Replace(sT, "¥","YEN") : sT = Replace(sT, "©","c") : sT = Replace(sT, "«","""") sT = Replace(sT, "¯","-") : sT = Replace(sT, "°","o") : sT = Replace(sT, "±","+/-") : sT = Replace(sT, "²","2") : sT = Replace(sT, "³","3") : sT = Replace(sT, "´","'") sT = Replace(sT, "µ","micron") : sT = Replace(sT, "·",".") : sT = Replace(sT, "¸",".") : sT = Replace(sT, "¹","1") : sT = Replace(sT, "º","o") : sT = Replace(sT, "»","""") sT = Replace(sT, "¼","1/4") : sT = Replace(sT, "½","1/2") : sT = Replace(sT, "¾","3/4") : sT = Replace(sT, "¿","?") : sT = Replace(sT, "À","A") : sT = Replace(sT, "Á","A") sT = Replace(sT, "Â","A") : sT = Replace(sT, "Ã","A") : sT = Replace(sT, "Ä","A") : sT = Replace(sT, "Å","A") : sT = Replace(sT, "Æ","AE") : sT = Replace(sT, "Ç","C") sT = Replace(sT, "È","E") : sT = Replace(sT, "É","E") : sT = Replace(sT, "Ê","E") : sT = Replace(sT, "Ë","E") : sT = Replace(sT, "Ì","I") : sT = Replace(sT, "Í","I") sT = Replace(sT, "Î","I") : sT = Replace(sT, "Ï","I") : sT = Replace(sT, "Ð","D") : sT = Replace(sT, "Ñ","N") : sT = Replace(sT, "Ò","N") : sT = Replace(sT, "Ó","O") sT = Replace(sT, "O","O") : sT = Replace(sT, "Õ","O") : sT = Replace(sT, "Ö","O") : sT = Replace(sT, "×","x") : sT = Replace(sT, "Ø","dia.") : sT = Replace(sT, "Ù","U") sT = Replace(sT, "Ú","U") : sT = Replace(sT, "Û","U") : sT = Replace(sT, "Ü","U") : sT = Replace(sT, "Ý","Y") : sT = Replace(sT, "Þ","b") : sT = Replace(sT, "ß","ss") sT = Replace(sT, "à","a") : sT = Replace(sT, "á","a") : sT = Replace(sT, "â","a") : sT = Replace(sT, "ã","a") : sT = Replace(sT, "ä","a") : sT = Replace(sT, "å","a") sT = Replace(sT, "æ","ae") : sT = Replace(sT, "ç","c") : sT = Replace(sT, "è","e") : sT = Replace(sT, "é","e") : sT = Replace(sT, "ê","e") : sT = Replace(sT, "ë","e") sT = Replace(sT, "ì","i") : sT = Replace(sT, "í","i") : sT = Replace(sT, "i","i") : sT = Replace(sT, "ï","i") : sT = Replace(sT, "ð","d") : sT = Replace(sT, "ñ","n") sT = Replace(sT, "ò","o") : sT = Replace(sT, "ó","o") : sT = Replace(sT, "ô","o") : sT = Replace(sT, "õ","o") : sT = Replace(sT, "ö","o") : sT = Replace(sT, "ö","/") sT = Replace(sT, "ø","dia.") : sT = Replace(sT, "ù","u") : sT = Replace(sT, "ú","u") : sT = Replace(sT, "û","u") : sT = Replace(sT, "ü","u") : sT = Replace(sT, "ý","y") : sT = Replace(sT, "þ","b") : sT = Replace(sT, "ÿ","y") ' // https://www.mtu.edu/umc/services/websites/writing/characters-avoid/ ' // caractères qui n'ont pas de sustitution # pound % percent & ampersand { left curly bracket } right curly bracket \ back slash < left angle bracket > right angle bracket * asterisk ? question mark / forward slash blank spaces $ dollar sign ! exclamation point single quotes " double quotes : colon @ at sign ' // Là où Thunderbird a proposé une substitution, on fait de même... sT = replace (sT, "&", "+") : sT = replace (sT, "\", "-") : sT = replace (sT, "*", "-") : sT = replace (sT, "?", "-") sT = replace (sT, "/", "-") : sT = replace (sT, ":", "-") : sT = replace (sT, "@", "-") ' // On substitue aussi la virgule et le point sT = replace (sT, ",", "-") : sT = replace (sT, ".", "-") For intCount = 1 To Len(sT) ' // cette formule autorise le blanc mais pas & If InStr(1,"[abcdefghijklmnopqrstuvwxyz0123456789+=_-)(*%#! ]", Mid(sT, intCount, 1),1) > 0 Then StripChars = StripChars & Mid(sT, intCount, 1) End If Next Do While InStr(StripChars, "__") > 0 OR InStr(StripChars, "--") > 0 OR InStr(StripChars, " ") > 0 StripChars = replace (StripChars, "__", "_") : StripChars = replace (StripChars, "--", "-") : StripChars = replace (StripChars, " ", " ") Loop End Function A propos de l'unicité du nom... Le UID sur serveur POP est unique. Pas le titre du mail. Or, certains clients envoient le même mail sur plusieurs boites, le serveur mail crée aussi des doublons... Donc, dans le contexte du Listener, éliminer ces doublons est plutôt une bonne idée: un mail reçu sur la boite A sera traité et marqué comme tel. Le même mail reçu sur la boite B, ne sera pas traité, puisqu'il est marqué comme traité. A l'inverse les systèmes automatiques tels que UPS et en particulier GLS, envoient des mails différents avec le même titre (et pas de pièce jointe). A ces mails, comme à ceux dont le titre est un peu court, on ajoute un GUID If InStr(1, sentete, "GLS", 1) > 0 OR InStr(1, sentete, "UPS", 1) > 0 OR Len(sSujet) < 25 then 'InStr(1, sentete, "UPS", 1) > 0 OR ' Pour l'instant je n'aile pb qu'avec GLS 'il faut recréer une instance puis la purger à chaque fois, sinon, il donne le même résultat! Set TypeLib = CreateObject("Scriptlet.TypeLib") myGuid = TypeLib.Guid myGuid = Replace(myGuid, "{","") myGuid = Replace(myGuid, "}","") myGuid = Replace(myGuid, "-","") ' // Quand on veut le GUID complet, ce qui n'est pas le cas ici... myGuid = Replace(Left(myGuid, Len(myGuid)-2),"-","") sTitre = sTitre & "_" & Left(myGuid,6) set TypeLib = nothing End If Un peu de nettoyage... Il y a 3 nettoyages à effectuer: les dossiers locaux, les listes d'historique (ou base de données, le cas échéant), les dossiers POP3 distants. On ne fait le nettoyage qu'une seule fois par jour, aux heures creuses (ex. 6 heures du matin). ' // Lecture de la date de nettoyage quotidien dans le fichier correspondant. Les dates sont au format ISO simplifié, c-à-d. sans tiret sDate_Nettoyage_Quotidien = "20220101" ' // valeur par défaut sDateNettoyageQuotidienFileName = "Nettoyage_Quotidien.txt" sDateNettoyageQuotidienFilePath = "C:\Users\MonCompte\MyDocuments\Listener\" ' // A personnaliser sAujourdhui = ToIsoDateSimplified (Now()) Set objOpen = objFSO.OpenTextFile(sDateNettoyageQuotidienFilePath, 1, true) ' // 1 = ForReading, true créera le fichier si besoin If NOT objOpen.AtEndOfStream then sDate_Nettoyage_Quotidien = trim(objOpen.ReadLine) objOpen.Close Set objOpen = nothing ' Vérification si le nettoyage quotidien doit être effectué aujourd'hui Do_Nettoyage_Quotidien = False If sAujourdhui > sDate_Nettoyage_Quotidien AND Hour(Now()) > 5 then Do_Nettoyage_Quotidien = True Private Function StrN2(n) If Len(CStr(n)) < 2 Then StrN2 = "0" & n Else StrN2 = n End Function Public Function ToIsoDateSimplified (datetime) ToIsoDateSimplified = CStr(Year(datetime)) & StrN2(Month(datetime)) & StrN2(Day(datetime)) End Function On crée une table des dossiers à purger de sorte à éviter l'inflation et on définit une durée limite (ex: 15 j.) en incluant les dossiers de reception sur chaque boite mise sous surveillance. De même, on crée une liste des fichiers cumulatifs, historiques, avec éventuellemet un cap et un cap par défaut. Avant chaque action, le fichier cumulatif est pris en considération pour éviter de refaire ce qui a déjà été fait. DIM ArDossiers_A_Nettoyer (50) ArDossiers_A_Nettoyer (0) = sLogFolderPath ' // A personaliser et compléter j=49 For i = 0 to 9 If ArComptes (i,0) <> "" then ArDossiers_A_Nettoyer (j) = sDossierComptesFolderPath & ArComptes (i,0) & "\Inbox\" ArDossiers_A_Nettoyer (j-1) = sDossierComptesFolderPath & ArComptes (i,0) & "\Mails\" j=j-2 End If Next DIM ArFichiersHistoriques (20,2) ArFichiersHistoriques (1,0) = sAlreadyDownloadedFilePath ' // A personaliser et compléter ArFichiersHistoriques (1,1) = 3000 ' // ici, pas plus de 3000 lignes dans ce fichier if Do_Nettoyage_Quotidien then ' // Call Log ( VbCrLf & "*****" & VCrLf & "On entre dans le module de Nettoyage *****") ' // Call Log ("On fait un petit nettoyage journalier, car sAujourdhui: " & sAujourdhui & " sDate_Nettoyage: " & sDate_Nettoyage & " et Do_Nettoyage_Quotidien : " & Do_Nettoyage_Quotidien) For i = 0 to 50 If ArDossiers_A_Nettoyer (i) <> "" then If objFSO.FolderExists(ArDossiers_A_Nettoyer (i)) then Set Folder =objFSO.GetFolder (ArDossiers_A_Nettoyer (i)) For each File in Folder.Files sFileName = File.Name dtLastModified = CDate(Int(File.DateLastModified)) delta = sDayStamp - dtLastModified if Delta > DeltaMax AND objFSO.FileExists(ArDossiers_A_Nettoyer (i) & sFileName ) then objFSO.DeleteFile ArDossiers_A_Nettoyer (i) & sFileName Next End If End If Next ' // les fichiers cumulatifs sont tronqués de facon à ne pas devenir trop long For i = 0 to 20 If ArFichiersHistoriques (i,0) <> "" then j=0 JMax = 1000 if ArFichiersHistoriques (i,1) <> "" then JMax = CInt(ArFichiersHistoriques (i,1)) sNew = "" Set objOpen = objFSO.OpenTextFile(ArFichiersHistoriques (i,0), ForReading,true) If NOT objOpen.AtEndOfStream then Do While NOT objOpen.AtEndOfStream sLine = objOpen.ReadLine if j < JMax AND trim(sLine) <> "" then sNew = sNew & VbCrLf & trim(sLine) : j=j+1 Loop End If objOpen.Close Set objOpen = nothing If sNew <> "" then Set objOpen = objFSO.OpenTextFile(ArFichiersHistoriques (i,0), ForWriting,true) objOpen.Write sNew objOpen.Close Set objOpen = nothing End If End If Next ' // En fin de nettoyage, on metà jour la date du dernier nettoyage fait Set objFile = objFSO.OpenTextFile(sDateNettoyageQuotidienFilePath, ForWriting,true) objFile.Write sAujourdhui objFile.Close Set objFile = nothing Else ' // Call Log ("On ne fait pas de petit nettoyage") End If Les boites mails étant, par ailleurs, surveillées par Thunderbird, on lui laisse la tache de nettoyer régulièrement le serveur POP3. Et ensuite ? Le WorkFlow post-synchro Le WorkFlow est le suivant: La Synchronisation avec le serveur de Mail (ce billet ici même) Tri et distribution du courrier Lire → L'Extraction et transformation des pièces jointes La Lecture OCR L'extraction de données La definition des taches La Validation manuelle éventuelle L'execution https://forums.ivanti.com/s/article/Creating-a-workflow-to-send-an-email-when-a-listener-stops-working?language=en_US Précedent Suivant