Creating a Digest email (based on the contents of other Email) using EWS or REST in Exchange and Office365
The concept of digest emails is quite an old one, it is where you have one email that summarises the contents of many different items to essentially make your life a little easier to catch up on high volume Mailing lists or really anything else where you want to compress down the contents of many to one. Other things digests can be used for are summaries of Public Folders or Junk Mail or they could be used in Group, Team or Shared Mailboxes to enhanced the usability of these. Another common use if by email marketers so if you ever googled the subject you would have found a lot or material about creating marking type email with digest contents using HTML tables. I always find these a good source of humour because anybody who has ever tried to make a digest email that looks good in every client factor probably has less hair then I do (which isn't much).
In this post I'm going to look at how you can create a digest email in your OnPremise or Office365 Exchange infrastructure using EWS if your onPrem or in the Cloud or the Graph API if your in the cloud.
Two formatting options
The two formatting options I'll present in this post are first a simple HTML table with many rows one for each email eg
and the second is multiple tables with formatted rows which offers more flexibility in the information that your present eg
In the above example each email basically is a separate HTML table with some merged rows and I've used the BodyPreview property to make the information more useful. The format is more flexible as you can add or remove the summary properties you want to look at, eg for example from my other post on Summarising the Junk Email folder in Exchange this is an example of looking at the Email Authentication information for messages that are going to a distribution list and then being forwarding to a Mailbox in Office365 so both Authentication Results and Original Authentication Results header is available in this instance.
Making your digest clickable
The most useful part of a digest email should be easy access to the email your digesting so in my two examples above in the first the subject is a hyperlink that will take you to the underlying email and in the bottom example the MoreInfo text is a hyperlink that will take you to the underlying email. There are two different ways of making these links clickable that needs a little explanation.
The Outlook Protocol Schema Outlook://
The Outlook protocol Schema is a legacy that before Outlook 2007 used to be registered in the O/S so you could essentially have a clickable link that would open directly into an Outlook Item. However since 2007 as documented in https://support.microsoft.com/en-us/help/929590/known-issues-when-you-develop-custom-solutions-for-office-outlook-2007 this is no longer registered by the installer. However it is still useable with Outlook itself so if your targeting your digest to be useable within Outlook this is a good method. (However this format won't be understood in other clients like ActiveSync or OWA so its generally good for tech's that have some tolerance of the limitations and want this to work in Outlook)
WebLink to Outlook on the Web
Both EWS and REST provide a property that gives you the full URI that can be used to open the underlying item in OWA. In REST this is called the weblink property in EWS its the WebClientReadFormQueryString property. The property will work regardless of the client but will always try to open the item in a new browser window.
The Code - EWS
I've posted the code for digesting in EWS to my GitHub https://github.com/gscales/Powershell-Scripts/blob/master/Get-EWSDigestEmailBody.ps1 this module cmdlet will take a collection of EWS items as an Input and return a HTML String as an output. The Output will the serve as the Body of a Message you would then send in EWS. To demonstrate this I've updated my Generic EWS Item script from a few weeks back to return the necessary information for the Digest as well as I've included a simple send function to send the Digest email. This updated script is available in GitHub https://github.com/gscales/Powershell-Scripts/blob/master/GenericFolderAndItem.ps1
So to use this first we get the Items we want to digest eg the Last 10 items in the JunkEmail folder
Then depending if we want a basic or detailed digest with OWA or Outlook weblink you use the following
REST
I've added the Digest function to my Exch-Rest library which is available from the PowerShell Gallery https://www.powershellgallery.com/packages/Exch-Rest and GitHub https://github.com/gscales/Exch-Rest . It works the same as the EWS script I talked about above but lets look at a specific example
In this post I'm going to look at how you can create a digest email in your OnPremise or Office365 Exchange infrastructure using EWS if your onPrem or in the Cloud or the Graph API if your in the cloud.
Two formatting options
The two formatting options I'll present in this post are first a simple HTML table with many rows one for each email eg
and the second is multiple tables with formatted rows which offers more flexibility in the information that your present eg
In the above example each email basically is a separate HTML table with some merged rows and I've used the BodyPreview property to make the information more useful. The format is more flexible as you can add or remove the summary properties you want to look at, eg for example from my other post on Summarising the Junk Email folder in Exchange this is an example of looking at the Email Authentication information for messages that are going to a distribution list and then being forwarding to a Mailbox in Office365 so both Authentication Results and Original Authentication Results header is available in this instance.
Making your digest clickable
The most useful part of a digest email should be easy access to the email your digesting so in my two examples above in the first the subject is a hyperlink that will take you to the underlying email and in the bottom example the MoreInfo text is a hyperlink that will take you to the underlying email. There are two different ways of making these links clickable that needs a little explanation.
The Outlook Protocol Schema Outlook://
The Outlook protocol Schema is a legacy that before Outlook 2007 used to be registered in the O/S so you could essentially have a clickable link that would open directly into an Outlook Item. However since 2007 as documented in https://support.microsoft.com/en-us/help/929590/known-issues-when-you-develop-custom-solutions-for-office-outlook-2007 this is no longer registered by the installer. However it is still useable with Outlook itself so if your targeting your digest to be useable within Outlook this is a good method. (However this format won't be understood in other clients like ActiveSync or OWA so its generally good for tech's that have some tolerance of the limitations and want this to work in Outlook)
WebLink to Outlook on the Web
Both EWS and REST provide a property that gives you the full URI that can be used to open the underlying item in OWA. In REST this is called the weblink property in EWS its the WebClientReadFormQueryString property. The property will work regardless of the client but will always try to open the item in a new browser window.
The Code - EWS
I've posted the code for digesting in EWS to my GitHub https://github.com/gscales/Powershell-Scripts/blob/master/Get-EWSDigestEmailBody.ps1 this module cmdlet will take a collection of EWS items as an Input and return a HTML String as an output. The Output will the serve as the Body of a Message you would then send in EWS. To demonstrate this I've updated my Generic EWS Item script from a few weeks back to return the necessary information for the Digest as well as I've included a simple send function to send the Digest email. This updated script is available in GitHub https://github.com/gscales/Powershell-Scripts/blob/master/GenericFolderAndItem.ps1
So to use this first we get the Items we want to digest eg the Last 10 items in the JunkEmail folder
$Items = Invoke-GenericFolderItemEnum -MailboxName gscales@datarumble.com -FolderPath \JunkEmail -MaxCount 10 -Credentials $creds
Basic with Outlook links
$Digest = Get-EWSDigestEmailBody -MessageList $Item
Basic with OWA weblinks
$Digest = Get-EWSDigestEmailBody -MessageList $Item -weblink
Detailed Digests
For the detailed digest the code I've created has 5 information digest properties eg in the above example they are the HasAttachment,RetentionDate etc . With the code I've created I've made these dynamic so they can be any of the Strongly typed properties that are returned on a Message (or properties that you want to promote on the message with other code). So to make them dynamic I have 5 parameter properties InfoField1Name to InfoField5Name where you pass in the name of the property (on the message object) that you want to use in the Digest and it will then create a digest out of these props with a little plumbing in the code eg
$Digest = Get-EWSDigestEmailBody -MessageList $Items -Detail -InfoField1Name HasAttachments -InfoField2Name RetentionDate -InfoField3Name Sensitivity -InfoField4Name ItemClass -InfoField5Name FolderPath
If you want Weblinks instead of the Outlook protocol links use the -weblink switch in the above example.
Now we have the Digest HTML in the $Digest variable we can send that as an email in EWS using the included function in the Generic Item script eg
Send-EWSMessage -To gscales@datarumble.com -Body $Digest -Subject "Test Digest" -Credentials $creds -MailboxName gscales@datarumble.com
I've added the Digest function to my Exch-Rest library which is available from the PowerShell Gallery https://www.powershellgallery.com/packages/Exch-Rest and GitHub https://github.com/gscales/Exch-Rest . It works the same as the EWS script I talked about above but lets look at a specific example
So to use this first we get the Items we want to digest eg the Last 10 items in the JunkEmail folder
$Items = Get-EXRWellKnownFolderItems -WellKnownFolder JunkEmail -Top 10 -TopOnly:$true -MailboxName gscales@datarumble.com -BatchReturnItems -ReturnSize -ReturnEntryId -ReturnSentiment
Then depending if we want a basic or detailed digest with OWA or Outlook weblink you use the following
Basic with Outlook links
$Digest = Get-EWSDigestEmailBody -MessageList $Items
Basic with OWA weblinks
$Digest = Get-EWSDigestEmailBody -MessageList $Items -weblink
Detailed Digests
For the detailed digest the code I've created has 5 information digest properties eg in the above example they are the HasAttachment,etc . With the code I've created I've made these dynamic so they can be any of the Strongly typed properties that are returned on a Message (or properties that you want to promote on the message with other code). So to make them dynamic I have 5 parameter properties InfoField1Name to InfoField5Name where you pass in the name of the property (on the message object) that you want to use in the Digest and it will then create a digest out of these props with a little plumbing in the code eg
$Digest = Get-EXRDigestEmailBody -MessageList $Items -Detail -InfoField1Name hasAttachments-InfoField2Name isRead -InfoField3Name -InfoField4Name importance -InfoField5Name Sentiment
If you want Weblinks instead of the Outlook protocol links use the -weblink switch in the above example.
Now we have the Digest HTML in the $Digest variable we can send that as an email in EWS using the included function in the Generic Item script eg
Send-EXRMessage -To gscales@datarumble.com -Body $Digest -Subject "Test Digest" -MailboxName gscales@datarumble.com