Доступ к данным Microsoft 365 и управление с помощью Microsoft Graph

Contents
[ ]

Оптимизировать доступ и управление данными Microsoft 365 с помощью Aspose.Email Graph Client

Microsoft Graph Это REST API для доступа к данным Microsoft 365. Реализация Graph Client в Aspose.Email for .NET позволяет получать доступ к Microsoft Graph через наш API. В приведенных ниже примерах мы создадим экземпляр MS Graph Client, предоставив токен. Затем мы рассмотрим основные методы управления папками, их обновления, копирования и удаления. Сообщения, их содержимое и вложения также могут быть получены или изменены с нашим MS Graph Client. Управление категориями, правилами, блокнотами и переопределениями является расширенной функцией Microsoft Graph Client от Aspose.Email.

Аутентификация и запросы с IGraphClient с использованием MSAL в .NET

Чтобы взаимодействовать с сервисами Microsoft Graph, вам потребуется создать IGraphClient объект. После аутентификации этот клиент позволяет выполнять различные запросы к сервису. GetClient метод, который создает IGraphClient, требует ITokenProvider реализацию в качестве первого параметра. Эта ITokenProvider отвечает за предоставление необходимого токена аутентификации. Чтобы получить токен, мы используем Библиотека Microsoft Authentication Library (MSAL) для .NET.

Вот как настроить процесс аутентификации:

Шаг 1: Настройка аутентификации

Следующие шаги помогут вам получить токен авторизации:

  1. Создать класс AccessParameters.

    Определите класс AccessParameters для хранения ваших учетных данных.

public class AccessParameters
{
    public string TenantId { get; init; }
    public string ClientId { get; init; }
    public string ClientSecret { get; init; }
    public string UserId { get; init; }
    public Uri Authority => new ($"https://login.microsoftonline.com/{TenantId}");
    public string ApiUrl => "https://graph.microsoft.com/.default";
}
  1. Добавить Пакет MSAL.NET.

    Установить Microsoft.Identity.Client Пакет NuGet, содержащий бинарные файлы MSAL.NET, необходимые для аутентификации.

  2. Реализовать интерфейс ITokenProvider.

    Создайте GraphTokenProvider класс, реализующий ITokenProvider интерфейс. Этот класс будет использовать библиотеку MSAL.NET для получения токена доступа.

using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using Aspose.Email.Clients;

public class GraphTokenProvider : ITokenProvider
{
    private readonly IConfidentialClientApplication _app;
    private readonly string[] _scopes;
    private string? _token;

