cancel
Showing results for 
Search instead for 
Did you mean: 

Canonical Property - Internet Message ID Outlook

xlxu001
Level 5
@devneetmohanty07 any chance you have written a code to extract the Internet Message ID for an Outlook email? I did some research and looks like the PR_TRANSPORT_MESSAGE_HEADERS property can give this information, but I'm unsure how to add it to the Outlook VBO.  Also ran into a Python library that thought would help, but doesn't talk about the internet headers.  Any ideas? I have noticed you have a lot of codes that you have shared with the community which we greatly appreciate.

exchangelib

https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagtransportmessageheaders-canonical-property​

------------------------------
Lourdes Urena
Sr Solutions Engineering
Grainger Panama Services
Panama
------------------------------
Lourdes Urena Sr Solutions Engineering Grainger Panama Services Panama
1 BEST ANSWER

Helpful Answers

Hi Lourdes,

I actually never came across an use case like that before so I didn't have a code for this. However, I went through some of the resources related to this use case. Also, to let you know I am not able to access the link that you have posted as it is giving me Error 404 - Content not found error.

I did some tweaking on the Outlook VBO at my end and I was able to extract the Internet Header Message ID at my end. You can just verify whether the ID I am referring is what you want or not?

NOTE: I would suggest trying the below solution approach on a different Business Object which would be a duplicate or a replica of your Outlook VBO so that in case there is any error and you want to revert back to the original solution then you can easily achieve the same.

If I am correct the ID shown below in the screenshot while opening a email property manually is what you require I guess:

24533.png

So in order to retrieve this ID, you are correct that we need to refer to the PR_TRANSPORT_MESSAGE_HEADERS property. However, it can only be accessed via the URI schema: "http://schemas.microsoft.com/mapi/proptag/0x007D001F"

So the modifications that I have done in my Outlook VBO are as follows:

First I changed the collection schema for "Items" in the "Get Received Items (Basic)" action in order to also include a separate column named "InternetMessageID" of type Text.

24534.png

Next, I modified the "Internal_Get Items" action where actually our code stage resides. The first changed was to again modify the schema of the collection "Items" in order to include a separate column named "InternetMessageID" of type Text.

24535.png

Next I modified the code stage in order to add this column at runtime and also to refer the property schema URI in order to fetch the whole Internet Headers section as we can see in the first screenshot that I was able to navigate manually. Once I get the Internet Headers, I am using a series of string manipulation functions to extract the Message ID part out of the entire header content.

The highlighted content in below code is what I have added extra:

Dim app = CreateObject("Outlook.Application")
Dim _nameSpace = app.GetNameSpace("MAPI")
Dim internetHeaders As String
Dim folder = _nameSpace.GetDefaultFolder(Outlook_Folder_ID)

