Adicionar capacidades de e-mail a aplicações .NET com o Microsoft Graph

Neste artigo, vai expandir a aplicação que criou na compilação de aplicações .NET com o Microsoft Graph com as APIs de correio do Microsoft Graph. Utilize o Microsoft Graph para listar a caixa de entrada do utilizador e enviar um e-mail.

Listar a caixa de entrada do utilizador

Comece por listar mensagens na caixa de entrada do e-mail do utilizador.

  1. Abra ./GraphHelper.cs e adicione a seguinte função à classe GraphHelper .

    public static Task<MessageCollectionResponse?> GetInboxAsync()
    {
        // Ensure client isn't null
        _ = userClient ??
            throw new NullReferenceException("Graph has not been initialized for user auth");
    
        return userClient.Me
            .MailFolders["Inbox"] // Only messages from Inbox folder
            .Messages
            .GetAsync((config) =>
            {
                /* Only request specific properties */
                config.QueryParameters.Select = ["from", "isRead", "receivedDateTime", "subject"];
                /* Get at most 25 results */
                config.QueryParameters.Top = 25;
                /* Sort by received time, newest first */
                config.QueryParameters.Orderby = ["receivedDateTime DESC"];
            });
    }
    
  2. Substitua a função empty ListInboxAsync no Program.cs pelo seguinte.

    async Task ListInboxAsync()
    {
        try
        {
            var messagePage = await GraphHelper.GetInboxAsync();
    
            if (messagePage?.Value == null)
            {
                Console.WriteLine("No results returned.");
                return;
            }
    
            // Output each message's details
            foreach (var message in messagePage.Value)
            {
                Console.WriteLine($"Message: {message.Subject ?? "NO SUBJECT"}");
                Console.WriteLine($"  From: {message.From?.EmailAddress?.Name}");
                Console.WriteLine($"  Status: {(message.IsRead!.Value ? "Read" : "Unread")}");
                Console.WriteLine($"  Received: {message.ReceivedDateTime?.ToLocalTime().ToString()}");
            }
    
            // If NextPageRequest is not null, there are more messages
            // available on the server
            // Access the next page like:
            // var nextPageRequest = new MessagesRequestBuilder(messagePage.OdataNextLink, _userClient.RequestAdapter);
            // var nextPage = await nextPageRequest.GetAsync();
            var moreAvailable = !string.IsNullOrEmpty(messagePage.OdataNextLink);
    
            Console.WriteLine($"\nMore messages available? {moreAvailable}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error getting user's inbox: {ex.Message}");
        }
    }
    
  3. Execute a aplicação, inicie sessão e selecione a opção 2 para listar a sua caixa de entrada.

    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    2
    Message: Updates from Ask HR and other communities
      From: Contoso Demo on Yammer
      Status: Read
      Received: 12/30/2021 4:54:54 AM -05:00
    Message: Employee Initiative Thoughts
      From: Patti Fernandez
      Status: Read
      Received: 12/28/2021 5:01:10 PM -05:00
    Message: Voice Mail (11 seconds)
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 5:00:46 PM -05:00
    Message: Our Spring Blog Update
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:49:46 PM -05:00
    Message: Atlanta Flight Reservation
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:35:42 PM -05:00
    Message: Atlanta Trip Itinerary - down time
      From: Alex Wilber
      Status: Unread
      Received: 12/28/2021 4:22:04 PM -05:00
    
    ...
    
    More messages available? True
    

GetInboxAsync explicado

Considere o código na GetInboxAsync função .

Aceder a pastas de correio conhecidas

A função utiliza o _userClient.Me.MailFolders["Inbox"].Messages construtor de pedidos, que cria um pedido para a API Listar mensagens . Uma vez que inclui o MailFolders["Inbox"] construtor de pedidos, a API só devolve mensagens na pasta de correio pedida. Neste caso, uma vez que a caixa de entrada é uma pasta predefinida e conhecida dentro da caixa de correio de um utilizador, é acessível através do nome conhecido. As pastas não predefinidas são acedidas da mesma forma ao substituir o nome conhecido pela propriedade ID da pasta de correio. Para obter detalhes sobre os nomes de pastas conhecidos disponíveis, consulte mailFolder resource type (Tipo de recurso mailFolder).

Aceder a uma coleção

