|
- using MailKit;
- using MailKit.Net.Imap;
- using MailKit.Search;
- using MailKit.Security;
- using MimeKit;
- using Services.ReActAgent;
- using System.Collections.ObjectModel;
- using System.Text;
- using System.Text.Json;
- using System.Text.Json.Serialization;
- using System.Text.RegularExpressions;
- using ToolsServices;
-
- namespace Services
- {
- public static class EmailService
- {
- public enum eTypeSensibilite
- {
- Ton,
- Posture,
- Couleur,
- NiveauDetail
- }
-
- #region Variables privées
-
- private static readonly string NomFichierParamsMail = FichiersInternesService.ParamsMail;// "paramsMail.txt";
- private static readonly string NomFichierMails = FichiersInternesService.ListeMails;// "listeMails.json";
- private static ObservableCollection<EmailMessage>? Emails;
- private static ReActAgent.ReActAgent _ReActAgent = new();
- #endregion
-
- #region Méthodes publiques
- public static List<string> LoadSensibilites(eTypeSensibilite eSensibilite)
- {
- LoggerService.LogInfo($"EmailService.LoadSensibilites : {eSensibilite}");
- var nomFile = "";
- var contenu = "";
- switch(eSensibilite)
- {
- case eTypeSensibilite.Ton:
- nomFile = FichiersInternesService.EmailsSensibiliteTon;
- contenu = "Formel;Professionnel neutre;Chaleureux / convivial;Urgent / alerte;Didactique / explicatif;Persuasif / engageant";
- break;
- case eTypeSensibilite.Posture:
- nomFile = FichiersInternesService.EmailsSensibilitePosture;
- contenu = "D’égal à égal;Hiérarchique (vers le haut ou vers le bas);De cadrage (donner des instructions, poser un cadre);De demandeur;De médiateur / facilitateur;D’alerte / vigilance;De soutien / collaboratif";
- break;
- case eTypeSensibilite.Couleur:
- nomFile = FichiersInternesService.EmailsSensibiliteCouleur;
- contenu = "Politesse (sobre → très formelle);Enthousiasme (positif, motivant);Gravité (sérieux, solennel);Humour (léger, complice);Sarcasme (ironique, risqué)";
- break;
- case eTypeSensibilite.NiveauDetail:
- nomFile = FichiersInternesService.EmailsSensibiliteNiveauDetail;
- contenu = "Simple et conçis;simple, objectif clair;structuré et nuancé;précision lexicale et stylistique;stratégie relationnelle autour du mail";
- break;
- }
- var lst = new List<string>();
- if (File.Exists(nomFile))
- {
- string[] lignes = File.ReadAllLines(nomFile);
- foreach (string line in lignes)
- {
- lst.Add(line);
- }
- }
- else
- {
- lst = new(contenu.Split(";").Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x)));
- SaveSensibilite(eSensibilite, lst);
- }
- return lst.OrderBy(x=>x).ToList();
- }
-
- public static bool SaveSensibilite(eTypeSensibilite eSensibilite, List<string> lst, string newSensibilite="")
- {
- LoggerService.LogInfo($"EmailService.SaveSensibilite : {eSensibilite}");
- try
- {
- var nomFile = "";
-
- switch (eSensibilite)
- {
- case eTypeSensibilite.Ton:
- nomFile = FichiersInternesService.EmailsSensibiliteTon;
- break;
- case eTypeSensibilite.Posture:
- nomFile = FichiersInternesService.EmailsSensibilitePosture;
- break;
- case eTypeSensibilite.Couleur:
- nomFile = FichiersInternesService.EmailsSensibiliteCouleur;
- break;
- case eTypeSensibilite.NiveauDetail:
- nomFile = FichiersInternesService.EmailsSensibiliteNiveauDetail;
- break;
- }
- StringBuilder sb = new();
- foreach (var s in lst)
- {
- if(s.Trim() != "")
- sb.AppendLine(s.Trim());
- }
- if (newSensibilite != "")
- {
- sb.AppendLine(newSensibilite.Trim());
- }
-
- var b = TxtService.CreateTextFile(nomFile, sb.ToString());
- if(!b)
- {
- LoggerService.LogError($"EmailService.SaveSensibilite : Erreur lors de la sauvegarde du fichier {nomFile}");
- return false;
- }
-
- return true;
- }
- catch (Exception ex)
- {
- LoggerService.LogError($"EmailService.SaveSensibilite : {ex.Message}");
- return false;
- }
- }
-
- public async static Task<CompteMailUser?> LoadParametresAsync()
- {
- var p = LoadParametres();
- await Task.Delay(1);
- return p;
- }
-
- public static CompteMailUser? LoadParametres()
- {
- LoggerService.LogInfo("EmailService.LoadParametres");
-
- CompteMailUser SelectedItem = new();
-
- try
- {
- if (File.Exists(NomFichierParamsMail))
- {
- SelectedItem.IsOk = true;
-
- string[] lignes = File.ReadAllLines(NomFichierParamsMail);
-
- if (lignes.Length > 0)
- SelectedItem.ServeurImap = DecryptData(lignes[0]);
-
- if (lignes.Length > 1)
- SelectedItem.ServeurImapPort = int.Parse(lignes[1]);
-
- if (lignes.Length > 2)
- SelectedItem.ServeurSmtp = DecryptData(lignes[2]);
-
- if (lignes.Length > 3)
- SelectedItem.ServeurSmtpPort = int.Parse(lignes[3]);
-
- if (lignes.Length > 4)
- SelectedItem.UserAdresse = DecryptData(lignes[4]);
-
- if (lignes.Length > 5)
- SelectedItem.UserMotPasse = DecryptData(lignes[5]);
-
- if (lignes.Length > 6)
- SelectedItem.UserNomPrenom = DecryptData(lignes[6]);
-
- if (lignes.Length > 7)
- SelectedItem.UserRole = DecryptData(lignes[7]);
-
- if (lignes.Length > 8)
- SelectedItem.UserEntreprise = DecryptData(lignes[8]);
-
- if (lignes.Length > 9)
- {
- if(int.TryParse(lignes[9], out int delay))
- SelectedItem.DelayRefresh = delay;
- }
-
- if (lignes.Length > 10)
- {
- if (int.TryParse(lignes[10], out int delaySentRefresh))
- SelectedItem.DelaySentRefresh = delaySentRefresh;
- }
-
- if (lignes.Length > 11)
- {
- if (int.TryParse(lignes[11], out int delaySentRecup))
- SelectedItem.DelaySentRecup = delaySentRecup;
- }
-
- if (lignes.Length > 12)
- {
- if (int.TryParse(lignes[12], out int overdueDaysSentRecup))
- SelectedItem.OverdueDaysSent = overdueDaysSentRecup;
- }
- }
- return SelectedItem;
-
- }
- catch
- {
- return null;
- }
- }
-
- public async static Task<bool> SaveParametresAsync(CompteMailUser selectedItem)
- {
- var b = SaveParametres(selectedItem);
- await Task.Delay(1);
- return b;
- }
-
- public static bool SaveParametres(CompteMailUser selectedItem)
- {
- LoggerService.LogInfo("EmailService.SaveParametres");
-
- try
- {
- StringBuilder sb = new();
-
- sb.AppendLine(EncryptData(selectedItem.ServeurImap));
- sb.AppendLine(selectedItem.ServeurImapPort.ToString());
- sb.AppendLine(EncryptData(selectedItem.ServeurSmtp));
- sb.AppendLine(selectedItem.ServeurSmtpPort.ToString());
- sb.AppendLine(EncryptData(selectedItem.UserAdresse));
- sb.AppendLine(EncryptData(selectedItem.UserMotPasse));
-
- sb.AppendLine(EncryptData(selectedItem.UserNomPrenom));
- sb.AppendLine(EncryptData(selectedItem.UserRole));
- sb.AppendLine(EncryptData(selectedItem.UserEntreprise));
-
- sb.AppendLine(selectedItem.DelayRefresh.ToString());
-
- sb.AppendLine(selectedItem.DelaySentRefresh.ToString());
- sb.AppendLine(selectedItem.DelaySentRecup.ToString());
- sb.AppendLine(selectedItem.OverdueDaysSent.ToString());
-
- File.WriteAllText(NomFichierParamsMail, sb.ToString());
- selectedItem.IsOk = true;
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- public static async Task<ObservableCollection<EmailMessage>?> LireEmailsAsync(ObservableCollection<EmailMessage>? emails)
- {
- LoggerService.LogInfo("EmailService.LireEmailsAsync");
-
- Emails = emails;
- CompteMailUser? CompteMail = LoadParametres();
- if (CompteMail == null)
- {
- return null;
- }
- return await LoadUnreadEmailsAsync(CompteMail.UserAdresse, CompteMail.UserMotPasse, CompteMail.ServeurImap, CompteMail.ServeurImapPort, CompteMail.UserAdresse);
- }
-
- public static async Task<bool> EnvoyerMailAsync(MailKit.UniqueId? id, string destinataire, string sujet, string messageTexte, bool isReponse, string messageOrigineid, string destinataireCc="")
- {
- LoggerService.LogInfo("EmailService.EnvoyerReponseAsync");
-
- try
- {
- CompteMailUser? CompteMail = LoadParametres();
- if (CompteMail == null)
- {
- return false;
- }
- var message = new MimeMessage();
- message.From.Add(MailboxAddress.Parse(CompteMail.UserAdresse)); // expéditeur
-
- var dests = destinataire.Split(';');
- foreach (var dest in dests)
- {
- message.To.Add(MailboxAddress.Parse(dest));
- }
-
- if (destinataireCc != "")
- {
- var destsCc = destinataireCc.Split(';');
- foreach (var dest in destsCc)
- {
- message.Cc.Add(MailboxAddress.Parse(dest));
- }
- }
-
- message.Subject = (isReponse & !sujet.StartsWith("RE:", StringComparison.CurrentCultureIgnoreCase) ? "RE: " + sujet : sujet);
- if(isReponse)
- {
- message.InReplyTo = messageOrigineid;
- }
-
- // Version texte brut (fallback)
- var plainText = new TextPart("plain")
- {
- Text = messageTexte
- };
-
- // Version HTML avec police Calibri et taille 12pt
- // on remplace les sauts de ligne par des paragraphes <p>
- var htmlParagraphs = string.Join("",
- messageTexte
- .Split('\n')
- .Where(line => !string.IsNullOrWhiteSpace(line))
- .Select(line => $"<p>{System.Net.WebUtility.HtmlEncode(line)}</p>")
- );
- /*
- string signatureHtml = @"
- <hr>
- <table style=""width: 250px;"">
- <tbody>
- <tr>
- <td style=""width: 96px; text-align: center;border-right-style: solid;border-right-width: 0px;padding-right: 20px;"">
- <img src=""data:image/png;base64,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"" alt=""All In IT"" style=""width: 96px; height: 80px;"">
- </td>
- <td style=""font-size: 14px; line-height: 1.3;padding-left: 15px;border-left-style: solid;border-left-width: 2px;font-family: Helvetica, sans-serif;white-space: nowrap;"">
- <h1 style=""margin: 0; font-size: 16px;"">Guillaume TOPENOT</h1>
- <p style=""margin: 0;color: #666;"">Manager</p>
- <p style=""margin: 0;""><a href=""""></a></p>
- </td>
- </tr>
- </tbody>
- </table>";
- */
- string signatureHtml = "";
- var htmlText = new TextPart("html")
- {
- Text = $"<html><body style='font-family: Calibri, sans-serif; font-size: 12pt;'>{htmlParagraphs+signatureHtml}</body></html>"
- };
-
- // Regroupe les deux versions (plain + html)
- var alternative = new MultipartAlternative();
- alternative.Add(plainText);
- alternative.Add(htmlText);
-
- // Ajoute au message
- message.Body = alternative;
-
- // --- Envoi via SMTP ---
- using var smtp = new MailKit.Net.Smtp.SmtpClient();
- await smtp.ConnectAsync(CompteMail.ServeurSmtp, CompteMail.ServeurSmtpPort, SecureSocketOptions.StartTls);
- await smtp.AuthenticateAsync(CompteMail.UserAdresse, CompteMail.UserMotPasse);
- await smtp.SendAsync(message);
- await smtp.DisconnectAsync(true);
-
- if (id != null)
- {
- var Id = (MailKit.UniqueId)id;
- await MarquerMessageCommeLu(Id, CompteMail.UserAdresse, CompteMail.UserMotPasse, CompteMail.ServeurImap, CompteMail.ServeurImapPort);
- }
-
- // --- Sauvegarde dans "Sent" via IMAP ---
- using var imap = new MailKit.Net.Imap.ImapClient();
- await imap.ConnectAsync(CompteMail.ServeurImap, CompteMail.ServeurImapPort, SecureSocketOptions.SslOnConnect);
- await imap.AuthenticateAsync(CompteMail.UserAdresse, CompteMail.UserMotPasse);
-
- // Accès à la boîte aux lettres personnelle (root)
- var personal = imap.GetFolder(imap.PersonalNamespaces[0]);
-
- // Récupérer le dossier "Sent"
- var sentFolder = await personal.GetSubfolderAsync("Sent");
-
- // Si ça ne marche pas (par exemple dossier en français "Envoyés") :
- if (sentFolder == null || !sentFolder.Exists)
- {
- var allFolders = await personal.GetSubfoldersAsync(false);
- sentFolder = allFolders.FirstOrDefault(f => f.Name.Equals("Sent", StringComparison.OrdinalIgnoreCase)
- || f.Name.Equals("Envoyés", StringComparison.OrdinalIgnoreCase));
- }
-
- // Si on a bien trouvé un dossier "Sent" ou équivalent
- if (sentFolder != null)
- {
- await sentFolder.OpenAsync(FolderAccess.ReadWrite);
- await sentFolder.AppendAsync(message, MessageFlags.Seen);
- }
-
- LoggerService.LogDebug("Réponse par mail envoyée.");
- return true;
- }
- catch (Exception ex)
- {
- LoggerService.LogError(ex.ToString());
- return false;
- }
- }
-
- public static async Task<bool> MaquerLu(MailKit.UniqueId? id)
- {
- LoggerService.LogInfo("EmailService.MaquerLu");
-
- CompteMailUser? CompteMail = LoadParametres();
- if (CompteMail == null)
- {
- return false;
- }
- var b = await MarquerMessageCommeLu(id, CompteMail.UserAdresse, CompteMail.UserMotPasse, CompteMail.ServeurImap, CompteMail.ServeurImapPort);
- return b;
- }
-
- public static async Task<bool> SauvegarderReponseEmails(EmailMessage item)
- {
- try
- {
- LoggerService.LogInfo("EmailService.SauvegarderReponseEmails");
- await Task.Delay(1);
- if (!File.Exists(NomFichierMails))
- return false;
-
- using FileStream fs = File.OpenRead(NomFichierMails);
- var items = JsonSerializer.Deserialize<ObservableCollection<EmailMessage>>(fs);
- fs.Close();
- if (items == null)
- {
- return false;
- }
-
- var mail = items.FirstOrDefault(m => m.UidString == item.UidString);
- if (mail != null)
- {
- mail.Reponse = item.Reponse;
- var options = new JsonSerializerOptions { WriteIndented = true };
- File.WriteAllText(NomFichierMails, JsonSerializer.Serialize(items, options));
- }
-
- return true;
- }
- catch (Exception ex)
- {
- LoggerService.LogError($"{ex.Message}");
- return false;
- }
- }
-
- public static void SauvegarderEmails(ObservableCollection<EmailMessage> ListeItems)
- {
- try
- {
- LoggerService.LogInfo("EmailService.SauvegarderEmailsAsync");
-
- if (ListeItems == null)
- return;
-
- var options = new JsonSerializerOptions
- {
- WriteIndented = true,
- // Ignore les propriétés non sérialisables comme UniqueId si nécessaire
- IgnoreReadOnlyProperties = false,
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
- };
-
- if (File.Exists(NomFichierMails))
- File.Delete(NomFichierMails);
- using FileStream fs = File.Create(NomFichierMails);
- JsonSerializer.Serialize(fs, ListeItems, options);
- }
- catch (Exception ex)
- {
- LoggerService.LogError(ex.Message);
- }
- }
-
- public static ObservableCollection<EmailMessage> ChargerEmailsDepuisJson()
- {
- LoggerService.LogInfo("EmailService.ChargerEmailsDepuisJsonAsync");
-
- if (!File.Exists(NomFichierMails))
- return new ObservableCollection<EmailMessage>();
-
- using FileStream fs = File.OpenRead(NomFichierMails);
- var items = JsonSerializer.Deserialize<ObservableCollection<EmailMessage>>(fs);
-
- if (items == null)
- {
- return new ObservableCollection<EmailMessage>();
- }
- return items;
- }
-
- public static async Task<string> SeekByKeyWord(string RechercheString)
- {
- LoggerService.LogInfo("EmailService.SeekByKeyWord");
- var adressEmail = LoadParametres()?.UserAdresse ?? "";
- return await RAGService.Search(Domain.Emails, RechercheString, adressEmail);
- }
-
- public static bool SaveParametresCheckEmail(int val1, int val2)
- {
- try
- {
- StringBuilder sb = new();
- sb.AppendLine(val1.ToString());
- sb.AppendLine(val2.ToString());
-
- File.WriteAllText(FichiersInternesService.ParamsLancerCheckMails, sb.ToString());
- return true;
- }
- catch (Exception ex)
- {
- LoggerService.LogError($"EmailService.SaveParametresCheckEmail Erreur : {ex.Message}");
- return false;
- }
- }
-
- public static (int, int) LoadParametresCheckEmail()
- {
- try
- {
- int val1 = 0;
- int val2 = 0;
- if (File.Exists(FichiersInternesService.ParamsLancerCheckMails))
- {
- string[] lignes = File.ReadAllLines(FichiersInternesService.ParamsLancerCheckMails);
-
- if (lignes.Length > 0)
- val1 = int.Parse(lignes[0]);
-
- if (lignes.Length > 1)
- val2 = int.Parse(lignes[1]);
-
- }
- return (val1,val2);
- }
- catch (Exception ex)
- {
- LoggerService.LogError($"EmailService.SaveParametresCheckEmail Erreur : {ex.Message}");
- return (0,0);
- }
- }
-
- public static async Task<(bool, string)> GenererMailAsync(string context, string query)
- {
- LoggerService.LogInfo($"EmailService.GenererMailAsync");
- var paramUser = LoadParametres();
- var prompt = PromptService.GetPrompt(PromptService.ePrompt.EmailService_Generer_Mail, query, context, paramUser!.UserNomPrenom, paramUser!.UserRole, paramUser!.UserEntreprise);
- LoggerService.LogDebug($"Prompt : {prompt}");
-
- var (textMail, m) = await _ReActAgent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.GenerationMail, true, prompt, "Génération d'email");
- LoggerService.LogDebug($"EmailService.GenererMailAsync : Modele : '{m}'\nMail généré : {textMail}");
- var b = textMail.Contains("Error", StringComparison.OrdinalIgnoreCase) || textMail.Contains("Exception", StringComparison.OrdinalIgnoreCase);
- return (!b, textMail);
- }
-
- #endregion
-
- #region Méthodes privées
-
- private static string EncryptData(string clairString)
- {
- LoggerService.LogDebug("EmailService.EncryptData");
- return CryptageService.EncryptData(clairString);
-
- }
-
- private static string DecryptData(string encryptedString)
- {
- LoggerService.LogDebug("EmailService.DecryptData");
- return CryptageService.DecryptData(encryptedString);
-
- }
-
- private static async Task<ObservableCollection<EmailMessage>> LoadUnreadEmailsAsync(string email, string password, string imapServer, int port, string proprietaire)
- {
- LoggerService.LogInfo("EmailService.LoadUnreadEmailsAsync");
-
- var messages = new ObservableCollection<EmailMessage>();
-
- using var client = new ImapClient();
- await client.ConnectAsync(imapServer, port, SecureSocketOptions.SslOnConnect);
- await client.AuthenticateAsync(email, password);
-
- var inbox = client.Inbox;
- await inbox.OpenAsync(FolderAccess.ReadOnly);
-
- var uids = await inbox.SearchAsync(SearchQuery.NotSeen);
- if(Emails != null && Emails.Count > 0)
- {
- foreach (var mail in Emails)
- {
- bool isAbsentDansInbox = false;
- if (Emails != null)
- {
- isAbsentDansInbox = !uids.Any(e => e == mail.Uid);
- if(isAbsentDansInbox)
- {
- // Si l'email n'est pas dans la liste des non lus, on le marque pour suppression
- mail.ToRemove = true; ;
- }
- }
- }
- }
-
-
- foreach (var uid in uids)
- {
- bool isExistDansListe = false;
- if (Emails != null)
- {
- isExistDansListe = Emails.Any(e => e.Uid == uid);
- }
-
- if (!isExistDansListe)
- {
- var message = await inbox.GetMessageAsync(uid);
-
- EmailMessage msg = (new EmailMessage
- {
- Uid = uid,
- Id = message.MessageId,
- To = string.Join(";", message.To.Mailboxes.Select(e => e.Address).ToList()),
- Cc = string.Join(";", message.Cc.Mailboxes.Select(e => e.Address).ToList()),
- FromName = message.From.Mailboxes.FirstOrDefault()?.Name ?? "",
- From = message.From.Mailboxes.FirstOrDefault()?.Address ?? "",
- Subject = message.Subject,
- Date = message.Date.DateTime,
- Preview = message.TextBody?.Substring(0, Math.Min(200, message.TextBody.Length)) ?? "",
- TextBody = message.TextBody != null ? message.TextBody : "",
- TextBodyHTML = message.HtmlBody != null ? message.HtmlBody : "",
- InReplyTo = message.InReplyTo,
- IsDestinatairePrincipal = string.Join(";", message.To.Mailboxes.Select(e => e.Address).ToList()).Contains(email, StringComparison.OrdinalIgnoreCase)
-
- });
-
- if(msg.TextBody == "" && message.HtmlBody != null)
- {
- msg.TextBody = HtmlToPlainText(message.HtmlBody);
- }
-
- // Ici, on vectorize et stocke le message
- var identiteMessage = $"Du {msg.Date.ToString("dd/MM/yyyy hh:mm")} - De {msg.From} - Sujet : {msg.Subject}";
- if (message.TextBody != null && message.TextBody != "")
- {
- await RAGService.IngestDocument(Domain.Emails,false, false, msg.TextBody, identiteMessage, msg.Subject,proprietaire);
- }
-
-
- if (message.Attachments != null && message.Attachments.Any())
- {
- msg.ContentPJ = new();
- var listFullText = await ExtractAndSummarizeAttachments(message, identiteMessage);
-
- if (listFullText != null && listFullText.Count > 0)
- {
- msg.ContentPJ = listFullText;
- }
- }
-
-
- // Analyse du message par modele
- msg = await AnalyserMail(msg);
-
- messages.Add(msg);
- }
- }
-
- await client.DisconnectAsync(true);
- return messages;
- }
-
- private static async Task<string> TraitementPJ(string fullFilename,string filename, ReActAgent.ReActAgent reActRagAgent, string identiteMessage)
- {
- LoggerService.LogInfo("EmailService.TraitementPJ");
-
- string sReturn = "";
-
- string extractedText = FilesService.ExtractText(fullFilename);
- if (!string.IsNullOrWhiteSpace(extractedText))
- {
- //reActRagAgent.IngestDocument(extractedText, filename, identiteMessage);
- var chunks = Services.RAGService.ChunkText(extractedText);
- var (summary, model) = await reActRagAgent.SummarizeDocAsync("Résumé de PJ", chunks, false);
-
- sReturn = $"📎 {filename} :\n{summary}";
- LoggerService.LogDebug($"{model} \t {summary}");
- }
- else
- {
- sReturn = $"📎 {filename} :\n Fichier illisible... ";
- }
-
- return sReturn;
-
- }
-
- private static async Task<List<string>> ExtractAndSummarizeAttachments(MimeMessage message, string identiteMessage)
- {
- LoggerService.LogInfo("EmailService.ExtractAndSummarizeAttachments");
-
- var reActRagAgent = new Services.ReActAgent.ReActAgent();
- var summaries = new List<string>();
-
- foreach (var attachment in message.Attachments)
- {
- if (attachment is MimePart part)
- {
- var fileName = part.FileName ?? "piece_jointe.xxx";
- var extension = Path.GetExtension(fileName).ToLowerInvariant();
- var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + "_" + fileName);
-
- LoggerService.LogInfo($"Traitement de la pièce jointe : {fileName}");
- using (var stream = File.Create(tempPath))
- await part.Content.DecodeToAsync(stream);
-
- if (FilesService.IsExtensionSupport(extension))
- {
- summaries.Add(await TraitementPJ(tempPath, fileName, reActRagAgent, identiteMessage));
- }
- else if (extension == ".zip")
- {
- var extractDir = Path.Combine(Path.GetTempPath(), "zip_" + Guid.NewGuid());
- Directory.CreateDirectory(extractDir);
-
- System.IO.Compression.ZipFile.ExtractToDirectory(tempPath, extractDir);
- foreach (var innerFile in Directory.GetFiles(extractDir, "*.*", SearchOption.AllDirectories))
- {
- var filenameInZip = Path.GetFileName(innerFile);
- LoggerService.LogInfo($"Traitement de la pièce jointe dans {fileName} : {filenameInZip}");
-
- try
- {
- var ext = Path.GetExtension(innerFile).ToLowerInvariant();
-
- if (FilesService.IsExtensionSupport(ext))
- {
- summaries.Add(await TraitementPJ(innerFile, filenameInZip, reActRagAgent, identiteMessage));
- }
- else
- {
- summaries.Add($"📎 {filenameInZip} :\n Format de fichier non pris en charge... ");
- }
- }
- catch
- {
- summaries.Add($"📎 {filenameInZip} :\n Fichier illisible... ");
- }
- }
-
- Directory.Delete(extractDir, true);
- }
- else
- {
- summaries.Add($"📎 {fileName} :\n Format de fichier non pris en charge... ");
- }
-
- File.Delete(tempPath);
-
- }
-
- }
-
- return summaries;
- }
-
- private static string HtmlToPlainText(string html)
- {
- LoggerService.LogInfo("EmailService.HtmlToPlainText");
-
- return System.Text.RegularExpressions.Regex.Replace(html, "<.*?>", string.Empty);
- }
-
- private static async Task<EmailMessage> AnalyserMail(EmailMessage email)
- {
- try
- {
- LoggerService.LogInfo($"EmailService.AnalyserMail : '{email.Subject}'");
-
- #region MAJ du modèle IA
- email.ModeleIA = ReActAgent.ReActAgent.GetModeleIA(ModelsUseCases.TypeUseCase.AnalyseMails);
- LoggerService.LogInfo($"Modèle utilisé : {email.ModeleIA}");
- #endregion
-
- #region Résumé
- bool isPromptInjection = false;
- string messagePromptInjection = "";
- var subject = _ReActAgent.CleanUserInput(email.Subject, out isPromptInjection);
- if (isPromptInjection)
- {
- messagePromptInjection += "Le sujet de l'email contient des éléments suspects.\n";
- email.PresenceSuspecte = true;
- }
- var textBody = _ReActAgent.CleanUserInput(email.TextBody, out isPromptInjection);
- if (isPromptInjection)
- {
- messagePromptInjection = "Le corps de l'email contient des éléments suspects.\n";
- email.PresenceSuspecte = true;
- }
- /*
- var promptResume = $@"
- Tu es un assistant professionnel chargé d'analyser un e-mail.
- Lis le contenu suivant et fais un résumé clair et concis.
-
- Ensuite, indique explicitement :
- - Une note d'importance entre 0 et 5 (5 étant la plus haute importance) avec justification si possible
- - Une note d'urgence entre 0 et 5 (5 étant la plus haute importance) avec justification si possible
-
- Format de réponse attendu :
- Résumé : ...
-
- Importance (0-5) : ...
- Urgence (0-5) : ...
-
- Objet : {subject}
- Contenu : {textBody}";
- */
- var promptResume = PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Resume, subject, textBody);
-
- if (email.IsPJ)
- {
- var contentPJ = _ReActAgent.CleanUserInput(email.ContentPJ_STR, out isPromptInjection); ;
- //promptResume += $"\n\n Inclus dans le résumé l'analyse des pièces jointes dont voici le résumé : {contentPJ}";
- promptResume += $"\n\n" + PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Resume_PJ, contentPJ);
-
- if (isPromptInjection)
- {
- messagePromptInjection += "Le contenu des pièces jointes contient des éléments suspects.\n";
- email.PresenceSuspecte = true;
- }
- }
-
- LoggerService.LogDebug($"Génération Résumé de : '{email.Subject}'");
- var (resume, m1) = await _ReActAgent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.AnalyseMails, false, promptResume, "Résumé d'email");
- email.Resume = messagePromptInjection + resume;
-
- var (important, urgent, importanceScore, urgenceScore, analyse) = ExtrairePriorites(resume);
- email.IsImportant = important;
- email.IsUrgent = urgent;
- email.ImportanceScore = importanceScore;
- email.UrgenceScore = urgenceScore;
- email.Analyse = analyse;
- #endregion
-
- #region Catégorie
- /*
- var promptCategorie = $@"
- Tu dois catégoriser un email en fonction de son contenu.
- Voici le résumé de l'email :
- {resume}
-
- Catégorise ce message parmi les choix suivants :
- - Demande d'information
- - Réclamation
- - Demande de devis
- - Problème technique
- - Autre
- Réponds uniquement par une des catégories listées.";
- */
- var promptCategorie = PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Categorie, resume);
- LoggerService.LogInfo($"Génération Catégorie de : '{email.Subject}'");
- var (categorie,m2) = await _ReActAgent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.AnalyseMails, false, promptCategorie, "Catégorie d'email");
- email.Categorie = categorie;
- #endregion
-
- #region Stratégie
- /*
- var promptStrategie = $@"
- Tu dois choisir une stratégie de réponse à un email.
-
- Catégorie : {categorie}
- Important : {(important ? "oui" : "non")}
- Urgent : {(urgent ? "oui" : "non")}
-
- Voici les options possibles :
- - Répondre avec une explication simple
- - Demander plus d'informations
- - Présenter des excuses et proposer une solution
- - Accuser réception et informer d'un délai
-
- Choisis la stratégie la plus adaptée en tenant compte de la **catégorie**, de l'**importance** et de l'**urgence**.";
- */
- var promptStrategie = PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Strategie, categorie, (important ? "oui" : "non"), (urgent ? "oui" : "non"));
- LoggerService.LogInfo($"Génération Stratégie de : '{email.Subject}'");
- var (strategie, m3) = await _ReActAgent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.AnalyseMails, false, promptStrategie, "Stratégie d'email");
- email.Strategie = strategie;
- #endregion
-
- #region Réponse proposée
- var paramUser = LoadParametres();
- /*
- var promptReponse = $@"
- Rédige une réponse professionnelle à cet email en suivant la stratégie définie.
-
- Objet : {email.Subject}
- Contenu : {email.TextBody}
- Résumé : {resume}
- Catégorie : {categorie}
- Stratégie : {strategie}
-
- La réponse doit être claire, polie, adaptée au contexte et suffisamment concise.
- Voici la signature à insérer en fin de mail :
- Cordialement,
- {paramUser!.UserNomPrenom}
- {paramUser!.UserRole}
- {paramUser!.UserEntreprise}";
- */
- var promptReponse = PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Reponse, email.Subject, email.TextBody, resume, categorie, strategie, paramUser!.UserNomPrenom, paramUser!.UserRole, paramUser!.UserEntreprise);
- if (email.IsPJ)
- {
- //promptReponse += $"\n\n Inclus dans la réponse proposée l'analyse des pièces jointes dont voici le résumé : {email.ContentPJ_STR}";
- promptReponse += $"\n\n" + PromptService.GetPrompt(PromptService.ePrompt.EmailService_AnalyserMail_Reponse_PJ, email.ContentPJ_STR);
-
- }
-
- LoggerService.LogInfo($"Génération Réponse proposée de : '{email.Subject}'");
- var (reponse,m4) = await _ReActAgent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.AnalyseMails, false, promptReponse, "Réponse proposée d'email");
- email.Reponse = reponse;
- #endregion
-
- LoggerService.LogInfo($"Analyse d'un mail terminée : '{email.Subject}'");
- return email;
- }
- catch (Exception ex)
- {
- LoggerService.LogError($"Erreur lors de l'analyse du mail '{email.Subject}': {ex.Message}");
- email.Reponse = "Une erreur est survenue lors de l'analyse de cet email.";
- return email;
-
- }
- }
-
- private static (bool important, bool urgent, int importanceScore, int urgenceScore, string analyse) ExtrairePriorites(string resume)
- {
- LoggerService.LogInfo("EmailService.ExtrairePriorites");
-
- //var important = resume.Contains("Important : oui", StringComparison.OrdinalIgnoreCase);
- //var urgent = resume.Contains("Urgent : oui", StringComparison.OrdinalIgnoreCase);
-
- int importanceScore = ExtraireScore(resume, "Importance");
- int urgenceScore = ExtraireScore(resume, "Urgence");
- string analyse = ExtraireAnalyse(resume, "Analyse");
-
- var important = (importanceScore > 2);
- var urgent = (urgenceScore > 2);
-
- return (important, urgent, importanceScore, urgenceScore, analyse);
- }
-
- private static int ExtraireScore(string texte, string motCle)
- {
- LoggerService.LogInfo("EmailService.ExtraireScore");
-
- // Cette regex gère :
- // - "Importance (0-5) : 4"
- // - "Importance (0-5):4"
- // - "Importance (4/5) : ..."
- // - "Importance: 4/5"
- // - avec ou sans espaces
-
- var pattern = $@"{motCle}\s*(?:\(\s*0\s*[--–—]\s*5\s*\)\s*:?\s*(\d)|\(\s*(\d)\s*/\s*5\s*\)|:?\s*(\d)\s*/\s*5)";
- var match = System.Text.RegularExpressions.Regex.Match(texte, pattern, RegexOptions.IgnoreCase);
-
- if (match.Success)
- {
- // On prend le premier groupe non vide (selon le format rencontré)
- for (int i = 1; i < match.Groups.Count; i++)
- {
- if (match.Groups[i].Success)
- return int.Parse(match.Groups[i].Value);
- }
- }
-
- return 0;
- }
-
- private static string ExtraireAnalyse(string texte, string motCle)
- {
- if (string.IsNullOrWhiteSpace(texte) || string.IsNullOrWhiteSpace(motCle))
- return string.Empty;
-
- // Échappe le mot-clé pour éviter les problèmes si motCle contient des caractères regex spéciaux
- var escaped = Regex.Escape(motCle);
-
- // 1) Pattern principal : capture un mot (lettres Unicode, -, +) juste après "Analyse :"
- var pattern = $@"\b{escaped}\s*:\s*([\p{{L}}\-+]+)";
- var match = Regex.Match(texte, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
-
- if (match.Success)
- return match.Groups[1].Value; // "Neutre"
-
- // 2) Fallback : capture la portion jusqu'à la fin de la ligne ou jusqu'à une ponctuation,
- // puis on prend le premier token (au cas où il y aurait du texte additionnel sur la même ligne)
- pattern = $@"\b{escaped}\s*:\s*([^\r\n\.\,\;\:\!\?]+)";
- match = Regex.Match(texte, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
-
- if (match.Success)
- {
- var s = match.Groups[1].Value.Trim();
- var first = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
- return first.Length > 0 ? first[0] : string.Empty;
- }
-
- return string.Empty;
- }
-
- private static async Task<bool> MarquerMessageCommeLu(MailKit.UniqueId? id, string email, string password, string imapServer, int port)
- {
- LoggerService.LogInfo("EmailService.MarquerMessageCommeLu");
-
- try
- {
- using var client = new ImapClient();
- await client.ConnectAsync(imapServer, port, SecureSocketOptions.SslOnConnect);
- await client.AuthenticateAsync(email, password);
-
- var inbox = client.Inbox;
- await inbox.OpenAsync(FolderAccess.ReadWrite);
-
- if(id.HasValue) // Marque comme lu
- await inbox.AddFlagsAsync(id.Value, MessageFlags.Seen, true); // Marque comme lu
-
- await client.DisconnectAsync(true);
-
- await Task.Delay(1);
- LoggerService.LogInfo("Mail marqué comme 'lu'");
- return true;
- }
- catch (Exception ex)
- {
- LoggerService.LogError(ex.ToString());
- return false;
- }
- }
-
- #endregion
-
- #region Conservés pour la culture
-
- private static async Task<MimeMessage?> GetLastUnreadEmailAsync(string email, string password, string imapServer, int port = 993)
- {
- using var client = new ImapClient();
- await client.ConnectAsync(imapServer, port, SecureSocketOptions.SslOnConnect);
- await client.AuthenticateAsync(email, password);
-
- var inbox = client.Inbox;
- await inbox.OpenAsync(MailKit.FolderAccess.ReadOnly);
-
- // Récupère tous les messages non lus
- var uids = await inbox.SearchAsync(SearchQuery.NotSeen);
- if (!uids.Any()) return null;
-
- // On prend le dernier non lu
- var lastUnread = uids.Last();
- var message = await inbox.GetMessageAsync(lastUnread);
-
- await client.DisconnectAsync(true);
- return message;
- }
-
- private static async Task<MimeMessage> LireDernierEmailAsync(string email, string password, string imapServer, int port = 993)
- {
- using var client = new ImapClient();
- await client.ConnectAsync(imapServer, port, SecureSocketOptions.SslOnConnect);
- await client.AuthenticateAsync(email, password);
-
- var inbox = client.Inbox;
- await inbox.OpenAsync(MailKit.FolderAccess.ReadOnly);
- var message = await inbox.GetMessageAsync(inbox.Count - 1);
- await client.DisconnectAsync(true);
- return message;
- }
-
-
- #endregion
- }
- }
|