Top
Microsoft Flow

Embed images in e-mail’s body using Microsoft Flow


I was working on my newsletter’s solution, aimed to automatically send prepared messages hosted in my SharePoint. Naturally, newsletters often contain images. Lots of them frankly speaking. The most straightforward approach was to insert them as a URL to the physical file stored in SharePoint (described here).  However, in that approach, if a recipient has no access to the site, where the file is hosted or is not yet logged in, the images won’t show up.

How to embed images into the body?

There are in fact three approaches:

  1. The “src” attribute pointing to the file hosted somewhere;
  2. The “src=cid” (Content-ID) – so the internal linking in the e-mail, if the file is physically attached to the e-mail it can be displayed inline using the “cid” (source);
  3. Embedding image using base64 encoded string, and the “src=data:image/jpeg;base64,<base64-encoded-image>” (or png, or gif) value of the src attribute (source).

Ad. 1 – it works like a charm, but as I mentioned above – only when user really has an access to the file.

Ad. 2 – Flow allows you to add only one attachment. You cannot add multiple (you can vote for it here). So the approach with showing images inline using the “cid method” is not very possible in case you want to show more than one file. 

Ad. 3 – seemed to be feasible in Flow, however I was also aware, that unfortunately most of the e-mail clients do not support it. This old, but still up-to-date post shows support for base64 encoded images embedded in e-mails: https://www.campaignmonitor.com/blog/email-marketing/2013/02/embedded-images-in-html-email/

The base64 approach

As I wrote above, that is fairly easy to do. I managed to do it in couple of steps (having in mind that pure regular expressions are not yet available for Flow, vote for them here):

  1. First I processed the newsletter’s body, to extract all images paths. I did that using the “split” action using the ‘ src=” ‘ token (yes, with a quote).
  2. Then for each item from that array I checked, whether the string starts from “http” – if yes that meant the element is an URL to an image.
  3. I then extracted the image URL, using the following expression (so from its beginning to the closing quote):
    substring(item(), 0, indexOf(item(), '"'))
  4. Then I used the action to get file contents from SharePoint using its path (split to the absolute site URL and then site-relative URL to the file).
  5. In return I received an object, from which I needed to get the “$contents” attribute and using it replace with the original “src” attribute’s value in my newsletter’s body. For that purpose I used the following expression:
    replace(variables('var_Body_Str'), outputs('Image_Path'), concat('data:image/png;base64,', body('Get_file_content_using_path')?['$content']))

And basically that did the trick. When I previewed my Flow execution I saw that the HTML is constructed properly. When I opened sent e-mail in Outlook Web Access it also worked fine:

Microsoft Flow insert base64 encoded images to the e-mail

 

Thanks for reading! Do you have other ideas? Please share them! 🙂


Tomasz Poszytek

Hi, I am Tomasz. I am expert in the field of process automation and business solutions' building using Power Platform. I am Microsoft MVP and Nintex vTE.

23 Comments
  • Anton Zamotki

    hi

    so what do i writein the body email then : s

    March 26, 2018 at 1:26 pm Reply
    • Tomasz Poszytek

      Hi! You can write whatever HTML you want. My approach just replaces images in the HTML body contents with their base64 definitions.

      April 9, 2018 at 9:54 am Reply
  • Sharan sharepoint

    Hi Tomasz,
    i am new to using expression on microsoft flow.
    Could you please tell me more how can i extract image using expression?

    April 12, 2018 at 12:55 pm Reply
    • Tomasz Poszytek

      Hi, sure! I’m doing it in less straightforward way. First, I split the whole message body using the ‘src=”‘ token: split(variables('var_Body_Str'), 'src="'). Then, for each token (split creates an array), I am extracting substring from its beginning until the quote char, what should always return a full image path: substring(item(), 0, indexOf(item(), '"')). Then, I am building an absolute path to the image and using action “Get file content using path” I am getting file contents which then I am transforming to the right base64 structure.

      April 12, 2018 at 2:34 pm Reply
  • Carlos Vaquedano

    Could you help me?

    on a flow, i need to first get an embed image (or more than one) from an e-mail body then i need to send it on an another e-mail but now as an attachment.

    It is very similar to what you already do.
    I have a hard time following what needs to be done. Would you give me a step by step for what I need?

    October 21, 2018 at 8:46 pm Reply
    • Tomasz Poszytek

      Well, it might be similar, but mustn’t 🙂 First, are you sure the images inside your e-mail are added as references to an asset stored elsewhere? So that in e-mail’s body HTML you can find “ October 25, 2018 at 8:21 am Reply

  • Dipan Das

    Looks great! Just a request, can you post screenshots of your steps. I am really new to Flow, so I keep getting lost.

    October 25, 2018 at 9:22 pm Reply
    • Tomasz Poszytek

      I think the post itself is very descriptive. Where are you getting stuck exactly?

      December 5, 2018 at 10:04 pm Reply
  • Dipan Das

    Hi Tomasz,

    Thank you for the solution. Will be possible for you to send screenshots of the steps. Looks like I am not getting the steps correctly.

    December 20, 2018 at 11:20 pm Reply
  • Susan Vijay

    this works only for OUtlook web not the native desktop version

    February 11, 2019 at 9:37 am Reply
    • Tomasz Poszytek

      I’m nearly sure I checked it also for desktop clients, however that is possible it only works for online client 🙂 Nevertheless this way of embedding images into e-mails, using base64 strings, used to be working for desktop clients for sure! 🙂

      February 18, 2019 at 11:14 am Reply
  • Josiah Owens

    Hi Tomasz, can you assist in adding image to email body for desktop client. Specific steps would be helpful! Thanks.

    June 12, 2019 at 9:54 pm Reply
    • Tomasz Poszytek

      Hi, what exactly are you missing? Where are you stuck?

      June 17, 2019 at 12:44 pm Reply
  • Hikmat Noorebad

    Hi Tomasz,

    Thanks for the posts, I am having issue with this hope you can help!

    I am using OneDrive Get file content

    That gives me this output!
    {
    “$content-type”: “image/png”,
    “$content”: “iVBORw0KGgoAAAANSUhEUgAA….”
    }

    Then I get base64 by using the function in a compose action:
    base64(body('Get_file_content'))

    Then I use a second compose to add the extra bits:
    concat('data:image/png;base64,', outputs('Compose'))

    Finally, I just the output of the second compose in the email body:

    However, the image does not show up I get empty image tag in the email!

    I have tried this as well:
    concat('data:image/jpeg;base64,', body('Get_file_content')?['$content'])
    Still no luck!

    Thanks,

    October 17, 2019 at 1:45 am Reply
    • Tomasz Poszytek

      Where are you trying to display it? What application?

      October 17, 2019 at 6:59 pm Reply
  • Guillermo

    Hello Tomasz, Could you share screenshots an the code for this clever solution?
    I have an email coming with a signature included in a cid attachment, when converting to HTML the signature is gone so I wanted to find and encode the image, I’m new to MS Flow.
    Thank you in advance.

    April 9, 2020 at 6:48 am Reply
  • Roni

    Hello Tomasz, i followed the logic in the post above and managed to embed the image using Base64 encoding. The image shows in outlook desktop and doesnt render in outlook web or the app.

    April 29, 2020 at 3:29 pm Reply
    • Tomasz Poszytek

      That’s the limit of the technology. The image this way will not be displayed in Gmail either. To avoid it you must store images somewhere publicly (like Azure Storage) and reference to them.

      April 30, 2020 at 12:11 pm Reply

Post a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.