Common mail tasks using the Office 365 client library

Applies to: Exchange Online | Office 365

The Office 365 APIs .NET and JavaScript client libraries can make it easier interact with the REST APIs. They help manage authentication tokens, simplify the code needed to query and consume data, and perform discovery. You can get the libraries in the latest version of Office 365 API Tools for Visual Studio.

Alternatively, you can use the Mail REST APIs to interact with Office 365 mail data.

Use the client library with the Mail API

To access the Mail API by using the .NET or JavaScript client library, you need to acquire an access token and get the Outlook Services client. Then, you can send async queries to interact with mail data.

Acquire an access token | Get the Outlook Services client

Get messages | Send new messages | Reply to messages | Forward messages | Update messages | Delete messages | Move or copy messages | Get attachments

Get folders | Create folders | Update folders | Delete folders | Move or copy folders

Acquire an access token

Acquire the access token used for authentication. The client ID and authorization URI are assigned when you register your app with Microsoft Azure Active Directory.

Note In a Windows Store App, values for ClientID and AuthorizationUri are added to your project's App.xaml file when you register your application. AuthorizationUri is used as the host name for the CommonAuthority variable.

// Properties of the native client app.
public const string ClientID = "dc180c60-..."; 
public static Uri ReturnUri = new Uri("http://redirecturi");

// Properties used to communicate with a Windows Azure AD tenant.  
public const string CommonAuthority = "https://login.windows.net/Common"; 
public const string DiscoveryResourceId = "https://api.office.com/discovery/"; 

public static AuthenticationContext AuthenticationContext { get; set; } 
public static async Task<string> AcquireTokenAsync(AuthenticationContext context, string resourceId)
{
    string accessToken = null;
    try
    {
        // Try to get the AccessToken silently using the resourceId that was passed in
        // and the client ID of the application.
        accessToken = 
           (await context.AcquireTokenSilentAsync(resourceId, ClientID)).AccessToken;
    }
    catch (Exception)
    {
        // If unable to acquire the AccessToken silently, try again with full prompting. 
        accessToken = null;
    }
    if (accessToken == "" || accessToken == null)
    {
        AuthenticationResult result = 
            (await context.AcquireTokenAsync(resourceId, ClientID, ReturnUri));
        accessToken = result.AccessToken;
    }
    return accessToken;
}
var authContext;
var authToken; // for use with creating an outlookClient later.
authContext = new O365Auth.Context();
authContext.getIdToken("https://outlook.office365.com/")
   .then((function (token) {
       authToken = token;
       // The auth token also carries additional information. For example:    
       userName = token.givenName + " " + token.familyName;
   }).bind(this), function (reason) {
       console.log('Failed to login. Error = ' + reason.message);
   });

Get the Outlook Services client

Get the OutlookServicesClient object. You can call this code from other methods that use the Outlook Services client.

public static async Task<OutlookServicesClient> EnsureClientCreatedAsync()
{
    try
    {
        AuthenticationContext = new AuthenticationContext(CommonAuthority);
        if (AuthenticationContext.TokenCache.ReadItems().Count() > 0)
        {

            // Re-bind AuthenticationContext to the authority source of the cached token.
            // This is needed for the cache to work when asking for a token from that
            // authority.
            string cachedAuthority = 
                AuthenticationContext.TokenCache.ReadItems().First().Authority;
            AuthenticationContext = new AuthenticationContext(cachedAuthority);
        }
        DiscoveryClient discoveryClient = new DiscoveryClient(
            async () => await AcquireTokenAsync(AuthenticationContext, DiscoveryResourceId));

        // Get the "Mail" capability.
        CapabilityDiscoveryResult result = 
            await discoveryClient.DiscoverCapabilityAsync("Mail");
        var outlookClient = new OutlookServicesClient(
            result.ServiceEndpointUri,
            async () => 
                await AcquireTokenAsync(AuthenticationContext, result.ServiceResourceId));
        return outlookClient;
    }
    catch (Exception)
    {
        if (AuthenticationContext != null && AuthenticationContext.TokenCache != null)
        AuthenticationContext.TokenCache.Clear();
        return null;
    }
}
// Once the authToken has been acquired, create an outlookClient. One place to do this is inside of the
//    ".then" function callback of authContext.getIdToken(...) above.
var outlookClient = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0', authToken.getAccessTokenFn('https://outlook.office365.com'));

