How to enumerate Mail Folders with all child folders

Brown, Micah 1 Reputation point
2022-06-14T12:32:07.38+00:00

Currently, as far as I can tell, Microsoft graph offers 2 primary endpoints for outlook mail folders according to

https://learn.microsoft.com/en-us/graph/api/user-list-mailfolders?view=graph-rest-1.0&tabs=http

List mail folders and List child folders - meaning just to build the folder hierarchy in my app, I need to make recursive REST API calls - which is very slow and very bad.

Is there any way to get microsoft to just return all folders at once?

If it is not then how to make a recursion on child folders and it's sub folders.

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,672 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Shivam Dhiman 5,946 Reputation points
    2022-06-14T15:39:10.09+00:00

    Hi @Brown, Micah

    You can use GET /me/mailFolders/{id}/childFolders to get a MailFolder and Sub Folders also in single API call.
    For example: There is a subfolder present in my inbox, Using the below API we can get the SubFolder-id:

    https://graph.microsoft.com/v1.0/me/mailFolders/inbox/childFolders  
    

    After this use the SubFolder-id in the below API to get subfolders present in that Folder.

    https://graph.microsoft.com/v1.0/me/mailFolders/{SubFolder-id}/childFolders  
    

    Similarly you can traverse through all subfolders.

    Further you can refer to these similar posts-

    Hope this helps,

    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have further questions about this answer, please click "Comment".

    1 person found this answer helpful.
    0 comments No comments

  2. Glen Scales 4,431 Reputation points
    2022-06-15T00:36:59.537+00:00

    The beta endpoint will return all folders (eg it does a deep traversal) https://graph.microsoft.com/beta/me/mailfolders?$select=displayName&$top=1000 however this is been in beta for a number of years and very few changes seem to get made .

    If you really need to get all folders and child folders you can get the graph to return the first two levels using https://graph.microsoft.com/v1.0/me/mailfolders?$top=1000&$expand=childFolders you can page in max lots of 1000 folders. With the remaining subfolders eg 3 deep check the childFolderCount and then use batching https://learn.microsoft.com/en-us/graph/json-batching with a max concurrency of 4 requests (else you'll get throttled) but similarly you can get two levels of folder using expand. The performance of this is generally not that bad as you can reduce the number of requests you need to make to a get the full hierarchy to minimum on most mailboxes the downside is it increases complexity a lot.

    1 person found this answer helpful.

  3. Glen Scales 4,431 Reputation points
    2022-06-16T03:55:12.15+00:00

    Using the GraphSDK something like

     private static void BatchChildFolders(List<string> folderIds, GraphServiceClient graphServiceClient, List<MailFolder> folders)  
             {  
                 var baseRequestURL = "https://graph.microsoft.com/v1.0/Me/MailFolders";  
                 BatchRequestContent batchRequestContent = new BatchRequestContent();  
                 foreach (string folderid in folderIds)  
                 {  
                     var childFolderBatchRequest = graphServiceClient.Teamwork.Request().GetHttpRequestMessage();  
                     string requestUrl = baseRequestURL + $"/{folderid}/childFolders?$expand=childFolders&$top=1000";  
                     childFolderBatchRequest.RequestUri = new Uri(requestUrl);  
                     batchRequestContent.AddBatchRequestStep(new BatchRequestStep(folderid, childFolderBatchRequest));  
                 }  
                 var batchResults = graphServiceClient.Batch.Request().PostAsync(batchRequestContent).GetAwaiter().GetResult();  
                 foreach (string folderid in folderIds)  
                 {  
                     using (var batchResult = batchResults.GetResponseByIdAsync(folderid).GetAwaiter().GetResult())  
                     {  
                         if (batchResult != null)  
                         {  
                             if (batchResult.StatusCode == System.Net.HttpStatusCode.OK)  
                             {                              
                                 var mailFoldersResponse = batchResults.GetResponseByIdAsync<MailFolderChildFoldersCollectionResponse>(folderid).GetAwaiter().GetResult();  
                                 foreach(var mailFolder in mailFoldersResponse.Value)  
                                 {  
                                     Console.WriteLine(mailFolder.DisplayName);  
                                 }                                 
                             }  
                             else  
                             {  
                                 //errir  
                             }  
                         }  
                     }  
                 }  
             }  
    

    Where you passing in a list of FolderIds you want to batch

    0 comments No comments