Email Collector avec Office 365 / bug et contournement

Bonsoir la communauté

je fais référence à ce sujet : https://www.dolibarr.org/forum/t/email-collector-365-search-string-not-understood/17721 que je complète. Désolé si mon classement du post est erroné, j’hésite entre anomalie et suggestion ^^

nous sommes donc passés sous Office 365. Et en même temps j’ai commencé à vouloir installer le module ticket avec le module Email Collector, dans le but de créer des tickets automatiquement depuis une boite mail.
Donc premier « échec » : l’incompatibilité des serveurs Exchange avec un autre CHARSET que US-ASCII lors de la lecture en IMAP. Ok c’est donc côté Exchange. Mais a priori cela ne a pas bouger. Donc besoin pour moi de trouver une solution.

(tout se passe dans htdocs/emailcollector/class/emailcollector.class.php)

  1. Solution pour lire les mails en IMAP depuis un serveur Exchange
    Il faut donc modifier le paramètre CHARSET lors de la lecture imap.
    Donc modifier
    $arrayofemail = imap_search($connection, $search, null, "UTF-8");
    par
    $arrayofemail = imap_search($connection, $search, null, "US-ASCII");

Ok maintenant les emails sont bien lus. Mais nouveau souci parfois, la récupération des entêtes de mails notamment pour récupérer les « References » de ticket dolibarr, ne fonctionne pas correctement. Une histoire de CR/LF et de ‹ : › sans espace. De mon côté j’ai « MessageID » et « References » qui se retrouvent vides.

  1. Bien récupérer les entêtes
    Donc toujours dans le même fichier, j’ai ajouté après :
    $header = imap_fetchheader($connection, $imapemail, 0);
    $matches = array();
    une ligne pour formater des retours chariots corrects :
    $header = preg_replace('/\r\n\s+/m', ' ', $header);

Et là ok toutes mes entêtes sont bien récupérées. Cool.

Mais encore un souci. Effectivement la lecture dans les headers d’un mail du sujet, est mal formaté en raison du US-ASCII quand il y a des accents. Et le bout de code suivant ne fonctionne pas pour moi :

            // Can use also imap_mime_header_decode($str)
            // Can use also mb_decode_mimeheader($str)
            // Can use also iconv_mime_decode($str, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8')
            if (function_exists('imap_mime_header_decode')) {
                    $elements = imap_mime_header_decode($overview[0]->subject);
                    $newstring = '';
                    if (! empty($elements)) {
                    $num = count($elements);
                            for ($i = 0; $i < $num; $i++) {
                                    $newstring .= ($newstring ? ' ' : '').$elements[$i]->text;
                            }
                            $overview[0]->subject = $newstring;
                    }
            }
            elseif (function_exists('mb_decode_mimeheader')) {
                    $overview[0]->subject = mb_decode_mimeheader($overview[0]->subject);
            }

Du coup pour moi il faut traiter avec une autre fonction PHP, « iconv_mime_decode »
Il suffit d’insérer la ligne suivante juste avant le IF ci-dessus
$overview[0]->subject = iconv_mime_decode($overview[0]->subject, 0, 'UTF-8');

Et pour traiter les emoji qui font planter sur les champs varchar en BDD, il faut ajouter cette ligne ensuite :
$overview[0]->subject = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $overview[0]->subject);

Et voilà maintenant le sujet est bien décodé et utilisable sans provoquer d’erreur dans le traitement qui suit.

Et comme il faut faire la même chose concernant UTF8 / UTF8mb4 dans le « body » du mail :
Donc pour cela après la ligne :
$messagetext = $plainmsg ? $plainmsg : dol_string_nohtmltag($htmlmsg, 0);

Vous pouvez ajouter :
$messagetext = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $messagetext);

Voilà. Je ne suis (plus) un dev. J’ai passé du temps sur ce bout de code. Pour moi ça (semble) fonctionner. Il faudrait sans doute tester plus.
Je sais qu’il y a le git pour pousser des évol/modif. Je ne maitrise pas forcément, donc si quelqu’un veut reprendre cette suite, avec plaisir !

Merci et bon courage à tous avec le contexte.
Bertrand

2 « J'aime »

Hello,

je poste un complément car nouveau souci avec un emoji dans le sujet d’un email
ex :
sujet = « 📣 C’est le moment de se lancer »
résultat : erreur car ne fonctionne pas avec MySQL en UTF8 tel que dolibarr est. Il faudrait passer en UTF8mb4, j’ai rapidement trouvé un ticket sur github mais vieux et rien de neuf.

Donc pour contourner cela, en référence à https://stackoverflow.com/questions/8491431/how-to-replace-remove-4-byte-characters-from-a-utf-8-string-in-php
il faut ajouter une ligne :
$overview[0]->subject = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $overview[0]->subject);

J’édite mon post initial pour inclure cela

Forcément ces emojis ne passent pas non plus dans un champ de BDD texte … même erreur

Donc pour cela après la ligne :
$messagetext = $plainmsg ? $plainmsg : dol_string_nohtmltag($htmlmsg, 0);

Vous pouvez ajouter :
$messagetext = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $messagetext);

Quelqu’un pour m’aider à pousser ces infos pour la V12 qui est en cours de débug ? Sur github Dolibarr. Désolé de cette demande.
Ou sinon un lien pour m’expliquer comment faire (oui je pourrai chercher c’est vrai, mais en ce moment le temps est plus que limité, entre bosser, télétravailler, faire les cours aux enfants, …)

Bonjour,

En gros :
1 - crée un compte GitHub
2 - Faire un Fork de DOlibarr : https://help.github.com/en/github/getting-started-with-github/fork-a-repo
3 - Faire les modifications dans votre FOrk
4 - Pousser les modifications dans une PR : https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request

J’ai intégré les corrections par ce patch pour la v12

Par contre, le iconv_mime_decode, c’est bien en remplacement du imap_mime_header_decode (c’est l’un ou l’autre, et non en pus ?)

Salut Eldy,

désolé j’avais vu ton retour et puis j’ai pas traité de suite et puis … voilà !

Donc déjà un gros merci pour le push sur la v12.

Pour ta question sur iconv_mime_decode, j’avoue que mes compétences en dev remontent un peu ^^. Mais de ce que j’ai vu sur la doc PHP :
iconv_mime_decode — Décode un champ d’en‐tête MIME
imap_mime_header_decode — Décode les éléments MIME d’un en-tête

Donc là le besoin est bien de décoder le champ « sujet » du mail, donc besoin de iconv. imap_mime me semble donc inutile. Mais je n’ai pas fait le test