Get messages

Get the messages in the Inbox by using the Me.Messages shortcut property. To get the messages from a different folder, use the folder's Messages property. You can use the following well-known folder names instead of the ID for the corresponding folder: Inbox, SentItems, Drafts, DeletedItems.

Example: outlookClient.Me.Folders["SentItems"].Messages.ExecuteAsync()

To get a particular message, specify the message ID as the index of the Messages collection or use the GetById method.

Note Message collections support query expressions such as Select, OrderBy, and Take.

This example assumes you already got the Outlook Services client.

IPagedCollection<IMessage> messagesResults = await outlookClient.Me.Messages.ExecuteAsync();

// Get the ID of the first message.
string messageId = messagesResults.CurrentPage[0].Id;
outlookClient.me.folders.getFolder('Inbox').messages.getMessages().orderBy('DateTimeReceived desc').fetchAll(10).then(function (result) {
    result.forEach(function (message) {
        console.log('Message "' + message.subject + '" received at "' + message.dateTimeReceived.toString() + '"');
    });
}, function(error) {
    console.log(error);
});

Send new messages

You can send a new message on the fly with a supplied message or create draft message and then send it.

Send a new message on the fly

Create a message and pass it to the SendMailAsync method.

This example assumes you already got the Outlook Services client.

ItemBody body = new ItemBody
{
    Content = "It was <b>awesome</b>!",
    ContentType = BodyType.HTML
};
List<Recipient> toRecipients = new List<Recipient>();
toRecipients.Add(new Recipient
{
    EmailAddress = new EmailAddress
    {
        Address = "katiej@a830edad9050849NDA1.onmicrosoft.com"
    }
});
toRecipients.Add(new Recipient
{
    EmailAddress = new EmailAddress
    {
        Address = "pavelb@a830edad9050849NDA1.onmicrosoft.com"
    }
});
Message newMessage = new Message
{
    Subject = "Did you see last night's game?",
    Body = body,
    ToRecipients = toRecipients
};

// To send a message without saving to Sent Items, specify false for  
// the SavetoSentItems parameter. 
await outlookClient.Me.SendMailAsync(newMessage, true);

Create a draft message

Create a draft message and pass it to the AddMessageAsync method. Then you can update the draft and send it.

This example assumes you already got the Outlook Services client.

ItemBody body = new ItemBody
{
    Content = "I'm coming out a week later.",
    ContentType = BodyType.HTML
};
List<Recipient> toRecipients = new List<Recipient>();
toRecipients.Add(new Recipient
{
    EmailAddress = new EmailAddress
    {
        Address = "katiej@a830edad9050849NDA1.onmicrosoft.com"
    }
});
Message draftMessage = new Message
{
    Subject = "Changed my travel plans",
    Body = body,
    ToRecipients = toRecipients,
    Importance = Importance.High
};

// Save the draft message. Saving to Me.Messages saves the message in the Drafts folder.
await outlookClient.Me.Messages.AddMessageAsync(draftMessage);

// Get the ID of the message.
string messageId = draftMessage.Id;

Adding a message to the Me.Messages collection saves the draft in the Drafts folder, but you can save a draft in the Messages collection of any folder.

Example: outlookClient.Me.Folders["AAMkADE3N..."].Messages.AddMessageAsync(newMessage)

Send a draft message

Send a draft message by calling SendAsync. You can send a draft of a new, reply, reply-all, or forward message.

This example assumes you already got the Outlook Services client and got the message ID.

await outlookClient.Me.Messages[messageId].SendAsync();