If Sub_Folder <> "" Then
For each name as string in Sub_Folder.Split("\")
folder = folder.Folders(name)
Next
End If

'See https://msdn.microsoft.com/en-us/library/office/aa210946(v=office.11).aspx
'for mail item properties
Dim dataTable As New Data.DataTable
dataTable.Columns.Add("EntryID", Type.GetType("System.String"))
dataTable.Columns.Add("To", Type.GetType("System.String"))
dataTable.Columns.Add("CC", Type.GetType("System.String"))
dataTable.Columns.Add("Subject", Type.GetType("System.String"))
dataTable.Columns.Add("Body", Type.GetType("System.String"))
dataTable.Columns.Add("Attachments", Type.GetType("System.String"))
dataTable.Columns.Add("ReceivedOn", Type.GetType("System.DateTime"))
dataTable.Columns.Add("SentOn", Type.GetType("System.DateTime"))
dataTable.Columns.Add("SenderName", Type.GetType("System.String"))
dataTable.Columns.Add("SenderEmailAddress", Type.GetType("System.String"))
dataTable.Columns.Add("Unread", Type.GetType("System.Boolean"))
dataTable.Columns.Add("InternetMessageID", Type.GetType("System.String"))

Dim folderItems = If(Filter_Expression <> "", folder.Items.Restrict(Filter_Expression), folder.Items)

For Each item As Object In folderItems
If Not TypeOf item Is MailItem Then Continue For
Dim row As Data.DataRow = dataTable.NewRow
row("EntryID") = item.EntryID
row("To") = item.To
row("CC") = item.CC
row("Subject") = item.Subject
row("Body") = item.Body

Dim attachments As String = ""
For Each attachment As Object In item.Attachments
If attachment.Type = 1 Then
attachments = attachments & "|" & attachment.DisplayName
End If
Next

row("Attachments") = If (attachments.Length = 0, "", attachments.SubString(1))
row("SentOn") = item.SentOn
row("ReceivedOn") = item.ReceivedTime
row("SenderName") = item.SenderName
row("SenderEmailAddress") = If (item.SenderEmailType = "EX",item.Sender.GetExchangeUser.PrimarySmtpAddress,item.SenderEmailAddress)
row("Unread") = item.Unread
internetHeaders = item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F")
row("InternetMessageID") = Trim(Replace(Replace(Replace(internetHeaders.Substring(internetHeaders.IndexOf("Message-ID:")+Len("Message-ID:"),internetHeaders.IndexOf("Accept-Language:") - (internetHeaders.IndexOf("Message-ID:")+Len("Message-ID:"))),Environment.NewLine(),""),"<",""),">",""))
dataTable.Rows.Add(row)
Item_Count += 1
Next
Items = dataTable

NOTE: In the above code extraction logic is based on extracting any data which is location between the labels: "Message-ID:" and "Accept-Language:" based on how my Internet Headers message was appearing. In your case, you might need to cross verify if the sequencing of the label is in the similar way or not. In case it is different, you can modify the extraction logic as per your need.

Results:

24536.png
24537.png
24538.png

Let me know if this helps to resolve your query

------------------------------
----------------------------------
Hope it helps you and if it resolves you query please mark it as the best answer so that others having the same problem can track the answer easily

Regards,
Devneet Mohanty
Intelligent Process Automation Consultant
Blue Prism 7x Certified Professional
Website: https://devneet.github.io/
Email: devneetmohanty07@gmail.com

----------------------------------
------------------------------
---------------------------------------------------------------------------------------------------------------------------------------
Hope this helps you out and if so, please mark the current thread as the 'Answer', so others can refer to the same for reference in future.
Regards,
Devneet Mohanty,
SS&C Blueprism Community MVP 2024,
Automation Architect,
Wonderbotz India Pvt. Ltd.

View answer in original post

7 REPLIES 7

Hi Lourdes,

I actually never came across an use case like that before so I didn't have a code for this. However, I went through some of the resources related to this use case. Also, to let you know I am not able to access the link that you have posted as it is giving me Error 404 - Content not found error.

I did some tweaking on the Outlook VBO at my end and I was able to extract the Internet Header Message ID at my end. You can just verify whether the ID I am referring is what you want or not?

NOTE: I would suggest trying the below solution approach on a different Business Object which would be a duplicate or a replica of your Outlook VBO so that in case there is any error and you want to revert back to the original solution then you can easily achieve the same.

If I am correct the ID shown below in the screenshot while opening a email property manually is what you require I guess:

24533.png

So in order to retrieve this ID, you are correct that we need to refer to the PR_TRANSPORT_MESSAGE_HEADERS property. However, it can only be accessed via the URI schema: "http://schemas.microsoft.com/mapi/proptag/0x007D001F"

So the modifications that I have done in my Outlook VBO are as follows:

First I changed the collection schema for "Items" in the "Get Received Items (Basic)" action in order to also include a separate column named "InternetMessageID" of type Text.

24534.png

Next, I modified the "Internal_Get Items" action where actually our code stage resides. The first changed was to again modify the schema of the collection "Items" in order to include a separate column named "InternetMessageID" of type Text.

24535.png

Next I modified the code stage in order to add this column at runtime and also to refer the property schema URI in order to fetch the whole Internet Headers section as we can see in the first screenshot that I was able to navigate manually. Once I get the Internet Headers, I am using a series of string manipulation functions to extract the Message ID part out of the entire header content.

The highlighted content in below code is what I have added extra:

Dim app = CreateObject("Outlook.Application")
Dim _nameSpace = app.GetNameSpace("MAPI")
Dim internetHeaders As String
Dim folder = _nameSpace.GetDefaultFolder(Outlook_Folder_ID)

If Sub_Folder <> "" Then
For each name as string in Sub_Folder.Split("\")
folder = folder.Folders(name)
Next
End If

'See https://msdn.microsoft.com/en-us/library/office/aa210946(v=office.11).aspx
'for mail item properties
Dim dataTable As New Data.DataTable
dataTable.Columns.Add("EntryID", Type.GetType("System.String"))
dataTable.Columns.Add("To", Type.GetType("System.String"))
dataTable.Columns.Add("CC", Type.GetType("System.String"))
dataTable.Columns.Add("Subject", Type.GetType("System.String"))
dataTable.Columns.Add("Body", Type.GetType("System.String"))
dataTable.Columns.Add("Attachments", Type.GetType("System.String"))
dataTable.Columns.Add("ReceivedOn", Type.GetType("System.DateTime"))
dataTable.Columns.Add("SentOn", Type.GetType("System.DateTime"))
dataTable.Columns.Add("SenderName", Type.GetType("System.String"))
dataTable.Columns.Add("SenderEmailAddress", Type.GetType("System.String"))
dataTable.Columns.Add("Unread", Type.GetType("System.Boolean"))
dataTable.Columns.Add("InternetMessageID", Type.GetType("System.String"))

Dim folderItems = If(Filter_Expression <> "", folder.Items.Restrict(Filter_Expression), folder.Items)

For Each item As Object In folderItems
If Not TypeOf item Is MailItem Then Continue For
Dim row As Data.DataRow = dataTable.NewRow
row("EntryID") = item.EntryID
row("To") = item.To
row("CC") = item.CC
row("Subject") = item.Subject
row("Body") = item.Body

Dim attachments As String = ""
For Each attachment As Object In item.Attachments
If attachment.Type = 1 Then
attachments = attachments & "|" & attachment.DisplayName
End If
Next

row("Attachments") = If (attachments.Length = 0, "", attachments.SubString(1))
row("SentOn") = item.SentOn
row("ReceivedOn") = item.ReceivedTime
row("SenderName") = item.SenderName
row("SenderEmailAddress") = If (item.SenderEmailType = "EX",item.Sender.GetExchangeUser.PrimarySmtpAddress,item.SenderEmailAddress)
row("Unread") = item.Unread
internetHeaders = item.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F")
row("InternetMessageID") = Trim(Replace(Replace(Replace(internetHeaders.Substring(internetHeaders.IndexOf("Message-ID:")+Len("Message-ID:"),internetHeaders.IndexOf("Accept-Language:") - (internetHeaders.IndexOf("Message-ID:")+Len("Message-ID:"))),Environment.NewLine(),""),"<",""),">",""))
dataTable.Rows.Add(row)
Item_Count += 1
Next
Items = dataTable

NOTE: In the above code extraction logic is based on extracting any data which is location between the labels: "Message-ID:" and "Accept-Language:" based on how my Internet Headers message was appearing. In your case, you might need to cross verify if the sequencing of the label is in the similar way or not. In case it is different, you can modify the extraction logic as per your need.

Results:

24536.png
24537.png
24538.png

Let me know if this helps to resolve your query

------------------------------
----------------------------------
Hope it helps you and if it resolves you query please mark it as the best answer so that others having the same problem can track the answer easily

Regards,
Devneet Mohanty
Intelligent Process Automation Consultant
Blue Prism 7x Certified Professional
Website: https://devneet.github.io/
Email: devneetmohanty07@gmail.com

----------------------------------
------------------------------
---------------------------------------------------------------------------------------------------------------------------------------
Hope this helps you out and if so, please mark the current thread as the 'Answer', so others can refer to the same for reference in future.
Regards,
Devneet Mohanty,
SS&C Blueprism Community MVP 2024,
Automation Architect,
Wonderbotz India Pvt. Ltd.

Hi Devneet,

 

I attempted to make those changes but I'm getting the below error at the time of running the code stage itself:

"Internal : Could not execute code stage because exception thrown by code stage: Value does not fall within the expected range." Any ideas?

 

24541.png

 

Lourdes Urena  | Sr. Solutions Engineering (RPA) | W.W. Grainger, Inc.

Ph: 224-724-5080| lourdes.urena@grainger.com |www.grainger.com

 



Lourdes Urena Sr Solutions Engineering Grainger Panama Services Panama

@devneetmohanty07 I GOT IT! Thank you soooo much! This worked wonderfully.​

------------------------------
Lourdes Urena
Sr Solutions Engineering
Grainger Panama Services
Panama
------------------------------
Lourdes Urena Sr Solutions Engineering Grainger Panama Services Panama

Always happy to help and glad it finally worked out for you @xlxu001 :)​

------------------------------
----------------------------------
Hope it helps you and if it resolves you query please mark it as the best answer so that others having the same problem can track the answer easily

Regards,
Devneet Mohanty
Intelligent Process Automation Consultant
Blue Prism 7x Certified Professional
Website: https://devneet.github.io/
Email: devneetmohanty07@gmail.com

----------------------------------
------------------------------
---------------------------------------------------------------------------------------------------------------------------------------
Hope this helps you out and if so, please mark the current thread as the 'Answer', so others can refer to the same for reference in future.
Regards,
Devneet Mohanty,
SS&C Blueprism Community MVP 2024,
Automation Architect,
Wonderbotz India Pvt. Ltd.

Hi BluePrism community, Devneet,

I'm working on the above enhancement to our Outlook VBO code and it certainly works for the individual circumstance of internet header structure.

I need to expand the usability for hundreds of users within an organisation that may have received emails with varying types of internet header structure. Often these variances stem from being an internal email, an external email, and external automated engine emails.

Each of these received emails will have "Message-ID: <InfoToCapture@example> unique following structure".

Can someone please provide a suitable code snippet to reliably target "Message-ID: <wildcard/all_within_&lt_&gt> and ignore anything after the ">" sign?



------------------------------
Pierce Clements
------------------------------

Hi @xlxu001 

I noticed this post and that you originally were getting an error stating "value does not fall within expected range". I have been receiving this error intermittently on a couple of my bots for a few months, we havent made any code changes so its proving a bit difficult to identify the cause of it, can you tell me if you know what was causing the error in your code and what the fix was? Im thinking its maybe an issue with the outlook profile or possibly just a slow microsoft exchange connection issue.



------------------------------
Michael ONeil
Technical Lead developer
NTTData
Europe/London
------------------------------

Hi Michael,
I remembered it was something that had to so with the schemas URL changing, which if you google the above URL it actually doesn't work, but I'm not sure what the Google search I did was after that in order to get the right schemas URL to implement.



------------------------------
Lourdes Urena
Sr Solutions Engineering
Grainger Panama Services
Panama
------------------------------
Lourdes Urena Sr Solutions Engineering Grainger Panama Services Panama