Ao contrário da GetUserAsync função da secção anterior, que devolve um único objeto, este método devolve uma coleção de mensagens. A maioria das APIs no Microsoft Graph que devolvem uma coleção não devolve todos os resultados disponíveis numa única resposta. Em vez disso, utilizam a paginação para devolver uma parte dos resultados ao fornecer um método para os clientes solicitarem a página seguinte.

Tamanhos de página predefinidos

As APIs que utilizam a paginação implementam um tamanho de página predefinido. Para mensagens, o valor predefinido é 10. Os clientes podem pedir mais (ou menos) através do parâmetro de consulta $top . No GetInboxAsync, a adição $top é efetuada com o .Top(25) método .

Observação

O valor transmitido a .Top() é um limite superior e não um número explícito. A API devolve um número de mensagens até ao valor especificado.

Obter páginas subsequentes

Se existirem mais resultados disponíveis no servidor, as respostas da coleção incluem uma @odata.nextLink propriedade com um URL de API para aceder à página seguinte. A biblioteca de cliente .NET fornece a NextPageRequest propriedade em objetos de página de coleção. Se esta propriedade não for nula, existem mais resultados disponíveis.

A NextPageRequest propriedade expõe um GetAsync método que devolve a página seguinte.

Classificando coleções

A função utiliza o OrderBy método no pedido para pedir resultados ordenados quando a mensagem é recebida (ReceivedDateTime propriedade). Inclui o DESC palavra-chave para que as mensagens recebidas mais recentemente sejam listadas em primeiro lugar. Este método adiciona o parâmetro de consulta $orderby à chamada à API.

Enviar email

Agora, adicione a capacidade de enviar uma mensagem de e-mail como o utilizador autenticado.

  1. Abra ./GraphHelper.cs e adicione a seguinte função à classe GraphHelper .

    public static async Task SendMailAsync(string subject, string body, string recipient)
    {
        // Ensure client isn't null
        _ = userClient ??
            throw new NullReferenceException("Graph has not been initialized for user auth");
    
        // Create a new message
        var message = new Message
        {
            Subject = subject,
            Body = new ItemBody
            {
                Content = body,
                ContentType = BodyType.Text,
            },
            ToRecipients =
            [
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = recipient,
                    },
                },
            ],
        };
    
        // Send the message
        await userClient.Me
            .SendMail
            .PostAsync(new SendMailPostRequestBody
            {
                Message = message,
            });
    }
    
  2. Substitua a função empty SendMailAsync no Program.cs pelo seguinte.

    async Task SendMailAsync()
    {
        try
        {
            // Send mail to the signed-in user
            // Get the user for their email address
            var user = await GraphHelper.GetUserAsync();
    
            var userEmail = user?.Mail ?? user?.UserPrincipalName;
    
            if (string.IsNullOrEmpty(userEmail))
            {
                Console.WriteLine("Couldn't get your email address, canceling...");
                return;
            }
    
            await GraphHelper.SendMailAsync(
                "Testing Microsoft Graph",
                "Hello world!",
                userEmail);
    
            Console.WriteLine("Mail sent.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error sending mail: {ex.Message}");
        }
    }
    
  3. Execute a aplicação, inicie sessão e selecione a opção 3 para enviar um e-mail para si próprio.

    Please choose one of the following options:
    0. Exit
    1. Display access token
    2. List my inbox
    3. Send mail
    4. Make a Graph call
    3
    Mail sent.
    

    Observação

    Se estiver a testar com um inquilino de programador do Programa para Programadores do Microsoft 365, o e-mail que enviar poderá não ser entregue e poderá receber um relatório não dinâmico. Se quiser desbloquear o envio de correio do seu inquilino, contacte o suporte através do Centro de administração do Microsoft 365.

  4. Para verificar se a mensagem foi recebida, selecione a opção 2 para listar a sua caixa de entrada.

SendMailAsync explicado

Considere o código na SendMailAsync função .

Enviar correio

A função utiliza o _userClient.Me.SendMail construtor de pedidos, que cria um pedido para a API enviar correio . O construtor de pedidos utiliza um Message objeto que representa a mensagem a enviar.

Criar objetos

Ao contrário das chamadas anteriores para o Microsoft Graph que só leem dados, esta chamada cria dados. Para criar itens com a biblioteca de cliente, crie uma instância da classe que representa os dados (neste caso, Microsoft.Graph.Message) com o new palavra-chave, defina as propriedades pretendidas e, em seguida, envie-as na chamada à API. Uma vez que a chamada está a enviar dados, o PostAsync método é utilizado em vez de GetAsync.

Próxima etapa