3

我正在开发一个软件,我可以在其中检索收件箱并从 Outlook 发送项目。我想要做的是将收件箱电子邮件与回复联系起来(如果有人回复了该电子邮件)。列表应按此顺序显示

Sender@abc.com 接收主题接收时间 sender@abc.com 回复主题 发送时间

我打算做的是检索一个数据表中的收件箱项目和另一个数据表中的已发送项目。它根据发件人电子邮件和主题逐一读取电子邮件,然后在已发送项目中搜索该发件人和电子邮件,如果匹配,则将其合并到第三个数据表中。

还有其他更好的方法吗?

这是代码:

 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;
    }
4

1 回答 1

0

我在 Outlook 加载项中制作了这种东西

没有 100% 的方法可以做到……
问题是对话 ID 并不总是由其他软件保存。因此,您需要使用一组数据将电子邮件链接到他们的答案:
- Message-ID:这在电子邮件标题中可用。已发送的项目没有这个:/
- In-Reply-To:这也在电子邮件标题中
- 主题 ID

对于主题 ID,我按以下顺序检索值(我取第一个可用的值):
- MailItem.ConversationIndex:每个回复都将字节添加到对话索引
- 参考标头

然后,我使用 topicID 将电子邮件链接到他们的回复,电子邮件的前 X 个字符与回复相同。示例原始电子邮件主题 id = abc,回复 = abcdef 对于无法使用对话 id 链接的所有邮件,我尝试使用 Message-ID 和 In-Reply-To ID 进行链接

问题尤其来自 Outlook 发送的电子邮件(没有 Message-ID),然后用户回复没有 Reference/ConversationIndex 标头......您将无法将两封邮件链接在一起。

希望能帮助到你

编辑:这是一些代码。我已经从不同的类/方法复制/粘贴代码来创建一个方法,所以它可能无法编译。将其更多地视为伪代码。

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 是一个包含 3 个字段的类,如前所述:

  • MessageID(来自 Message-ID 标头)
  • ParentId(来自 In-Reply-To 标头)
  • TopicId(来自 ConversationIndex 或 Reference 标头)

SimpleTree<> 是一个创建树的类,它实际上是一个带有子节点的节点。这里没有什么特别的或与电子邮件相关的。.Value 属性指的是与节点关联的数据(此处为 MailData)

目标是对 TopicId 进行排序,以便我们可以在 1 个循环中构建树然后我检查树根中的所有邮件,以检查是否可以使用 MessageId/ParentId 将它们移动到另一个邮件下

请记住,它创建了一个单级树,例如:

  • 邮件 A
    • 回复 AA
    • 回复 AAA
  • 邮件 B
    • 回复 BB
    • 回复 BBB

但是你需要这样的东西:

  • 邮件 A
    • 回复 AA
      • 回复 AAA
  • 邮件 B
    • 回复 BB
      • 回复 BBB
于 2013-04-08T19:30:57.423 回答