MailKit 的 IMessageSummary.Envelope.InReplyTo 字段始终为空
MailKit's IMessageSummary.Envelope.InReplyTo field is always null
我正在尝试使用 IMAP 协议和 MailKit 库实现邮件客户端。
无论我如何配置 IMapClinet,字段 IMessageSummary.Envelope.InReplyTo
始终为空。
我正在使用如下所示的 Fetch 方法:
client.Inbox.Fetch(startIndex, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | MessageSummaryItems.References | MessageSummaryItems.All | MessageSummaryItems.Headers);
有趣的是 In-Reply-To
的 header 存在并且包含 References
header 上也存在的值(它们具有相同的值),但提到的字段始终为空。
我是不是遗漏了什么,或者我是否需要在访问其字段之前以某种方式评估 Envelop
属性?
编辑
这是@jstedfast 建议的要检查的协议日志:
Connected to imap://127.0.0.1:143/
S: * OK IMAP4rev1 SmarterMail
C: A00000000 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000000 OK CAPABILITY completed
C: A00000001 AUTHENTICATE CRAM-MD5
S: + PDE5MTIwMTU2NjMugwNDIzQFJvamFuUEM+
C: cm9qYW5Acm9qYW5wYy5sb2NhbCAyNGRiYMTNjNzk5YTkyYjBhZjkxYTU3ZQ==
S: A00000001 OK CRAM authentication successful
C: A00000002 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000002 OK CAPABILITY completed
C: A00000003 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A00000003 OK LIST completed
C: A00000004 LIST "" "INBOX"
S: * LIST (\HasNoChildren \Inbox) "/" "Inbox"
S: A00000004 OK LIST completed
C: A00000005 XLIST "" "*"
S: * XLIST (\HasNoChildren \Trash) "/" "Deleted Items"
S: * XLIST (\HasNoChildren) "/" "Drafts"
S: * XLIST (\HasNoChildren \Inbox) "/" "Inbox"
S: * XLIST (\HasNoChildren \Spam) "/" "Junk E-Mail"
S: * XLIST (\HasNoChildren \Sent) "/" "Sent Items"
S: A00000005 OK XLIST completed
C: A00000006 SELECT Inbox
S: * 1 EXISTS
S: * 0 RECENT
S: * OK [UNSEEN 1] Message 1 is first unseen
S: * OK [UIDVALIDITY 1] UIDs valid
S: * OK [UIDNEXT 35] Predicted next UID
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)
S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)] Folder flags
S: A00000006 OK [READ-WRITE] SELECT completed
C: A00000007 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY BODY.PEEK[HEADER])
S: * 1 FETCH (UID 34 FLAGS () INTERNALDATE "7-Apr-2020 18:36:29 +0200" RFC822.SIZE 1536 ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>") BODY (("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 242 11) ("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 482 8) "alternative") BODY[HEADER] {468}
S: From: "test@mypc.local" <test@mypc.local>
S: To: <my@mypc.local>
S: Subject: Re: Hi dear friend
S: Date: Tue, 07 Apr 2020 16:36:22 GMT
S: Reply-To: test@mypc.local
S: Message-ID: <e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>
S: MIME-Version: 1.0
S: Content-Type: multipart/alternative;
S: boundary=de8794cbb22d4f6ea5a415917f9287ee
S: In-Reply-To: <specified-message-id>
S: References: <specified-message-id>
S: Disposition-Notification-To: test@mypc.local
S: X-SmarterMail-TotalSpamWeight: 0 (Authenticated)
S:
S: )
S: A00000007 OK FETCH completed
似乎 In-Reply-To
仅与 References
一起出现在邮件的 header 中。
新问题:在[=20=上没有In-Reply-To
的情况下,手动检查[=是正确的方法吗? 45=]s 来查找值,还是使用 IMessageSummary
object?
提供的 References
字段更安全?
MailKit 解析 IMAP 服务器返回的 ENVELOPE
值。如果您查看 Protocol Log,IMAP 服务器响应是否在 ENVELOPE
响应中提供 non-null In-Reply-To 值?
ENVELOPE
值具有以下语法:
envelope = "(" env-date SP env-subject SP env-from SP
env-sender SP env-reply-to SP env-to SP env-cc SP
env-bcc SP env-in-reply-to SP env-message-id ")"
env-bcc = "(" 1*address ")" / nil
env-cc = "(" 1*address ")" / nil
env-date = nstring
env-from = "(" 1*address ")" / nil
env-in-reply-to = nstring
env-message-id = nstring
env-reply-to = "(" 1*address ")" / nil
env-sender = "(" 1*address ")" / nil
env-subject = nstring
env-to = "(" 1*address ")" / nil
TL;DR,您将在 ENVELOPE
括号列表值中查找 second-to-last 字符串。
编辑:
好的,现在您已经粘贴了日志,我们可以看看从服务器返回的内容。这是相关的位:
... ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>")
env-date
= "Tue, 07 Apr 2020 16:36:22 GMT"
env-subject
= "Re: Hi dear friend"
env-from
= (("test@mypc.local" 无 "test" "mypc.local"))
env-sender
= (("test@mypc.local" 无 "test" "mypc.local"))
env-reply-to
= ((无无"test" "mypc.local"))
env-to
= ((无无"someone" "mypc.local"))
env-cc
= 零
env-bcc
= 零
env-in-reply-to
= 无
env-message-id
= ""
所以问题是 IMAP 服务器告诉 MailKit In-Reply-To 值是 NIL
(又名 null
)。
根据您收到此邮件的原始 headers,很明显 SmarterMail IMAP 服务器至少在两个方面存在问题:
env-in-reply-to
值作为 NIL
发送,而它显然应该是 "<specified-message-id>"
env-sender
作为 env-from
的副本发送,但根据headers,因为它映射到 Sender:
header,您的示例消息不存在。
问你一个问题:"<specified-message-id>"
字面意思是 header 中的内容?我想知道 SmarterMail 是否正在发送 NIL
,因为那是 技术上 无效的语法,也许 SmarterMail 无法解析它?
只是一个想法。
关于您 post 中的 "New Question":
是的,您可以请求 In-Reply-To
header 并手动解析它 - 这完全没问题。事实上,MessageSummaryItems.References
的工作方式是它请求 HEADER.FIELDS (REFERENCES)
,然后解析原始的 header。由于您 也 发送 MessageSummaryItems.Headers
,MailKit 知道再次请求 References
毫无意义,因为它将成为 Headers
响应的一部分.
我可能会建议不要请求完整的 MessageSummaryItems.Headers
集(除非您有特定需要将它们全部获取),因为它有很多您不需要的额外数据。再一次,在处理损坏的 IMAP 服务器时,也许请求 Headers
比请求 Envelope
更好。
Envelope
的想法是 more-or-less 您需要客户端了解的所有内容,以便向用户显示 message-list。
MailKit 具有 MessageSummaryItems.References
(而不是任何其他个体 header)的原因是因为需要 References
header 才能使用MailKit.MessageThreader.Thread()
方法。它也会使用 Envelope.InReplyTo
值,但我认为这不是必需的,因为从技术上讲,References
是 应该 与其值之一相同的 msg-id
标记。
References
header 是 Message-Id
header 值的链回到 "conversation" 的根(它比那更复杂一点因为一旦列表变得太长,客户可以 trim 一些 msg-id
值,但这是一般的想法)。
我正在尝试使用 IMAP 协议和 MailKit 库实现邮件客户端。
无论我如何配置 IMapClinet,字段 IMessageSummary.Envelope.InReplyTo
始终为空。
我正在使用如下所示的 Fetch 方法:
client.Inbox.Fetch(startIndex, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | MessageSummaryItems.References | MessageSummaryItems.All | MessageSummaryItems.Headers);
有趣的是 In-Reply-To
的 header 存在并且包含 References
header 上也存在的值(它们具有相同的值),但提到的字段始终为空。
我是不是遗漏了什么,或者我是否需要在访问其字段之前以某种方式评估 Envelop
属性?
编辑
这是@jstedfast 建议的要检查的协议日志:
Connected to imap://127.0.0.1:143/
S: * OK IMAP4rev1 SmarterMail
C: A00000000 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000000 OK CAPABILITY completed
C: A00000001 AUTHENTICATE CRAM-MD5
S: + PDE5MTIwMTU2NjMugwNDIzQFJvamFuUEM+
C: cm9qYW5Acm9qYW5wYy5sb2NhbCAyNGRiYMTNjNzk5YTkyYjBhZjkxYTU3ZQ==
S: A00000001 OK CRAM authentication successful
C: A00000002 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000002 OK CAPABILITY completed
C: A00000003 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A00000003 OK LIST completed
C: A00000004 LIST "" "INBOX"
S: * LIST (\HasNoChildren \Inbox) "/" "Inbox"
S: A00000004 OK LIST completed
C: A00000005 XLIST "" "*"
S: * XLIST (\HasNoChildren \Trash) "/" "Deleted Items"
S: * XLIST (\HasNoChildren) "/" "Drafts"
S: * XLIST (\HasNoChildren \Inbox) "/" "Inbox"
S: * XLIST (\HasNoChildren \Spam) "/" "Junk E-Mail"
S: * XLIST (\HasNoChildren \Sent) "/" "Sent Items"
S: A00000005 OK XLIST completed
C: A00000006 SELECT Inbox
S: * 1 EXISTS
S: * 0 RECENT
S: * OK [UNSEEN 1] Message 1 is first unseen
S: * OK [UIDVALIDITY 1] UIDs valid
S: * OK [UIDNEXT 35] Predicted next UID
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)
S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)] Folder flags
S: A00000006 OK [READ-WRITE] SELECT completed
C: A00000007 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY BODY.PEEK[HEADER])
S: * 1 FETCH (UID 34 FLAGS () INTERNALDATE "7-Apr-2020 18:36:29 +0200" RFC822.SIZE 1536 ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>") BODY (("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 242 11) ("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 482 8) "alternative") BODY[HEADER] {468}
S: From: "test@mypc.local" <test@mypc.local>
S: To: <my@mypc.local>
S: Subject: Re: Hi dear friend
S: Date: Tue, 07 Apr 2020 16:36:22 GMT
S: Reply-To: test@mypc.local
S: Message-ID: <e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>
S: MIME-Version: 1.0
S: Content-Type: multipart/alternative;
S: boundary=de8794cbb22d4f6ea5a415917f9287ee
S: In-Reply-To: <specified-message-id>
S: References: <specified-message-id>
S: Disposition-Notification-To: test@mypc.local
S: X-SmarterMail-TotalSpamWeight: 0 (Authenticated)
S:
S: )
S: A00000007 OK FETCH completed
似乎 In-Reply-To
仅与 References
一起出现在邮件的 header 中。
新问题:在[=20=上没有In-Reply-To
的情况下,手动检查[=是正确的方法吗? 45=]s 来查找值,还是使用 IMessageSummary
object?
References
字段更安全?
MailKit 解析 IMAP 服务器返回的 ENVELOPE
值。如果您查看 Protocol Log,IMAP 服务器响应是否在 ENVELOPE
响应中提供 non-null In-Reply-To 值?
ENVELOPE
值具有以下语法:
envelope = "(" env-date SP env-subject SP env-from SP
env-sender SP env-reply-to SP env-to SP env-cc SP
env-bcc SP env-in-reply-to SP env-message-id ")"
env-bcc = "(" 1*address ")" / nil
env-cc = "(" 1*address ")" / nil
env-date = nstring
env-from = "(" 1*address ")" / nil
env-in-reply-to = nstring
env-message-id = nstring
env-reply-to = "(" 1*address ")" / nil
env-sender = "(" 1*address ")" / nil
env-subject = nstring
env-to = "(" 1*address ")" / nil
TL;DR,您将在 ENVELOPE
括号列表值中查找 second-to-last 字符串。
编辑:
好的,现在您已经粘贴了日志,我们可以看看从服务器返回的内容。这是相关的位:
... ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>")
env-date
= "Tue, 07 Apr 2020 16:36:22 GMT"
env-subject
= "Re: Hi dear friend"
env-from
= (("test@mypc.local" 无 "test" "mypc.local"))
env-sender
= (("test@mypc.local" 无 "test" "mypc.local"))
env-reply-to
= ((无无"test" "mypc.local"))
env-to
= ((无无"someone" "mypc.local"))
env-cc
= 零
env-bcc
= 零
env-in-reply-to
= 无
env-message-id
= ""
所以问题是 IMAP 服务器告诉 MailKit In-Reply-To 值是 NIL
(又名 null
)。
根据您收到此邮件的原始 headers,很明显 SmarterMail IMAP 服务器至少在两个方面存在问题:
env-in-reply-to
值作为NIL
发送,而它显然应该是"<specified-message-id>"
env-sender
作为env-from
的副本发送,但根据headers,因为它映射到Sender:
header,您的示例消息不存在。
问你一个问题:"<specified-message-id>"
字面意思是 header 中的内容?我想知道 SmarterMail 是否正在发送 NIL
,因为那是 技术上 无效的语法,也许 SmarterMail 无法解析它?
只是一个想法。
关于您 post 中的 "New Question":
是的,您可以请求 In-Reply-To
header 并手动解析它 - 这完全没问题。事实上,MessageSummaryItems.References
的工作方式是它请求 HEADER.FIELDS (REFERENCES)
,然后解析原始的 header。由于您 也 发送 MessageSummaryItems.Headers
,MailKit 知道再次请求 References
毫无意义,因为它将成为 Headers
响应的一部分.
我可能会建议不要请求完整的 MessageSummaryItems.Headers
集(除非您有特定需要将它们全部获取),因为它有很多您不需要的额外数据。再一次,在处理损坏的 IMAP 服务器时,也许请求 Headers
比请求 Envelope
更好。
Envelope
的想法是 more-or-less 您需要客户端了解的所有内容,以便向用户显示 message-list。
MailKit 具有 MessageSummaryItems.References
(而不是任何其他个体 header)的原因是因为需要 References
header 才能使用MailKit.MessageThreader.Thread()
方法。它也会使用 Envelope.InReplyTo
值,但我认为这不是必需的,因为从技术上讲,References
是 应该 与其值之一相同的 msg-id
标记。
References
header 是 Message-Id
header 值的链回到 "conversation" 的根(它比那更复杂一点因为一旦列表变得太长,客户可以 trim 一些 msg-id
值,但这是一般的想法)。