Reply to messages

You can reply to a message directly or create a draft reply message and then send it.

Reply to a message directly

Reply directly to the sender of the message or to all recipients by calling ReplyAsync or ReplyAllAsync and passing in a comment.

This example assumes you already got the Outlook Services client and got the message ID.

await outlookClient.Me.Messages[messageId].ReplyAsync("Count me in.");
await outlookClient.Me.Messages[messageId].ReplyAllAsync("Count me in.");

Create a draft Reply or ReplyAll message

Create a draft Reply or ReplyAll message by calling CreateReplyAsync or CreateReplyAllAsync. Then you can update the draft and send it.

This example assumes you already got the Outlook Services client and got the message ID.

IMessage replyDraft = await outlookClient.Me.Messages[messageId].CreateReplyAsync();

// Get the ID of the draft Reply message.
string replyMessageId = replyDraft.Id;
IMessage replyAllDraft = await outlookClient.Me.Messages[messageId].CreateReplyAllAsync();

// Get the ID of the draft Reply All message.
string replyAllMessageId = replyAllDraft.Id;

CreateReplyAsync and CreateReplyAllAsync create a draft message with the ToRecipients, IsDraft, and other appropriate properties prepopulated.

Forward messages

You can forward a message directly or create a draft forward message and then send it.

Forward a message directly

Forward a message directly by calling ForwardAsync and passing in a comment and the recipients.

This example assumes you already got the Outlook Services client and got the message ID.

List<Recipient> recipients = new List<Recipient>();
recipients.Add(new Recipient
{
    EmailAddress = new EmailAddress
    {
        Address = "garthf@a830edad9050849NDA1.onmicrosoft.com"
    }
});
await outlookClient.Me.Messages[messageId].ForwardAsync("Interested?", recipients);

Create a draft Forward message

Create a draft Forward message by calling CreateForwardAsync. Then you can update the draft and send it.

This example assumes you already got the Outlook Services client and got the message ID.

IMessage forwardDraft = await outlookClient.Me.Messages[messageId].CreateForwardAsync();

// Get the ID of the draft Forward message.
string forwardMessageId = forwardDraft.Id;

CreateForward creates a draft message with the IsDraft and other appropriate properties prepopulated.

Update messages

Change writable properties on a message, and call UpdateAsync to save the changes.

This example assumes you already got the Outlook Services client and got the message ID.

IMessage message = await outlookClient.Me.Messages[messageId].ExecuteAsync();
message.Body = new ItemBody
{
        Content = "I'm coming out a week earlier."
};
message.ToRecipients.Add(new Recipient
{
    EmailAddress = new EmailAddress
    {
        Address = "garthf@a830edad9050849NDA1.onmicrosoft.com"
    }
});
await message.UpdateAsync();

You can define multiple updates client-side and send the requests all at once (batch them) by using the following pattern:

  1. Call UpdateAsync(true) for each entity you want to update. Specifying true registers the updates locally on the client but doesn't post them to the server.
  2. Call outlookClient.Context.SaveChangesAsync() to post all updates that are registered locally.

Delete messages

Delete a message by calling DeleteAsync.

This example assumes you already got the Outlook Services client and got the message ID.

IMessage message = await outlookClient.Me.Messages[messageId].ExecuteAsync();
await message.DeleteAsync();

Move or copy messages

Move a or copy a message by passing the ID of the destination folder to the MoveAsync or CopyAsync method.

This example assumes you already got the Outlook Services client, got the message ID, and got the desination folder ID.

IMessage messageToMove = await outlookClient.Me.Messages[messageId].ExecuteAsync();
await messageToMove.MoveAsync("AAMkADE3N...");
IMessage messageToCopy = await outlookClient.Me.Messages[messageId].ExecuteAsync();
await messageToCopy.CopyAsync("Inbox");

Get attachments

Get attachments on message by calling the Attachments property. To get a particular attachment, specify the attachment ID as the index of the Attachments collection or use the GetById method.

