Pieter van der Westhuizen

The Office 365 API – OneDrive / Files API

SkyDrive, Windows Live SkyDrive and Windows Live Folders were all cloud storage offerings provided by Microsoft. In January 2014, Microsoft renamed SkyDrive and SkyDrive Pro to OneDrive and OneDrive for Business respectively. An interesting fact was that they had to change the name because of a lawsuit by British broadcaster BskyB that stated the word “Sky” infringes on their trademark.

It is important to know that there is indeed a distinction between OneDrive and OneDrive for Business, especially if you’re a developer and are planning on integrating with either. It appears that the two services provides different authentication services, so in order to integrate with OneDrive you’ll need to sign up for a Microsoft Account and to integrate with OneDrive for Business you’ll need an Office 365 subscription. You can read more about it on the OneDrive Developer site.

From what I’ve read it does look like Microsoft is working hard to create a unified API for both services, so keep an eye on OneDrive in the future, there are exciting things to come!

With that, let us get on to today’s article in which we’ll create a Microsoft Outlook Add-in, using Add-in Express, that will integrate with OneDrive for Business and give our users the ability to attach a file to an email directly from OneDrive.

Azure application setup and permissions

We’ve covered creating and setting up an application in Azure AD in a previous article, Office 365 API – authentication & setup, so we won’t go into too much detail on creating the application in Azure AD. Instead I’ll only cover the permissions required to integrate with OneDrive for Business.

Once you’re logged into your Azure AD admin console, create the application and scroll down to the “permissions to other applications” section of the page. Click on the green “Add application” button and select Office 365 SharePoint Online from the list.

Click on the green 'Add application' button and select Office 365 SharePoint Online from the list.

From the Delegated Permissions list, only select “Read and write user files“.

Select 'Read and write user files' from the Delegated Permissions list.

It is interesting to note that you have to select SharePoint in order to work with OneDrive for Business – this appears to be the main difference between OneDrive for Business and OneDrive. In essence, the former is a special implementation of SharePoint.

With our application and its permissions setup, we can now start building the Outlook Add-in. Of course there is no better toolset for the job than Add-in Express!

Creating the OneDrive Outlook add-in

Begin by starting Visual Studio 2015. Yes, Add-in Express for Office and .net fully supports Visual Studio 2015 with our latest version. Create a new ADX COM Add-in project.

Creating a new COM Add-in project

