2013-04-02 2 views
3

Je travaille sur un logiciel dans lequel je peux récupérer la boîte de réception et envoyer des éléments depuis Outlook. Ce que je veux faire est de relier les email de boîte de réception avec des réponses (si quelqu'un a envoyé une réponse à cet email). La liste doit être affichée dans cet ordreC# Outlook concernant la boîte de réception et les éléments envoyés

[email protected] Sujet entrant reçu temps [email protected] Répondre Sujet temps Envoyé

Qu'est-ce que je prévois de faire est de récupérer les éléments de la boîte de réception dans un datatable et les éléments envoyés dans un autre datatable. Il lit les courriels un par un sur la base du courrier électronique de l'expéditeur et du sujet, puis il recherche l'expéditeur et le courrier électronique dans les éléments envoyés et, s'il correspond, fusionne ce dernier avec un troisième élément de données.

Y a-t-il une autre meilleure façon de le faire?

Voici le code:

private DataTable GetInboxItems() 

    { 
     DataTable inboxTable; 
     //try 
     //{ 
     filter = "[ReceivedTime] >= '" + dtpStartDate.Value.ToString("dd/MM/yyyy 12:00 AM") + "' and [ReceivedTime] <= '" + dtpEndDate.Value.ToString("dd/MM/yyyy 11:59 PM") + "'"; 
     Outlook.Application outlookApp = GetApplicationObject(); 
     Outlook.Folder root = outlookApp.Session.DefaultStore.GetRootFolder() as Outlook.Folder; 
     EnumerateFolders(root); 
     //string filter = "[ReceivedTime] > '" + dtpStartDate.Value.ToString("dd/MM/yyyy") + "'"; 

     //inbox 
     Outlook.MAPIFolder inboxFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); 
     inboxTable = CreateTable(); 
     int count = 0; 


     if (inboxFolder.Items.Count > 0) 
     { 

      var restrictedItems = inboxFolder.Items.Restrict(filter); 
      restrictedItems.Sort("[ReceivedTime]", true); //descending 
      //foreach (var item in inboxFolder.Items) 
      foreach (var item in restrictedItems) 
      { 
       var mail = item as Outlook.MailItem; 
       if (mail != null) 
       { 
        //try 
        //{ 
        DataRow row = inboxTable.NewRow(); 
        //row["sn"] = (++count).ToString(); 
        row["sn"] = mail.EntryID + " " + mail.ReceivedByEntryID; 
        row["MailType"] = "Inbox"; 
        row["SenderName"] = mail.SenderName; 
        row["SenderEmail"] = mail.SenderEmailAddress; 
        row["ReceivedDate"] = mail.ReceivedTime; 
        row["Subject"] = mail.Subject; 
        row["Body"] = mail.Body != null ? (mail.Body.Length > 25 ? mail.Body.Substring(0, 25) : mail.Body) : null; 
        //row["Body"] = mail.Body != null ? mail.Body : ""; 
        row["MailSize"] = mail.Size.ToString(); 
        string attachments = null; 
        if (mail.Attachments.Count > 0) 
        { 
         foreach (var attachment in mail.Attachments) 
         { 
          if (((Outlook.Attachment)attachment) != null) 
           //attachments = ((Outlook.Attachment)attachment).FileName + " " + ((Outlook.Attachment)attachment).Size.ToString() + ", "; 
           attachments += (((Outlook.Attachment)attachment).Size/1024).ToString() + " KB, "; 
         } 
        } 


        row["AttachmentCount"] = mail.Attachments.Count; 
        if (attachments != null) 
         row["AttachmentSize"] = attachments.Substring(0, attachments.Length - 2); 

        inboxTable.Rows.Add(row); 
       } 
       //catch (Exception ex) 
       //{ 

       // return null; 
       //} 

      } 
     } 

     return inboxTable; 
    } 
+0

Qu'est-ce qui vous fait penser que votre code de travail n'est pas le meilleur moyen? –

+0

Je crois qu'il doit y avoir une certaine option pour relier la boîte de réception et les éléments envoyés au lieu de les trier par sujet et en ignorant le "Re:" ou un autre préfixe, puis les fusionner à une troisième datatable. – newbie

+0

Il existe une propriété ConversationID mais elle n'est pas exacte à 100%. – Arthur

Répondre

0

J'ai fait ce genre de choses dans une perspective add-in