Note Attachment collections support query expressions such as Select, OrderBy, and Take.

This example assumes you already got the Outlook Services client. The .NET code assumes you already got the message ID.

IPagedCollection<IAttachment> attachmentResults = await outlookClient.Me.Messages[messageId].Attachments.ExecuteAsync();

// Get the number of attachments and the name of the first attachment.
int attachmentCount = attachmentResults.CurrentPage.Count; 
string attachmentName = attachmentResults.CurrentPage[0].Name;
outlookClient.me.folders.getFolder('Inbox').messages.getMessages().filter('HasAttachments eq true').fetchAll(10).then(function (result) {
    result.forEach(function (message) {
        message.attachments.getAttachments().fetchAll(100).then(function (attachmentResult) {
            console.log('Message "' + message.subject + '" contains ' + attachmentResult.length + ' attachment(s)');
            attachmentResult.forEach(function (attachment) {
                console.log('*    "' + attachment.name + '" (' + attachment.size + ' KB)');
            });
        });
    }, function (error) {
        console.log(error);
    });
}, function (error) {
    console.log(error);
});

Get folders

Get the top-level folders in the mailbox by using the Me.Folders shortcut property. To get the folders from a specific folder, use its ChildFolders property. You can use the following well-known folder names instead of the ID for the corresponding folder: Inbox, SentItems, Drafts, DeletedItems.

Example: outlookClient.Me.Folders["Drafts"].ChildFolders.ExecuteAsync()

To get a particular folder, specify the folder ID as the index of the Folders collection or use the GetById method.

Note Folder collections support query expressions such as Select, OrderBy, and Take.

This example assumes you already got the Outlook Services client.

IPagedCollection<IFolder> foldersResults = await outlookClient.Me.Folders.ExecuteAsync();

// Get the ID of the first folder.
string folderId = foldersResults.CurrentPage[0].Id;
outlookClient.me.folders.getFolders().fetchAll(100).then(function (result) {
    result.forEach(function (folder) {
        console.log('Folder "' + folder.displayName + '"');
    });
}, function (error) {
    console.log(error);
});

Create folders

Create a Folder object and pass it to the AddFolderAsync method on the destination folder's ChildFolders collection.

This example assumes you already got the Outlook Services client and got the folder ID of the parent folder.

Folder newFolder = new Folder
{
    DisplayName = "Private"
};
await outlookClient.Me.Folders["Inbox"].ChildFolders.AddFolderAsync(newFolder);

// Get the ID of the new folder.
string folderId = newFolder.Id;

Update folders

Change a folder name. DisplayName is the only writeable property for a folder.

This example assumes you already got the Outlook Services client and got the folder ID.

IFolder folder = await outlookClient.Me.Folders[folderId].ExecuteAsync();
folder.DisplayName = "Personal";
await folder.UpdateAsync();

// Get the updated property.
string updatedName = folder.DisplayName;

You can define multiple updates client-side and send the requests all at once (batch them) by using the following pattern:

  1. Call UpdateAsync(true) for each entity you want to update. Specifying true registers the updates locally on the client but doesn't post them to the server.
  2. Call outlookClient.Context.SaveChangesAsync() to post all updates that are registered locally.

Delete folders

Delete a folder by calling DeleteAsync.

This example assumes you already got the Outlook Services client and got the folder ID.

IFolder folder = await outlookClient.Me.Folders[folderId].ExecuteAsync();
await folder.DeleteAsync();

Move or copy folders

Move or copy a folder by passing the ID of the destination folder to the MoveAsync or CopyAsync method.

This example assumes you already got the Outlook Services client and got the folder ID of the folder to move and the destination folder.

IFolder folder = await outlookClient.Me.Folders[folderId].ExecuteAsync();
await folder.MoveAsync("AAMkADE3N...");
IFolder folder = await outlookClient.Me.Folders[folderId].ExecuteAsync();
await folder.CopyAsync("Inbox");

Additional resources