Select your programming language of choice (VB.NET, C# or C++.NET), as well as the minimum version of MS Office that your add-in should be able to support. You’ll notice that Microsoft Office 2016 is already supported by Add-in Express.

Select your programming language and the minimum Office version that your add-in should be able to support.

On the next page of the wizard, select the supported MS Office application. Add-in Express supports multiple Office applications with one codebase. For this example, we’ll only need to support Microsoft Outlook.

Select Outlook as the only supported application.

When the New Microsoft Office COM Add-in wizard finishes, open the AddinModule designer surface by double-clicking on the AddinModule.cs file in the Solution Explorer.

Designing the user interface

We’ll need to create a UI for our Outlook add-in that will allow the user to log into her OneDrive account and see a list of her OneDrive files and folders. To do this, first add a new ADX Outlook Form to your add-in project.

Add a new ADX Outlook Form to the add-in project.

We’ll stick to a relatively simple design for the form. It will have a button to log into OneDrive, and tree view to display the OneDrive files and folders and another button to add the selected file to the current email as an attachment. My design for the form looks like the following image:

The design of the newly created Outlook form

Switch back to the AddinModule designer and add a new ADXOlFormsManager component to the designer surface.

Add a new ADXOlFormsManager component to the designer surface.

Add a new item to the ADXOlFormsManager’s Items collection and set the following properties:

  • AlwaysShowHeader : True
  • FormClassName : OnedriveOutlook.frmOneDrive
  • InspectorItemTypes : Mail
  • InspectorLayout : RightSubpane
  • InspectorMode : Compose

Adding required NuGet packages

Next, we need to add the required libraries to our project in order to authenticate with Office 365 and interact with the Office 365 Files API. To do this, open the Package Manager Console, by selecting it from the TOOLS > NuGet Package Manager Visual Studio menu.

Enter the following command to install the Active Directory Authentication Library:

Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

After the above mentioned library has been added, enter the following command in the Package Manager Console to add the Microsoft Office 365 My Files Library to your project:

Install-Package Microsoft.Office365.SharePoint

Adding the OnSendMessage event

Now that we have all the required libraries in our project, open the AddinModule.cs class in code view and add the following local variables to the top of the class file:

public IPagedCollection<IItem> Files = null;
 public Stream FileStream = null;
 public string AttachmentName = string.Empty;
 
 public int MESSAGE_FILES = 0x0400 + 903;
 public int MESSAGE_FILEDOWNLOAD = 0x0400 + 904;

Because we’ll be using async methods in our project, we’ll need to use the OnSendMessage event Add-in Express provides in order to make our add-in thread safe. Generate an event handler for the OnSendMessage event by switching to the designer view of the AddinModule class and double-clicking next to the event name in the event list:

Generating an event handler for the OnSendMessage event

Add the following code to the OnSendMessage event handler:

private void AddinModule_OnSendMessage(object sender, ADXSendMessageEventArgs e)
{
    if (e.Message == MESSAGE_FILES)
        ShowFiles();
 
    if (e.Message == MESSAGE_FILEDOWNLOAD)
        SaveAndAttachFile();
}

You’ll notice we called two methods depending on the message that was received. The code for the ShowFiles method follows below:

private void ShowFiles()
{
    var form = adxOlFormsCollectionItem1.GetCurrentForm() as frmOneDrive;
    form.ListFiles(Files.CurrentPage);
    form.picLoader.Visible = false;
    form.btnListFiles.Enabled = true;
}

The ShowFiles method gets a reference to the current instance of the frmOneDrive form and calls a method called ListFiles. This method is declared on the frmOneDrive form and we’ll take a closer look at this method a bit later.

The other method is called SaveAndAttachFile and its code is listed below:

private void SaveAndAttachFile()
{
    Outlook.Inspector currInspector = null;
    Outlook.MailItem currMail = null;
    Outlook.Attachments attachments = null;
 
    try
    {
        var fullFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), AttachmentName);
        var fs = File.Create(fullFilePath, (int)FileStream.Length);
        byte[] bytesInStream = new byte[this.FileStream.Length];
        this.FileStream.Read(bytesInStream, 0, bytesInStream.Length);
        fs.Write(bytesInStream, 0, bytesInStream.Length);
        fs.Close();
 
        currInspector = OutlookApp.ActiveInspector();
        currMail = currInspector.CurrentItem as Outlook.MailItem;
        attachments = currMail.Attachments;
        attachments.Add(fullFilePath, Outlook.OlAttachmentType.olByValue);
 
        var form = adxOlFormsCollectionItem1.GetCurrentForm() as frmOneDrive;
        form.btnAddAttachment.Enabled = true;
        form.panelStatus.Visible = false;
 
    }
    finally
    {
        if (attachments != null) Marshal.ReleaseComObject(attachments);
        if (currMail != null) Marshal.ReleaseComObject(currMail);
        if (currInspector != null) Marshal.ReleaseComObject(currInspector);
    }
}

The SaveAndAttachFile method, saves the FileStream object to disk and then attaches the file to the currently opened Mail item in Outlook. The FileStream object is set in the frmOneDrive form and we’ll take a look at how we accomplish this next.

Retrieving files from OneDrive for Business

Now we need to open the code-behind for the frmOneDrive form and add the following local variables to it:

private string clientId = "67fba0d2-8391-4ac3-af49-9dea87f4b400";
private string authority = "https://login.microsoftonline.com/common";
private string redirectUri = "http://localhost/0d303d2e84650b3efabfe6c4bda36cf8";
private string resourceId = "https://{yourtenantid}-my.sharepoint.com/";
private string serviceRoot = "https:// {yourtenantid}-my.sharepoint.com/_api/v1.0/me";
private string accessToken = string.Empty;
private SharePointClient client = null;

I’ve also created a local property called CurrentInstance that makes it a little easier to work with the current instance of the AddinModule:

public AddinModule CurrentInstance
{
    get
    {
        return this.AddinModule as AddinModule;
    }
}

