How to use images in outgoing emails
In general, there are 3 ways to embed images in your emails:
- Inline embedded CID images
- Inline embedded Base64 encoded images
- Linked images (specified via URLs)
Embed an image using CID (Content-ID) in the HTML email body, while attaching it to mail message (as Linked Resource).
Cons: has to be done programmatically and increases the email size.
Embed an image directly in the HTML email body as the Base64 encoded string.
Cons: has to be done programmatically, might be blocked in some email clients and increases the email size.
Embed an image using its full URL path in the HTML email body; the image needs to be stored on a public cloud storage.
Cons: Might be blocked in some email clients and requires download from external servers.
Are images supported in the email body of outgoing emails in D365FO
When it comes to emailing reports in D365FO, there is no support for the email body OOTB, so we can't really talk what's supported and what's not 😀.
On the other hand, for outgoing emails based on Organization and System email templates sent out from D365FO using Email processing (Batch email sending status and Email distributor batch), you can edit the email body and use static Linked images OOTB.
If you decide to customize your code and support email messages with embedded CID or Base64 encoded images, you will stumble upon a new problem: D365FO Exchange email provider doesn't support CID images.
As you know, there are 2 types of non-interactive Email providers in D365FO: Exchange and SMTP. And unlike Exchange, SMTP email provider supports all 3 types of embedded images. So, one could say that SMTP email provider is the way to go in D365FO to support embedding images in outgoing emails. But wait, bad news! Recently, Microsoft announced Deprecation of Basic authentication in Exchange Online, which currently represents the only authentication option to use SMTP email provider in D365FO 😢 (i.e. to authenticate sending user on Exchange Online server with username and password). What now?!
How to overcome D365FO emailing limitations for embedded images
Docentric Free Edition enables emailing reports with the email body, supporting all 3 types of embedded images (CID, Base64 and Linked images). Additionally, you can use Email processing for emailing reports or preconfigured Report Email templates. Also, you can use Email templates improved by Docentric to design Alert and Workflow notifications, using the same Email body editor that supports all 3 types of embedded images.
This is how Docentric Email body editor looks.
In one of the next releases, Docentric will deliver:
- MS OAuth 2.0 authentication for D365FO SMTP email provider. Yay!
- Optional fix for converting CID images to Base64 encoded images for D365FO Exchange email provider, please see below.
Convert CID to Base64 encoded images for D365FO Exchange email provider
If you are using Docentric, then you might have been using SMTP email provider and CID images in your outgoing emails so far. If you need to switch to Exchange (to avoid additional mail server configuration or because of deprecation of Basic authentication), you can use the following extension to convert all CID images in your outgoing emails to Base64 encoded images, which are supported by D365FO Exchange email provider as well.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/// <summary> /// The class SysMailerExchange_WE_Extension is an extension of the class SysMailerExchange. /// </summary> [ExtensionOf(classStr(SysMailerExchange))] final class SysMailerExchange_WE_Extension { /// <summary> /// Sends the message to the Exchange server, logging appropriate telemetry and inserting history records. /// </summary> /// <param name = "_message">The message to be sent.</param> /// <param name = "_interactive">Indicates if the message was created interactively.</param> /// <param name = "_correlationId">The ID that correlates the related telemetry.</param> /// <returns>True if the message was successfully sent, else false.</returns> protected boolean sendMessage(System.Net.Mail.MailMessage _message, boolean _interactive, guid _correlationId) { if (_message != null) { // Replace CID embedded images with Base64 embedded images in the provided email message. DocEmailMngHelper::replaceCIDWithBase64EmbeddedImages(_message); } return next sendMessage(_message, _interactive, _correlationId); } } |
This is an optional extension, and you are free to use it!
Of course, there is a method in our Docentric Free Edition library DocEmailMngHelper::replaceCIDWithBase64EmbeddedImages(), so you are welcome to install it.
If you are not eager to do so, check the source method below 😀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
/// <summary> /// Replaces embedded CID images with Base64 encoded images in the provided email message. /// </summary> /// <param name = "_mailMessage">Email message</param> public static void replaceCIDWithBase64EmbeddedImages(System.Net.Mail.MailMessage _mailMessage) { if (_mailMessage == null) { return; } // Replace CID embedded images with Base64 embedded images AlternateViewCollection alternateViews = _mailMessage.AlternateViews; for (int i = 0; i < alternateViews.Count; i++) { AlternateView alternateView = alternateViews.get_Item(i); if (alternateView.ContentType.MediaType != 'text/html') { continue; } LinkedResourceCollection linkedResources = alternateView.LinkedResources; for (int j = 0; j < linkedResources.Count; j++) { LinkedResource linkedResource = linkedResources.get_Item(j); if (linkedResource.ContentId == null || linkedResource.ContentStream == null || (!(linkedResource.ContentStream is MemoryStream)) || linkedResource.ContentType.MediaType == null || !linkedResource.ContentType.MediaType.StartsWith('image/', System.StringComparison::OrdinalIgnoreCase)) { continue; } str cidString = System.String::Format('cid:{0}', linkedResource.ContentId); str base64Image = DocGlobalHelper::convertToBase64String((linkedResource.ContentStream as MemoryStream).ToArray()); str dataString = System.String::Format('data:{0};base64,{1}', linkedResource.ContentType.MediaType, base64Image); _mailMessage.Body = _mailMessage.Body.Replace(cidString, dataString); // Delete CID attachment linkedResources.RemoveAt(j); j--; } } } |
See also
Email reports with images from database in the email body in D365FO >>
Troubleshooting techniques for solving emailing issues in D365FO >>
Batch email sending status improvements >>
Email or print an invoice from D365FO, depending on the customer’s email address availability >>
Emailing related articles >>