Il n'y a aucun moyen de 100% pour le rendre ...
Le problème est que l'ID de conversation n'est pas toujours conservé par un autre logiciel. Vous devez donc utiliser un ensemble de données pour lier les courriels à leurs réponses:
- Message-ID: ceci est disponible dans les en-têtes des courriels. Éléments envoyés n'ont pas ceci:/
- In-Reply-To: cela est aussi dans les en-têtes de courrier électronique
- Sujet ID

Pour l'ID de rubrique, je récupère les valeurs dans cet ordre (je prends le premier disponible):
- MailItem.ConversationIndex: Chaque réponse ajouter octets à l'index de conversation
- tête de référence

Puis, je créer un lien e-mail à leur réponse à l'aide topicID, email ont les mêmes premiers caractères X que la réponse. Exemple sujet de courriel original id = abc, réponse = abcdef Pour tous les mails que ne peut pas être lié à l'aide id de conversation, j'essaie de lier l'aide Message-ID & In-Reply-To ID

problème vient notamment de courrier électronique envoyé par Outlook (pas d'identificateur de message), puis réponse de l'utilisateur sans en-tête Reference/ConversationIndex ... vous n'aurez aucun moyen de lier les deux messages ensemble.

Hope it helps

EDIT: Voici un code. J'ai copié/collé le code d'une classe/méthode différente pour créer une seule méthode, donc il ne peut pas compiler. Prenez-le plus comme un pseudo-code.

public SimpleTree<MailData> CreateTree(List<MailData> mails) 
{ 
    mails.Sort((m1, m2) => m1.TopicId == m2.TopicId ? m2.CreationDate.CompareTo(m1.CreationDate) : m1.TopicId.CompareTo(m2.TopicId)); 

    var tree = new SimpleTree<MailData>(); 

    var i = 0; 
    while (i < mails.Count) 
    { 
     var node = tree.Children.Add(mails[i]); 
     var topicId = mails[i].TopicId; 
     var start = i + 1; 
     while (start < mails.Count 
      && !string.IsNullOrEmpty(topicId) 
      && !string.IsNullOrEmpty(mails[start].TopicId) 
      && mails[start].TopicId.StartsWith(topicId)) 
     { 
      node.Children.Add(mails[start]); 
      start++; 
     } 
     i = start; 
    } 

    // Handle email where TopicId are different, but ParentId is filled with correct value 
    for (int j = tree.Children.Count - 1; j >= 0; j--) 
    { 
     var child = tree.Children[j]; 
     if (child.Children.Count == 0 && !string.IsNullOrEmpty(child.Value.ParentId)) 
     { 
      var parentNode = tree.FindNode(s => s != null && s.MessageId == child.Value.ParentId); 
      if (parentNode != null && parentNode != child) 
       parentNode.Children.Add(child); 
     } 
    } 

    return tree; 
} 

Maildata est une classe avec les 3 champs nécessaires comme expliqué précédemment:

  • MessageID (de tête MessageID)
  • ParentId (de-Reply-In Pour en-tête)
  • TopicId (à partir de l'en-tête ConversationIndex ou Reference)

SimpleTree <> est une classe pour créer un arbre, il est en fait un noeud avec des enfants.Rien de spécial ou lié à l'email ici. La propriété .Value se réfère aux données associées au nœud (MailData ici)

Le but est de trier sur le TopicId afin que nous puissions construire l'arbre en 1 boucle Puis je vérifie tout le courrier dans la racine de l'arbre vérifier si nous pouvons les déplacer sous un autre courrier MessageId usine/ParentId

Rappelez-vous simplement que créer un arbre d'un niveau, quelque chose comme:

  • courrier a
    • Répondre AA
    • Répondre AAA
  • courrier B
    • Répondre BB
    • Répondre BBB

Mais vous auriez besoin quelque chose comme ceci:

  • courrier A
    • Répondre AA
      • Répondre AAA
  • courrier B
    • Répondre BB
      • Répondre BBB
+0

Salut Fabske Pouvez-vous s'il vous plaît me donner un petit exemple de code pour cela? – newbie

+0

Je n'ai pas un échantillon avec exactement ce que vous voulez parce que je n'ai pas besoin de lier chaque courrier à leur réponse, mais je dois seulement avoir le premier mail et lier tous les autres messages de la même conversation (j'en ai un niveau, et pas un niveau pour chaque réponse). Mais je vais essayer de poster quelque chose – Fabske

+0

Ok, j'ai édité ma réponse pour ajouter du code – Fabske

Questions connexes