使用mimekit / mailkit库获取无法投递的电子邮件地址

时间:2017-02-09 05:26:24

标签: c# mailkit

我开始使用@jstedfast Mimekit/Mailkit library,顺便说一下,使用其主题行进行搜索,可以提取不可比较的内容。我尝试使用message.to,message.resentto。

我如何获得这些信息。我今天第一次尝试。我能够获得列表和正文,但我只需要电子邮件。我尝试使用s22.imap,但不再有任何支持,然后我发现了这一点。我知道你在这里活跃@jstedfast我需要你的帮助..你的github里没有讨论标签。

提前致谢

2 个答案:

答案 0 :(得分:4)

如果查看原始邮件来源,Content-Type标题的值是否与multipart/report; report-type=delivery-status行匹配?如果是这样,则此邮件很可能包含一个带有Content-Type标头的子部件,其值为message/delivery-status。它应该multipart/report的第二个子部分(第一部分应该是一个人类可读的解释)。

如果是,您可以将message/delivery-status MimeEntity投射到MessageDeliveryStatus的实例。您会注意到MessageDeliveryStatus类有一个名为StatusGroups的属性,它是多个标题集合的列表(例如HeaderList个对象的列表)。

每个HeaderList都包含有关失败的特定收件人的信息。我想你想要做的是查看Final-Recipient标题,其中包含2条信息:

  1. 地址类型(通常应为"rfc822"
  2. 收件人的邮箱(这是您想要的)
  3. 不幸的是,MimeKit没有任何工具可以解析Final-Recipient标头,但是使用address-typeIndexOf (';')来查找标头值中MailboxAddress.TryParse()参数的结尾应该是微不足道的。那么你可以使用类似Substring()的东西来解析它(或者你可能只需要string[] GetUndeliverableAddresses (MimeMessage message) { var report = message.Body as MultipartReport; if (report == null) throw new ArgumentException ("This is not a multipart/report!"); MessageDeliveryStatus status = null; for (int i = 0; i < report.Count; i++) { status = report[i] as MessageDeliveryStatus; if (status != null) break; } if (status == null) throw new ArgumentException ("Did not contain a message/delivery-status!"); var undeliverables = new List<string> (); for (int i = 0; i < status.StatusGroups.Count; i++) { var recipient = status.StatusGroups[i]["Final-Recipient"]; int semicolon = recipient.IndexOf (';'); var undeliverable = recipient.Substring (semicolon + 1).Trim (); undeliverables.Add (undeliverable); } return undeliverables.ToArray (); } 解析它的值。

    因此,这可能在代码中看起来是这样的:

    message/delivery-status

    有关SELECT D1.[Day], D1.[TimeStamp], D1.[Material], D1.Source, CASE WHEN D1.[RunTotal] - D2.[RunTotal] >= 0 THEN D1.[RunTotal] - D2.[RunTotal] ELSE 0 END AS [Tons] FROM (SELECT ROW_NUMBER() OVER (ORDER BY [TimeStamp]) rownum, [TimeStamp], cast([TimeStamp] AS date) [Day], MIN(CASE Equipment WHEN 'Bin1' THEN CAST([Run Total] AS decimal(18, 3)) END) AS [RunTotal], MIN(CASE Equipment WHEN 'Bin1' THEN Material END) AS [Material], 'Bin1' AS Source FROM Plant_Production.dbo.Data WHERE Equipment = 'Bin1' GROUP BY [Timestamp]) D1 LEFT OUTER JOIN (SELECT ROW_NUMBER() OVER (ORDER BY [TimeStamp]) rownum, [TimeStamp], cast([TimeStamp] AS date) [Day], MIN(CASE Equipment WHEN 'Bin1' THEN CAST([Run Total] AS decimal(18, 3)) END) AS [RunTotal], MIN(CASE Equipment WHEN 'Bin1' THEN [Material] END) AS [Material], 'Bin1' AS Source FROM Plant_Production.dbo.Data WHERE Equipment = 'Bin1' GROUP BY [TimeStamp]) D2 ON D1.RowNum - 1 = D2.RowNum AND D1.[Day] = D2.[Day] 的详情,请参阅https://tools.ietf.org/html/rfc3464

    希望有所帮助。

答案 1 :(得分:0)

这就是我做的事情

 foreach (var uid in inbox.Search(query))
        {
            var message = inbox.GetMessage(uid);
           // Console.WriteLine("Subject: {0}", message.Subject);
            //Console.WriteLine("Subject: {0}", message.Headers);
           // Console.WriteLine("Subject: {0}", message.BodyParts);
            var text = message.BodyParts;
            string src = text.ElementAt(1).ToString();
            int srcStart = src.IndexOf("RFC822;",0); << i used final-recipient intially
            int srcEnd   = src.IndexOf("Action", 0);
            Console.WriteLine("Email:" + src.Substring(srcStart + 8, srcEnd - (srcStart + 8)));
            Console.WriteLine(src);


            //foreach (var part in message.BodyParts)
            //{
            //    Console.WriteLine(part);
            //    // do something
            //}

        }

如果可能存在问题,请告诉我..如果收件人收件箱已满,我会收到rfc822吗?我无法测试那个..我测试了不存在域名的电子邮件,邮箱不存在..有live.com,randomdomain.com,yahoo.com和gmail。另一方面,gmail不会返回任何不可更改的内容。