Ive been doing a few posts about Power Automate and Outlook in Office 365 recently and one of the things I needed to do was workout what the folder ID is for a folder. You dont seem to be able to do this from the UI so I needed to put together a flow which could get the id.
The input to my flow would be a json object like below and id call my flow over HTTP and use the Content-Type = application/json header
{
"FolderPath":"Inbox\\Read\\CSC"
}
I would then do some stuff and just return a string which was the id.
Background
First off a bit of background about graph api. I can use graph explorer to explore parts of my inbox using the mail API. Graph explorer is on this link:
https://developer.microsoft.com/en-us/graph/graph-explorer
I can authenticate my user and approve consent to use some of the API’s and I would be able to use a url like below to execute a query for my inbox folder:
https://graph.microsoft.com/beta/me/mailFolders?$filter=displayName eq 'inbox'
I would get a response like:
{
"@odata.context": "https://graph.microsoft.com/beta/$metadata#users('0ebd625f-244b-42f3-8628-6f77c8d1ba0e')/mailFolders",
"value": [
{
"id": "AAMkADIwOTJmN2E4LTllOTUtNGFmZC05NzhiLTMzMzJjOGFhNDcwYQAuAAAAAAAuGudwjWhtRpIMe7a_sJ6uAQCGSHbTe4MbQ7gmtUzO23QnAAAApxV0AAA=",
"displayName": "Inbox",
"parentFolderId": "AAMkADIwOTJmN2E4LTllOTUtNGFmZC05NzhiLTMzMzJjOGFhNDcwYQAuAAAAAAAuGudwjWhtRpIMe7a_sJ6uAQCGSHbTe4MbQ7gmtUzO23QnAAAApxVxAAA=",
"childFolderCount": 12,
"unreadItemCount": 0,
"totalItemCount": 0,
"wellKnownName": "inbox",
"isHidden": false
}
]
}
The challenge is when you want to use sub folders, you cant just supply a path, you need to then use the folder id for the parent and then query its sub folders. For example to see the children of a folder id use:
https://graph.microsoft.com/beta/me/mailFolders/{FolderID}/childFolders
Fortunately I can use the same filter I used earlier to query for a specific sub folder too which means I can create a flow which will navigate down the tree structure of a path I supply to get the id for the bottom folder in my list. If we take a look at my flow it would look like below:
Id start with my request trigger accepting the json input
Id then initiate some variables:
- Current folder id will track the id for the folder each time I query it navigating down the tree
- Graph API response is what ill copy the response from my query of graph api to so I can parse it later
- Count is what ill use to track how many times I query graph api. On the first call for the top level folder the API call is slightly different to the children
Next ill split the path input string with the \ character so I have an array:
One point to note here is that the input object is json so I will need to escape my path. The path Inbox\\Read\\CSC would result in the array shown below
Next ill loop over the array and call graph API once for each item in the array
You can see below how I use the condition so that the first time I call graph API I am querying my root folders for the folder called the name of the first element in the array and then subsequently I will be using a slightly different url where it will use the ID from the last folder I queried and then use a folder of that folders sub-folders.
By saving the response to a string variable as the format is the same each time for the property im interested in I can then just use 1 parse json action as shown below.
The json schema used in this action is:
{
"type": "object",
"properties": {
"@@odata.context": {
"type": "string"
},
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
]
}
}
}
}
Next I can extract the id from the response json which ill use set variable action to set my currentFolderId. The designer will put this in a loop anyway but there will be only 1 response to match the folder name queried.
Ill then increment the count variable each time we go through the loop.
Point to Note: Set the concurrency on your apply to each loop to 1 in this flow
The flow will now query each folder down the path as it goes across the array and then at the end we will have the id for the last folder which is then returned by the response shape.
I can now use this flow via HTTP as a helper flow when I have use cases where I need to dynamically work with outlook folders for Office 365 when I can supply a path and it will workout the folder Id I need to use.
Example Usage
One example where I could use this is when moving emails to folders dynamically when I dont want to hard code the path with the designer. I could get the path from somewhere and query for the Id based on the folder path then I can use the move email shape as shown below with the id supplied at runtime.
One point to note is that I need to supply id:: before the id as this is what the connector needs.