Microsoft introduced a while ago the concept of safe links. Microsoft has something called “Microsoft Defender for Office 365” that protects your company from malicious links that can be used for several nefarious actions. By scanning the URL against their database of potential threats, they can ensure that, when you click it, you are more protected from threats.
But when it comes to automation, there’s a nasty side effect. When we receive an URL of a file, we can automate the process of getting the file and saving it, but if the link is a “safe link,” then we have a problem because the link doesn’t point to a file. We can’t use the strategy we used in our “How to download a file from a link”, but we can use a different strategy to allow us to download the file.
Let’s explore it today.
The issue
The issue is that we get the following error when we try to download the file using the URL from the safe link and an “HTTP Request” action.
Notice that Power Automate doesn’t indicate that the URL is incorrect but indicates that the “object moved”. This is due to how safe links work, and it’s quite well done.
When you press an URL, it redirects automatically to Microsoft’s servers. They validate it and redirect to your destination URL if all is good. This way, if all is okay with the ULR, you only see a small “jump” in your browser and navigate to your destination URL without even noticing that something happened. But if something’s wrong, you’re redirected to a safe place instead.
The issue is this “redirection” because Power Automate will consider it an error. But there’s a technique to overcome this, so let’s explore it.
The solution
In Power Automate, you can define when an action will run. Automatically, all actions will run if the previous one ran successfully, but we can indicate to Power Automate that we want to run other actions when something goes wrong. This is useful when you want o recover from errors. I go over how to do that in this article, so if you’re curious, please take a look.
Let’s build a sample Flow.
If you have a direct link to a file, this is all you need to get its contents. But as we’ve seen before, we get an error when we have a file with a safe link. But if we look at the error message, we notice something:
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="https://manueltgomes.com/wp-content/uploads/2021/09/TEMPLATEHowtofetchmulti-selectcolumnsinSharePoint_20210926141943.zip">here</a>.</h2>
</body></html>
Our destination URL is right there, so we can get it and try again to download it.
Let’s add a “Scope” action that contains the logic to download the file like this:
We’ll add two “Compose” actions, the first that will get a piece of the URL and the other that will clean it. It is simple. We split the whole error message by “href=“to get the URL’s start and then do a substring with the end of the URL. We’re adding two “Compose” actions because we want to do things slowly and have some information to debug the content in case something goes wrong. Here’s the full Flow.
The first “compose” action has the following formula:
last(split(body('Tries_to_get_the_URL'),'href="'))
And the second has the following formula:
substring(outputs('Get_the_new_URL'),0,indexOf(outputs('Get_the_new_URL'),'"'))
Let’s see the result when the Flow runs to understand better what’s happening.
We start with the following:
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="https://manueltgomes.com/wp-content/uploads/2021/09/TEMPLATEHowtofetchmulti-selectcolumnsinSharePoint_20210926141943.zip">here</a>.</h2>
</body></html>
We indicate to Power Automate that we want to split by “href=” so we get two parts:
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a
And
https://manueltgomes.com/wp-content/uploads/2021/09/TEMPLATEHowtofetchmulti-selectcolumnsinSharePoint_20210926141943.zip">here</a>.</h2>
</body></html>
By using the “last” function we say to Flow that, regardless of how many things you find before the “href=“, we only want the second part. But now, we still have some characters we’re not interested in after the URL. Not a problem since we can remove them with the second formula. We use the “indexOf” function to check where are the first double quotes, and we use the “substring” function to indicate that we want everything before that position.
Now that we have a “clean” URL, we can add it to an “HTTP Request” action and get the file’s contents.
You can provide the body with a “Create file action” to save the file in the destination location of your choice.
Final thoughts on safe links
Safe links are pretty good at doing a lot of complex security validations for us, so be careful using this strategy. You’re downloading a file directly to its source without validating it, so ensure it comes from a reputable place.
Also, I’ve seen some solutions that involve getting the URL directly from the safe link. I didn’t propose this because it makes things quite hard and is error-prone. If it works for you, go for it, but I think this solution is “cleaner” and more sturdy, avoiding issues like special characters.
Photo by Moja Msanii on Unsplash