MailKit SMTP and IMAP read receipts

56 Views Asked by At

I have a few questions about return receipts using Exchange Online.

If I send an SMTP message with

vEmail.Headers(HeaderId.DispositionNotificationTo) = SenderEmail

It then sends the return receipt request when the user opens it (in this instance it's me using Domino/Notes)

When that read message is downloaded from Exchange, I get these values...

Dim Message = vClient.Inbox.GetMessage(vItems(i).UniqueId)
Dim vSubject As String = Message.Subject
Dim vBody As String = Message.HtmlBody

The Return Receipt is not in the body, but can be seen at the end of the full message. What I need to do is get a handle on one, if it exists - and then I can get the text to add it to the body and prefix the Subject with 'Read:'

The second question is how exchange is dealing with read receipts for the InBox messages.

When the message(s) is/are downloaded from Exchange with IMAP it finishes with

vClient.Inbox.AddFlags(vItems(i).UniqueId, MessageFlags.Deleted, True)

To delete from the server (I have the messages locally, no need to keep them) and then...

vClient.Inbox.Expunge()

As soon as Expunge is run Exchange immediately sends a 'Not read' reply. How do I overcome that behaviour? I don't want to set the flags to 'Read' first as they haven't.

Any pointers would be appreciated.

============= UPDATE======================

I have tried to get the read receipt as described...

'Check if the item is a return receipt
Dim report = TryCast(Message.Body, MultipartReport)
If report IsNot Nothing AndAlso report.ReportType.Equals("disposition-notification", StringComparison.OrdinalIgnoreCase) Then
vBody += report.ToString
vSubject = "Read: " & vSubject
End If

After adding this I emailed a message - when it was opened a read receipt was returned but it passed over the code.

=========FURTHER UPDATE==========

If a message contains a read request, I can see that in the Disposition-Notification...

Disposition-Notification-To: "My Name"[[email protected]]

So, I guess I can handle that in the Client in a similar way to Notes Client.

What I am really interested in is the read report sent back when the message I send out is opened. When it comes back this is appended to the end of the message without Disposition_Notification

MIME-Version: 1.0

Return Receipt
                                                                       
Your       Testing for read request                                     
document:                                                               
                                                                       
was        "Some Name" [[email protected]]             
received                                                                
by:                                                                     
                                                        
         
at:        03/01/2024 08:10:32 

For some reason this is not in the body of the message, and I think doing a search for 'Read Receipt' might only work for some servers/clients as they tend to give it different names and some DO send it as part of the body as well...

report-type=disposition-notification
Content-Language: en-US

--_000_ab934b08b0a54e928bb127db7b8c5277domainnamecouk_
Content-Type: multipart/alternative;
     
boundary="_002_ab934b08b0a54e928bb127db7b8c5277domainnamecouk_"

--_002_ab934b08b0a54e928bb127db7b8c5277domainnamecouk_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="us-ascii"

Your message

To: Kate Smith
Subject: Submission query 
Sent: Thursday, January 18, 2024 1:07:03 PM (UTC+00:00) Dublin, 
Edinburg=
h, Lisbon, London

 was read on Friday, March 1, 2024 12:12:08 PM (UTC+00:00) Dublin, 
Edinburg=
h, Lisbon, London.

--_002_ab934b08b0a54e928bb127db7b8c5277DDomainName_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="us-ascii"

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; 
 charset=3Dus-ascii"=
 >
 <meta name=3D"Generator" content=3D"Microsoft Exchange Server">
 <!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; pad=
 ding-left: 4pt; border-left: #800000 2px solid; } --></style>
 </head>
 <body>
 <font size=3D"2"><span style=3D"font-size:11pt;">
 <div class=3D"PlainText">Your message <br>
 <br>
 &nbsp;&nbsp; To: Kate Smith<br>
 &nbsp;&nbsp; Subject: Submission query 
 on<br>
 &nbsp;&nbsp; Sent: Thursday, January 18, 2024 1:07:03 PM 
 (UTC+00:00) Dublin=
 , Edinburgh, Lisbon, London<br>
 <br>
 &nbsp;was read on Friday, March 1, 2024 12:12:08 PM (UTC+00:00) 
 Dublin, Edi=
 nburgh, Lisbon, London.</div>
 </span></font>
 </body>
 </html>

As for dealing with 'not read' reports, it looks like there is a way to turn them off at Exchange Online, but they keep updating the interface so many times the only method I can find is already out of date.

1

There are 1 best solutions below

3
jstedfast On

This question is answered in the MailKit FAQ

Q: How can I process a read receipt notification?

A read receipt notification comes in the form of a MIME message with a top-level MIME part with a MIME-type of multipart/report that has a report-type parameter with a value of disposition-notification.

You could check for this in code like this:

var report = message.Body as MultipartReport;
if (report != null && report.ReportType.Equals ("disposition-notification", StringComparison.OrdinalIgnoreCase)) {
    // This is a read receipt notification.
}

The first part of the multipart/report will be a human-readable explanation of the notification.

The second part will have a MIME-type of message/disposition-notification and be represented by a MessageDispositionNotification.

This notification part will contain a list of header-like fields containing information about the message that this notification is for such as the Original-Message-Id, Original-Recipient, etc.

var notification = report[1] as MessageDispositionNotification;
if (notification != null) {
    // Get the Message-Id of the message this notification is for...
    var messageId = notification.Fields["Original-Message-Id"];
}

For more information on this topic, read rfc3798.