Objective: Move a Mail into an Outlook subfolder that does not exist. That is why I have to create that folder and subfolder in Outlook.
Possible solution: I decided to try ExchangeWebservice to achieve the creation of the folder and subfolder because I could not find an official package from Uipath to do it. This code must be executed in Uipath with Invoke Code.
string[] args ={appId, sharedMailboxAddress, mailboxAddress, folderPath};
static async System.Threading.Tasks.Task Main(string[] args)
{
System.Console.WriteLine("### Start of create Folder ###");
// Configure the MSAL client to get token
var pca = Microsoft.Identity.Client.PublicClientApplicationBuilder.Create(args[0]).Build();
// The permission scope required for EWS access
var ewsScopes = new string[] { "https://outlook.office365.com/EWS.AccessAsUser.All" };
try
{
Microsoft.Identity.Client.AuthenticationResult authResult;
try
{
System.Console.WriteLine("Make the silent token request");
// Make the silent token request
var accounts = await pca.GetAccountsAsync();
authResult = await pca.AcquireTokenSilent(ewsScopes,accounts.FirstOrDefault()).ExecuteAsync();
}
catch(Microsoft.Identity.Client.MsalUiRequiredException ex)
{
System.Console.WriteLine($"{ex}");
System.Console.WriteLine("Make the interactive token request");
// Make the interactive token request
authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();
}
// Configure the ExchangeService with the access token
System.Console.WriteLine("Configure the ExchangeService with the access token");
var ewsClient = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
FolderView fv = new FolderView(100);
// Set Root Mailbox FolderId
System.Console.WriteLine($"Shared Mailbox: {args[1]}");
FolderId RootMailboxFolderId = null;
if(args[1]!="")
{
RootMailboxFolderId = new FolderId(WellKnownFolderName.Inbox, args[1]);
}
else
{
RootMailboxFolderId = new FolderId(WellKnownFolderName.Inbox);
}
string s = args[3];
string[] newFolders = s.Split('\');
var parentFolderId = RootMailboxFolderId;
foreach(string folder in newFolders)
{
System.Console.WriteLine($"Parent folder: {parentFolderId}");
var findChildFolder = ewsClient.FindFolders(
parentFolderId,
new SearchFilter.SearchFilterCollection(
Microsoft.Exchange.WebServices.Data.LogicalOperator.Or,
new SearchFilter.ContainsSubstring(FolderSchema.DisplayName, folder)),
fv);
if(findChildFolder==null)
{
//Source: https://learn.microsoft.com/en-us/previous-versions/office/developer/exchange-server-2010/dd633637(v=exchg.80)
// Create a generic folder with a valid ExchangeService object
Folder newFolder = new Folder(ewsClient);
// Set the folder properties
newFolder.DisplayName = folder;
// Save the new folder in a specified parent folder.
newFolder.Save(parentFolderId);
parentFolderId = newFolder.Id;
System.Console.WriteLine($"Child Folder created successfully");
}
else
{
System.Console.WriteLine($"Child Folder {folder} exists");
}
}
}
catch (Exception ex)
{
System.Console.WriteLine($"Error: {ex.Message}");
//return ex.Message;
}
}
Main(args);
Current issues: When I execute my code and it implements the below piece of code, the code does not continue in the invoke code and jumps directly to the next activity “Move Exchange Mail Message” in my workflow
authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();
If I understood correctly this method run asynchronously and the keyword await suspend while the user types its credentials. I have two questions:
-
Should I keep going on this approach or is there another easy solution to solve my requirement?
-
If this is the right approach, How should I keep the execution without jumping to the next activity?.
4