Next, add the Authenticate method. This method is the same method we’ve used in previous articles to authenticate with Office 365:

public void Authenticate()
{
    var authContext = new AuthenticationContext(authority);
    var authResult = authContext.AcquireToken(resourceId, clientId,
        new Uri(redirectUri),PromptBehavior.Auto);
 
    accessToken = authResult.AccessToken;
}

Create a Click event handler for the “List Files” button and add the following code to it:

private async void btnListFiles_Click(object sender, EventArgs e)
{
    picLoader.Visible = true;
    btnListFiles.Enabled = false;
 
    CurrentInstance.Files = await GetFiles();
    CurrentInstance.SendMessage(CurrentInstance.MESSAGE_FILES);
}

Note that the Click event handler is declared with the async keyword. When the user clicks the button, it will fetch a list of files and folders from OneDrive and load it into the Files variable that is declared in the AddinModule class. Once the files are retrieved we call the SendMessage method of the AddinModule to notify it that the files has been retrieved.

The method that retrieves the files from OneDrive is called GetFiles and its code looks as follows:

private async Task<IPagedCollection<IItem>> GetFiles()
{
    if (string.IsNullOrEmpty(accessToken))
        Authenticate();
 
    if (!string.IsNullOrEmpty(accessToken))
    {
        client = new SharePointClient(new Uri(serviceRoot), async () => accessToken);
        var fileResult = await client.Files.ExecuteAsync();
        return fileResult;
    }
    return null;
}

As mentioned, after the files are fetched from OneDrive we call the SendMessage method, which in turn calls the ShowFiles method. This method then invoked the ListFiles method declared in the frmOneDrive class. The code for the ListFiles method follows below:

public void ListFiles(IReadOnlyList<IItem> currentPage)
{
    foreach (var item in currentPage)
    {
        var node = new TreeNode(item.Name);
        node.Tag = item.Id;
        node.ImageKey = item.Type;
        node.SelectedImageKey = item.Type;
        tvFiles.Nodes.Add(node);
    }
}

The code above loops through the file list returned from OneDrive and adds it to the tree view. You’ll notice that we used the Type property to determine whether it is a file or a folder.

Adding the OneDrive files as a mail attachment

The final step to complete our Outlook add-in is to add logic that will add the selected OneDrive file to the open mail item in Outlook. To accomplish this, we need to add the following code to the btnAddAttachment_Click event handler:

private async void btnAddAttachment_Click(object sender, EventArgs e)
{
    panelStatus.Visible = true;
    btnAddAttachment.Enabled = false;
    var fileId = tvFiles.SelectedNode.Tag.ToString();
    var fileFetcher = client.Files.GetById(fileId);
    var file = fileFetcher.ToFile();
    CurrentInstance.AttachmentName = tvFiles.SelectedNode.Text;
    CurrentInstance.FileStream = await file.DownloadAsync();
    CurrentInstance.SendMessage(CurrentInstance.MESSAGE_FILEDOWNLOAD);
}

A number of things happens in the code above. Firstly, we receive a reference to the OneDrive file by calling the GetById method, we then downloading the file to the FileStream object in the AddinModule class by invoking the DownloadAsync method.

Lastly, call the SendMessage method to in turn invoke the SaveAndAttachFile method declared in the AddinModule class.

Running the Outlook add-in

With all the code in place, we can build, register and run our Outlook add-in. If all goes according to plan, you should see the Advance form region on the right hand side of the Mail Inspector window in Outlook:

The Advance form region appears on the right hand side of the Mail Inspector window in Outlook.

Clicking on the List Files button, will prompt the user to log into Office 365. Once the user has entered their credentials, their OneDrive for Business files will be listed in the tree view. The user can then select a file and click the “Add Selected File as Attachment” button to automatically download and attach the OneDrive file as an attachment to the email.

The use can click the 'Add Selected File as Attachment' button to automatically download and attach the OneDrive file to the email.

Thank you for reading. Until next time, keep coding!

Available downloads:

This sample Outlook Add-in was developed using Add-in Express for Office and .net:

OneDrive Outlook sample

3 Comments

Post a comment

Have any questions? Ask us right now!