    public GraphTokenProvider(AccessParameters accessParams)
    {
        _app = ConfidentialClientApplicationBuilder.Create(accessParams.ClientId)
            .WithClientSecret(accessParams.ClientSecret)
            .WithAuthority(accessParams.Authority)
            .Build();

        _app.AddInMemoryTokenCache();

        _scopes = new[] { accessParams.ApiUrl };
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public OAuthToken GetAccessToken()
    {
        return GetAccessToken(false);
    }

    public OAuthToken GetAccessToken(bool ignoreExistingToken)
    {
        if (!ignoreExistingToken && _token != null)
        {
            return new OAuthToken(_token);
        }

        _token = GetAccessTokenAsync().GetAwaiter().GetResult();
        return new OAuthToken(_token);
    }

    private async Task<string?> GetAccessTokenAsync()
    {
        AuthenticationResult? result;

        try
        {
            result = await _app.AcquireTokenForClient(_scopes)
                .ExecuteAsync();

            Console.WriteLine("Token acquired");
        }
        catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
        {
            Console.WriteLine("Scope provided is not supported");
            result = null;
        }

        if (result == null) return null;
        _token = result.AccessToken;
        return result.AccessToken;
    }

Шаг 2: Создание экземпляра ITokenProvider

После определения GraphTokenProvider класс, вы можете создать экземпляр AccessParameters и используйте его для создания экземпляра GraphTokenProvider.

var accessParams = new AccessParameters()
{
    TenantId = "Your Tenant ID",
    ClientId = "Your Client ID",
    ClientSecret = "Your Client Secret",
    UserId = "User's Object ID"
};

var tokenProvider = new GraphTokenProvider(accessParams);

Шаг 3: Выполнение запросов с IGraphClient

Наконец, используйте GraphTokenProvider для создания аутентифицированного IGraphClient и начните выполнять запросы к сервису.

using var client = GraphClient.GetClient(tokenProvider, accessParams.TenantId);

client.Resource = ResourceType.Users;
client.ResourceId = accessParams.UserId;

С завершением этих шагов ваш IGraphClient теперь готов взаимодействовать с сервисами Microsoft Graph, используя аутентифицированные запросы.

Подключение к конечным точкам GCC High

Этот GraphClient поддерживает подключение к конечным точкам GCC High с использованием EndPoint свойство. Следующий пример кода демонстрирует, как настроить GraphClient для подключения к конечной точке GCC High для перечисления папок и получения сообщений.

client.EndPoint = "https://graph.microsoft.us";

var folders = client.ListFolders();
string folderId = folders.Find(x => x.DisplayName == "Inbox").ItemId;
var msgs = client.ListMessages(folderId);

Управление папками с IGraphClient

Список папок

Вызвав ListFolders метод из MS Graph Client, с его помощью можно получить список папок. У каждой папки есть набор параметров, таких как DisplayName, которые можно прочитать в FolderInfo тип.

var folders = client.ListFolders();

foreach (var folder in folders)
{
    Console.WriteLine(folder.DisplayName);
}

Обновление папок

Чтобы создать папку с помощью MS Graph Client, используйте CreateFolder метод. Вы получите FolderInfo объект и возможность доступа к DisplayName, ItemId, HasSubFolders и другим свойствам.

var folderInfo = client.CreateFolder("FolderName");
folderInfo.DisplayName = "FolderAnotherName";
client.UpdateFolder(folderInfo);

Копирование папок

CopyFolder метод является ключевым для копирования объекта папки с помощью MS Graph.

var folderInfo1 = client.CreateFolder("Folder1");
var folderInfo2 = client.CreateFolder("Folder2");
    
// copy Folder2 to Folder1
client.CopyFolder(folderInfo1.ItemId, folderInfo2.ItemId);

Перемещение и удаление папок

Использовать MoveFolder метод используется для перемещения папки, он принимает newParentId и itemId. Удалить метод используется для удаления метода по идентификатору.

var folderInfo1 = client.CreateFolder("Folder1");
var folderInfo2 = client.CreateFolder("Folder2");
    
// move Folder2 to Folder1
client.MoveFolder(folderInfo1.ItemId, folderInfo2.ItemId);
    
// delete Folder1
client.Delete(folderInfo1.ItemId)

Управление сообщениями с IGraphClient

MS Graph Client, реализованный в Aspose.Email для .NET, предоставляет набор методов для управления сообщениями и вложениями:

Список сообщений

var folders = client.ListFolders();

foreach (var folder in folders)
{
    if (folder.DisplayName.Equals("Inbox"))
    {
        // list messages in inbox
        var inboxMessages = client.ListMessages(folder.ItemId);

        foreach (var messageInfo in inboxMessages)
        {
            Console.WriteLine(messageInfo.Subject);
        }
    }
}

Фильтрация сообщений по дате отправки

Этот OrderBy метод из коллекции библиотеки позволяет получать сообщения с различными сортировками (по возрастанию и убыванию) в зависимости от даты их отправки. Следующий пример кода показывает, как отсортировать сообщения по дате отправки:

IGraphClient client = GraphClient.GetClient(provider, TenantId);

var builder = new GraphQueryBuilder();

// create orderby messages query 'DESC'
builder.SentDate.OrderBy(false);
var messagePageInfo = client.ListMessages(KnownFolders.Inbox, new PageInfo(10), builder.GetQuery());
var messages = messagePageInfo.Items;

builder.Clear();

// create orderby messages query 'ASC'
builder.SentDate.OrderBy(true);
messagePageInfo = client.ListMessages(KnownFolders.Inbox, new PageInfo(10), builder.GetQuery());
messages = messagePageInfo.Items;

Перечисление сообщений с поддержкой постраничного вывода

API позволяет выполнять постраничный вывод и фильтрацию сообщений при их перечислении. Это особенно полезно для почтовых ящиков с большим объёмом сообщений, поскольку экономит время, получая только необходимую сводную информацию.

Пример кода и перечисленные ниже шаги демонстрируют, как получать сообщения из папки Inbox, используя возможности постраничного вывода и фильтрации.

  1. Сначала инициализируйте клиент.
  2. Затем задайте количество элементов для отображения на странице, например, 10.
  3. Создайте фильтр для получения только непрочитанных сообщений, используя GraphQueryBuilder класс. builder.IsRead.Equals(false) задаёт условие для фильтрации непрочитанных сообщений.
  4. Вызвать ListMessages метод вызывается у объекта клиента, указывая папку (Inbox) и количество элементов на страницу (PageInfo(itemsPerPage)) в качестве параметров. Также передаётся объект запроса для применения фильтра непрочитанных сообщений. Возвращаемый объект PageInfo (pageInfo) содержит полученные сообщения текущей страницы в свойстве Items.
  5. Создайте цикл, который продолжается до тех пор, пока не будет достигнута последняя страница (pageInfo.LastPage равно false). Полученные сообщения добавляются в существующий список сообщений с помощью messages.AddRange(pageInfo.Items).
//  reading unread messages with paging
using var client = GraphClient.GetClient(tokenProvider, config.Tenant);

// paging option
var itemsPerPage = 10;
// create unread messages filter
GraphQueryBuilder builder = new GraphQueryBuilder();
builder.IsRead.Equals(false);
var query = builder.GetQuery();

// list messages
var pageInfo = client.ListMessages(KnownFolders.Inbox, new PageInfo(itemsPerPage), query);
var  messages = pageInfo.Items;

while (!pageInfo.LastPage)
{
    pageInfo = client.ListMessages(KnownFolders.Inbox, pageInfo.NextPage, query);
    messages.AddRange(pageInfo.Items);
}

// set messages state as read
foreach (var message in messages)
{
    client.SetRead(message.ItemId);
}

Получение сообщений

var folders = client.ListFolders();

foreach (var folder in folders)
{
    if (folder.DisplayName.Equals("Inbox"))
    {
        // list messages in inbox
        var inboxMessages = client.ListMessages(folder.ItemId);

        if (inboxMessages.Count > 0)
        {
            // fetch the first message in inbox
            var msg = client.FetchMessage(inboxMessages[0].ItemId);
            
            Console.WriteLine(msg.BodyHtml);
        }
        
    }
}

Создание сообщений

var msg = new MapiMessage(OutlookMessageFormat.Unicode)
{
    Subject = "My message",
    Body = "Hi, it is my message"
};

msg.Recipients.Add("sam@to.com", "Sam", MapiRecipientType.MAPI_TO);

// create message in inbox
client.CreateMessage(KnownFolders.Inbox, msg);

Отправка сообщений

// prepare the message
var msg = new MapiMessage(OutlookMessageFormat.Unicode)
{
    Subject = "My message",
    Body = "Hi, it is my message"
};

msg.Recipients.Add("sam@to.com", "Sam", MapiRecipientType.MAPI_TO);
msg.SetProperty(KnownPropertyList.SenderName, "John");
msg.SetProperty(KnownPropertyList.SentRepresentingEmailAddress, "John@from.com");

// send message
client.Send(msg);

Отправка черновиков сообщений

// prepare the message
var msg = new MapiMessage(OutlookMessageFormat.Unicode)
{
    Subject = "My message",
    Body = "Hi, it is my message"
};

msg.Recipients.Add("sam@to.com", "Sam", MapiRecipientType.MAPI_TO);
msg.SetProperty(KnownPropertyList.SenderName, "John");
msg.SetProperty(KnownPropertyList.SentRepresentingEmailAddress, "John@from.com");

// add message to Draft folder
var draftMessage = client.CreateMessage(KnownFolders.Drafts, msg);

// send a draft message
client.Send(draftMessage.ItemId);

Отправка EML‑сообщений

Создание и отправка электронных писем проста с использованием объекта MailMessage. Следующий пример кода демонстрирует, как создать и отправить сообщение email с помощью Graph API:

// prepare the message
var eml = new MailMessage
{
    From = "from@domain.com",
    To = "to1@domain.com, to2@domain.com",
    Subject = "New message",
    HtmlBody = "<html><body>This is the HTML body</body></html>"
};

// send the message
graphClient.Send(eml);
graphClient.Create(KnownFolders.Inbox, eml);

Копирование сообщений


// copy message to Inbox folder
var copiedMsg = client.CopyMessage(KnownFolders.Inbox, msg.ItemId);

Перемещение сообщений

// move message to Inbox folder
var movedMsg = client.MoveMessage(KnownFolders.Inbox, msg.ItemId);

Управление вложениями


// create an attachment
var attachment = new MapiAttachment();
attachment.SetProperty(KnownPropertyList.DisplayName, "My Attachment");
attachment.SetProperty(KnownPropertyList.AttachDataBinary, new byte[1024]);

// add an attachment to message
var createdAttachment = client.CreateAttachment(messageInfo.ItemId, attachment);

// fetch a message attachment
var fetchedAttachment = client.FetchAttachment(createdAttachment.ItemId);

// delete a message attachment 
client.DeleteAttachment(createdAttachment.ItemId);

// list the message attachments
var attachments = client.ListAttachments(messageInfo.ItemId);   

Управление элементами Outlook с помощью Graph Client

Управление событиями календаря

Aspose.Email предоставляет API для доступа, управления и взаимодействия с событиями календаря. Для этих целей он предлагает следующие методы в IGraphClient интерфейс:

  • ListCalendars() — Возвращает коллекцию информации о календарях.
  • ListCalendarItems(string id) — Возвращает коллекцию элементов календаря, связанных с указанным ID календаря.
  • FetchCalendarItem(string id) — Получает конкретный элемент календаря по указанному ID.
  • CreateCalendarItem(string calId, MapiCalendar mapiCalendar) — Создает новый элемент календаря в указанном календаре.
  • UpdateCalendarItem(MapiCalendar mapiCalendar) — Обновляет существующий элемент календаря.
  • UpdateCalendarItem(MapiCalendar mapiCalendar, UpdateSettings updateSettings) — Обновляет существующий элемент календаря с указанными настройками обновления.

Следующий образец кода демонстрирует, как взаимодействовать с событиями календаря в клиенте Microsoft Graph API, используя методы, предоставленные Aspose.Email:


// List Calendars
CalendarInfoCollection calendars = graphClient.ListCalendars();

// List Calendar Items
MapiCalendarCollection calendarItems = graphClient.ListCalendarItems("calendarId");

// Fetch Calendar Item
MapiCalendar calendarItem = graphClient.FetchCalendarItem("calendarItemId");

// Create Calendar Item
MapiCalendar newCalendarItem = new MapiCalendar(
    location: "Conference Room",
    summary: "Team Meeting",
    description: "Discuss project status and updates.",
    startDate: startDate,
    endDate: endDate
);

MapiCalendar createdCalendarItem = graphClient.CreateCalendarItem("calendarId", newCalendarItem);

// Update Calendar Item
createdCalendarItem.Location = "Zoom Meeting";
MapiCalendar updatedCalendarItem = graphClient.UpdateCalendarItem(createdCalendarItem);

Управление категориями

Чтобы управлять категориями с помощью MS Graph от Aspose.Email для .NET, используйте следующие методы:

// create a custom category with Orange color
var category = client.CreateCategory("My custom category", CategoryPreset.Preset1);

// fetch a category
var fetchedCategory = client.FetchCategory(category.Id);

// update category (change color to brown)
fetchedCategory.Preset = CategoryPreset.Preset2;
var updatedCategory = client.UpdateCategory(fetchedCategory);

// list available categories
var categories = client.ListCategories();

foreach (var cat in categories)
{
    Console.WriteLine(cat.DisplayName);
}

// delete a category
client.Delete(fetchedCategory.Id);

Управление контактами

Aspose.Email предоставляет API для доступа, управления и взаимодействия с элементами контактов. Для этих целей он предлагает следующие методы в IGraphClient интерфейс:

  • ListContacts(string id) — Возвращает коллекцию MAPI‑контактов, связанных с указанным ID папки.
  • FetchContact(string id) — Получает конкретный контакт по указанному ID элемента.
  • CreateContact(string folderId, MapiContact contact) — Создает новый контакт в указанной папке.
  • UpdateContact(MapiContact contact) — Обновляет существующий контакт.

Следующий образец кода демонстрирует, как взаимодействовать с контактами в клиенте Microsoft Graph API, используя методы, предоставленные Aspose.Email:

// List Contacts
MapiContactCollection contacts = graphClient.ListContacts("contactFolderId");

// Fetch Contact
MapiContact contact = graphClient.FetchContact("contactId");

// Create Contact
MapiContact newContact = new MapiContact("Jane Smith", "jane.smith@example.com", "XYZ Corporation", "777-888-999");

MapiContact createdContact = graphClient.CreateContact("contactFolderId", newContact);

// Update Contact
createdContact.Telephones.PrimaryTelephoneNumber = "888-888-999";

MapiContact updatedContact = graphClient.UpdateContact(createdContact);

Управление переопределениями

Чтобы управлять переопределениями с помощью MS Graph от Aspose.Email для .NET, используйте следующие методы:

// Create an user's override
var userOverride = client.CreateOrUpdateOverride
    (new MailAddress("JohnBrown@someorg.com", "JohnBrown"), ClassificationType.Focused);

// list the overrides
var overrides = client.ListOverrides();

// update override
userOverride.Sender.DisplayName = "John Brown";
var updatedOverride = client.UpdateOverride(userOverride);

// delete override
client.Delete(updatedOverride.Id);

Управление правилами

Чтобы управлять правилами с помощью MS Graph от Aspose.Email для .NET, используйте следующие методы:

// Create a rule
var rule = PrepareRule("user@someorg.com", "User");
var createdRule = client.CreateRule(rule);

// List all rules defined for Inbox
var rules = client.ListRules();

// Fetch a rule
var fetchedRule = client.FetchRule(createdRule.RuleId);

// Update a rule
fetchedRule.DisplayName = "Renamed rule";
fetchedRule.IsEnabled = false;
var updatedRule = client.UpdateRule(createdRule);

// Delete a rule
client.Delete(updatedRule.RuleId);
InboxRule PrepareRule(string email, string displayName)
{
    var rule = new InboxRule()
    {
        DisplayName = "My rule",
        Priority = 1,
        IsEnabled = true,
        Conditions = new RulePredicates(),
        Actions = new RuleActions()
    };

    rule.Conditions.ContainsSenderStrings = new StringCollection { displayName };
    rule.Actions.ForwardToRecipients = new MailAddressCollection
        { new MailAddress(email, displayName, true) };
    rule.Actions.StopProcessingRules = true;

    return rule;
}

Управление блокнотами

Чтобы управлять блокнотами с помощью MS Graph от Aspose.Email для .NET, используйте следующие методы:

// create a OneNote notebook
var newNotebook = new Notebook()
{
    DisplayName = "My Notebook"
};
var createdNotebook = client.CreateNotebook(newNotebook);

// fetch a notebook
var fetchedNotebook = client.FetchNotebook(createdNotebook.Id);

// list the notebooks
var notebooks = client.ListNotebooks();

Управление задачами в Microsoft Graph

Aspose.Email предоставляет разработчикам API для доступа, управления и взаимодействия со задачами и списками задач пользователей, используя следующие методы IGraphClient интерфейс:

Следующий пример кода демонстрирует, как управлять списками задач:

// List Task Lists
var taskLists = graphClient.ListTaskLists();

foreach (var tList in taskLists)
{
    Console.WriteLine($"Task List: {tList.DisplayName}");
}

// Get Task List
var taskList = graphClient.GetTaskList("taskListId");

// Delete Task List
graphClient.DeleteTaskList("taskListId");

Следующий пример кода демонстрирует, как управлять задачами:

// List Tasks in a Task List
MapiTaskCollection tasks = graphClient.ListTasks("taskListId");

// Fetch Task
MapiTask task = graphClient.FetchTask("taskId");

// Create Task
var newTask = new MapiTask
{
    Subject = "New Task",
    DueDate = new DateTime(2023, 12, 31),
    Status = MapiTaskStatus.NotStarted
};

MapiTask createdTask = graphClient.CreateTask(newTask, "taskListUri");

// Update Task
createdTask.Subject = "Updated Task Subject";
MapiTask updatedTask = graphClient.UpdateTask(createdTask);

// Update Task with UpdateSettings
var updateSettings = new UpdateSettings { SkipAttachments  = true };
MapiTask updatedTaskWithSettings = graphClient.UpdateTask(createdTask, updateSettings);