Thursday, December 16, 2020

Read Receipt Macro for Outlook

Know when your email is read

One of the annoying things about email today is not knowing when or if your email has been read. This is particularly annoying when sending a very important message that is somewhat time sensitive. Not everyone responds to the emails sent to them, and with spam filters employed on almost every computer, you just don't know if the message got through.

Most email applications do have a "return-receipt" option, but that requires the receiver of the email to be a participant in the process. Most people, as far as I can figure, turn off this feature. There are services available on the web that will allow you to track your emails. Two such services that come to mind are SpyPig and ReadNotify. SpyPig is a free service, whereas ReadNotify is fee based. I tried SpyPig but couldn't get it to work in my Outlook 2007. So, I decided to create my own.

The process to track your email is relatively simply and not new. Email marketeers have been using this "technology" for years. It simply requires inserting an image, whether visible or invisible, into the message in such a way that the image is not displayed on the recipients computer without first connecting to a server where it can be tracked.

To make this happen, I create this simple macro that inserts an image into the message before it actually gets sent. The macro is here:

Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)

  Dim strTo As String
  Dim strFrom As String
  Dim strSubject As String

  ' ask to send notification of read receipt
  svar = MsgBox("Send notification when message is read?", vbYesNo, "Read Receipt")
  If svar = vbYes Then
    strTo = Item.To
    strFrom = Application.Session.CurrentUser.Address
    strSubject = Item.Subject
    strKey = RandomString(12)
    Item.HTMLBody = Item.HTMLBody + "<img height=16 width=16 src='" + strKey + "|" + strFrom + "|" + strTo + "|" + strSubject + "' >"
  End If

End Sub

Function RandomString(cb As Integer) As String
  ' function created by Joel Spolsky
  Dim rgch As String
  rgch = "abcdefghijklmnopqrstuvwxyz"
  rgch = rgch & UCase(rgch) & "0123456789"

  Dim i As Long
  For i = 1 To cb
    RandomString = RandomString & Mid$(rgch, Int(Rnd() * Len(rgch) + 1), 1)

End Function

You need to insert this code into Outlook's Visual Basic editor which can be accessed by clicking on Tools - Macro - Visual Basic Editor, or by pressing Alt-F11. Insert the code into the This OutlookSession section of Project1. Once you close and reopen Outlook you may get a macro security warning depending on your security settings. To avoid this, I suggect self-signing the macro. Microsoft explains how to do this here: How to Prevent the VBA Macro Security Warning in Microsoft Outlook 2000. It is written for Outlook 2000, but you can figure it out for later versions very easily.

As I don't want to track every email, the macro prompts me as to whether I want to be notified when the email is read. If I answer "Yes", the image is inserted, otherwise the image is not inserted. The macro collects the recipient, sender and subject of the email and attaches this information to the "image". It also creates a random ID number which helps with the tracking. As the image is inserted into the message just before the message is sent, this information is sent to the server and logged with the random ID the first time it arrives. It also logs the sender's IP address so the sender does not receive a false read-receipt when the message is sent.

Now when the recipient opens the email, their IP address is compared to the senders IP address and if it is different, then a notification is sent to the sender. The server is set up so that the first 5 read notifications are sent.

Does this work all the time?
No. But it will probably work 90% to 98% of the time. It will not work if the recipient does not receive HTML messages, or if the recipient's email client does not display images by default. For example, it may not work in messages sent to GMail accounts as GMail turns off image display for senders it does not recognize.

You may not get a notification if:

  • You or the recipient uses a plain-text email or rich-text email instead of HTML-formatted email
  • The recipient disables or blocks the automatic image download on their email application
  • The recipient's ISP or network does not allow downloadable images in messages and alters the code
  • The recipient's anti-virus, anti-spam, anti-spyware software or firewall blocks the image

You may receive a false notification if:

  • You open the message from your Sent folder when your computer is connected to the internet at another location (ie: laptop)
  • You send the message to multiple people. You will receive a read notification for the first five people that open the email, whether they be the recipient, one of the recipients, someone copied (CC'd) or some blindcopied (BCC'd)
  • The recipient forwards the message and someone else opens it
  • The recipient sends the message back to you with the image intact and you open it on a different computer

Alternate Method
Instead of inserting a tracking image into the sent email, you could insert a "dummy" style-sheet. This way, no image appears in the message and the receiver of the email would be none the wiser. To do this, simple replace this line:

Item.HTMLBody = Item.HTMLBody + "<img height=16 width=16 src='" + strKey + "|" + strFrom + "|" + strTo + "|" + strSubject + "' >"

with this line:

Item.HTMLBody = Item.HTMLBody + "<link rel=stylesheet type='text/css' media=all href=''" + strKey + "|" + strFrom + "|" + strTo + "|" + strSubject + "|.css' >"

Interesting thing about using the style-sheet method above, Outlook 2007 moves the code to the head section of the message before sending, even though it is inserted at the end of the body section. Also, for email clients that don't display images, this tracking method still works. If using your own server you will have to make a change to the php code to send a "dummy" style-sheet instead of an image.

Privacy Policy
KidMoses does not know the content of your email message. The email address you provide to us is solely used to send you the read notifications. We will not send you any junk mail. We do not sell, rent or give away your email address for any purpose to anyone. All the information provided in the image link is kept private.

This script is provided for information purposes only. Any conflict arising between the sender and recipient of emails using this script is solely between the sender and recipient. Unlawful use of this script is prohibited.

The macro and related files can be downloaded here, although all that is needed is the script above. The other files are included if the user wishes to have the "image" files loaded on their own server. KidMoses does not guarantee that read-notifications will continue to be sent indefinitely.


delicious digg facebook stumble twitter myspace linkedin technorati reddit google springpad blogger | addthis Share More...

we are listening

anonymous said:

Wednesday, November 16, 2020

I just tested the script on myself, and it did not send me a read notification.

mrbsaved said:

Thursday, November 10, 2020

I don't need anything quite so fancy. My outlook admin team prevents users from always denying or every denying a read receipt by setting the default to always send. But I also cannot change the setting to always request a read receipt. I have to remember to do it every time I send a message. I need a macro that will automatically turn on request read receipt when I send the message. My VB skills are beginner, at best. By the way, is there a way to record a macro in outlook like one can in Excel?

Kidmoses said:

Thursday, June 16, 2021

This is the code you can use (change) to send a dummy css file: /* return dummy css file */ $file = 'pathtodummy.css'; header("Content-Transfer-Encoding: 8bit"); header("Content-length: " . filesize($file)); header("Content-type: text/css"); readfile($file); return true;

Steve S. said:

Monday, June 13, 2021

Hi Howard, Thanks much for the great script - It is just what I have been looking for. It executes with no problems. I would like to try the css method but I am not sure what I should place in the header to send a dummy css file. What should I change in the following? /* return dummy image file */ $file = 'icon.gif'; header("Content-Transfer-Encoding: 8bit"); header("Content-length: " . filesize($file)); header("Content-type: image/gif"); readfile($file); return true; Thanks, Steve

anonymous said:

Tuesday, December 28, 2020

Great script. Works perfectly. Thanks.