Power Automate: How to generate an URL to an email?

Bookmark

I got this question on my “Microsoft Planner: Send an email and create task” from Kristen McCarty (thanks for the excellent question) regarding how to generate a URL that opens the email directly on Microsoft’s Outlook. It’s not difficult, but we need to understand what’s happening so that the formula makes sense.

The expression

Let’s start with the expression to move on with your life, but if you’re curious, I will explain it in the tail in the next section.

concat(‘https://outlook.office.com/mail/inbox/id/’,replace(encodeUriComponent(triggerOutputs()?[‘body/conversationId’]),’_’,’%2B’))

So the formula uses the following functions:

We’re concatenating the URL for Office 365 Outlook’s email inbox plus the encoded ID of the message.

Please note that this formula only works if Microsoft maintains the same structure. If something changes, Microsoft won’t keep backward compatibility or warn us, so if it doesn’t work, please let me know, and we’ll try to figure out how to create another solution

Let’s look at the structure.

The overall structure

Microsoft defined the structure, so we can’t do a lot regarding that, but we can use the pieces to get to that URL.

The first part is the URL to Office 365 Office inbox. The URL is quite descriptive and indicates everything that we need to know. We want the item in the inbox with an ID.

We get this URL by opening any email on the inbox, like this:

We get something like this:

https://outlook.office.com/mail/inbox/id/AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM%2Bvnl2WtWFEvXLq8kH6kcs%3D

Let’s focus on the ID.

Please note that this ID is exclusive to this email on my environment. If you test on your environment you’ll get different IDs.

Let’s get the ID and parse it.

When we get the ID from somewhere

Using Power Automate, we can get the ID from the “When a new email arrives” trigger . In the trigger, we get the following:

{
    ...
    },
    "body": {
        "id": "AAMkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgBGAAAAAACvIW8tOruVQq_P-p9WUHDSBwC8MGg1BhiUTbxUOcauwKX2AAAAAAEMAAC8MGg1BhiUTbxUOcauwKX2AAKOYs4XAAA=",
        "receivedDateTime": "2022-02-28T14:24:50+00:00",
        "hasAttachments": false,
        "internetMessageId": "<3903be0c-ba36-467e-9213-93ded87daa9c@Spark>",
        "subject": "teste",
        "bodyPreview": "Manuel T Gomes\r\n\r\nFounder,\r\n\r\nSKILLFUL SARDINE",
        "importance": "normal",
        "conversationId": "AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM_vnl2WtWFEvXLq8kH6kcs=",
        "isRead": false,
        "isHtml": true,
        "body": "<redacted>",
        "from": "manuel@skillfulsardine.com",
        "toRecipients": "manuel@manueltgomes.com",
        "attachments": []
    }
}

I redacted some parts of the reply because they don’t add much value here. Looking at the message, we see that the email has an “ID,” but not quite what we need. It doesn’t fit the ID we’re looking for:

AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM%2Bvnl2WtWFEvXLq8kH6kcs%3D

But if we look at the “conversationId”, we can get almost what we need. We see the “%2B” and “%3D” values that compare with the original string map to the “_” and “=“ respectively.

We know how to encode these characters using the “encodeUriComponent” function. So let’s test it with a compose action.

encodeUriComponent(triggerOutputs()?['body/conversationId'])

We’ll get:

AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM_vnl2WtWFEvXLq8kH6kcs%3D

Almost there. The ID has the underscore still not encoded. I tried with other functions, and it’s not encoded properly, so we need to do it ourselves by using the replace function. If we do:

replace(encodeUriComponent(triggerOutputs()?['body/conversationId']),'_','%2B')

We’ll get:

AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM%2Bvnl2WtWFEvXLq8kH6kcs%3D

Does it look familiar? It’s exactly the URL that we need.

Building the URL

Finally let’s build the URL. This is the easy part since we only need to concatenate all the parts by using the concat function. Here’s the expression:

concat('https://outlook.office.com/mail/inbox/id/',replace(encodeUriComponent(triggerOutputs()?['body/conversationId']),'_','%2B'))

With this we’ll get:

https://outlook.office.com/mail/inbox/id/AAQkADhhNzYyNDgxLTNkNGYtNDhiNS1iOWUzLTllMDBmMzEzOTA4MgAQAM%2Bvnl2WtWFEvXLq8kH6kcs%3D

If you open this in your browser (with the ID generated by your email, otherwise you’ll get an error), you’ll get the email you’re looking for.

Final thoughts

The expression is simple, but it has this small gotcha that is simple once you know about it, but you can spend quite some time until you notice that the ID is not the same.

Have a suggestion of your own or disagree with something I said? Leave a comment or interact on Twitter and be sure to check out other Power Automate-related articles here.

Tweet

How to generate an URL to an email in Power Automate. It looks simple, but there’s a small “gotcha” that you should know if you want to save time, of course :).

Photo by Tamanna Rumee on Unsplash

Manuel Gomes

I'm a Project Manager with experience in large projects and companies. I've worked in the past for companies like Bayer, Sybase (now SAP) and I'm currently working for Pestana Hotel Group.

View all posts by Manuel Gomes →

Leave a Reply

Your email address will not be published.