Microsoft Graph を使用して .NET アプリに電子メール機能を追加する

この記事では、「Microsoft Graph メール API を使用して Microsoft Graph を使用して .NET アプリをビルド する」で作成したアプリケーションを拡張します。 Microsoft Graph を使用して、ユーザーの受信トレイを一覧表示し、メールを送信します。

ユーザーの受信トレイを一覧表示する

まず、ユーザーのメール 受信トレイにメッセージを一覧表示します。

  1. ./GraphHelper.cs を開き、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. Program.csの空の ListInboxAsync 関数 次のように置き換えます。

    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. アプリを実行し、サインインし、オプション 2 を選択して受信トレイを一覧表示します。

    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 の説明

GetInboxAsync関数のコードについて考えてみましょう。

既知のメール フォルダーへのアクセス

関数は、list messages API への要求をビルドする_userClient.Me.MailFolders["Inbox"].Messages要求ビルダーを使用します。 MailFolders["Inbox"]要求ビルダーが含まれているため、API は要求されたメール フォルダー内のメッセージのみを返します。 この場合、受信トレイはユーザーのメールボックス内の既定の既知のフォルダーであるため、既知の名前を使用してアクセスできます。 既定以外のフォルダーには、既知の名前をメール フォルダーの ID プロパティに置き換えることで、同じ方法でアクセスされます。 使用可能な既知のフォルダー名の詳細については、「 mailFolder リソースの種類」を参照してください。

コレクションへのアクセス

1 つのオブジェクトを返す前のセクションの GetUserAsync 関数とは異なり、このメソッドはメッセージのコレクションを返します。 コレクションを返す Microsoft Graph のほとんどの API では、使用可能なすべての結果が 1 つの応答で返されるわけではありません。 代わりに、 ページングを 使用して結果の一部を返しながら、クライアントが次のページを要求するメソッドを提供します。

既定のページ サイズ

ページングを使用する API では、既定のページ サイズが実装されます。 メッセージの場合、既定値は 10 です。 クライアントは、 $top クエリ パラメーターを使用して、より多く (またはそれ以下) を要求できます。 GetInboxAsyncでは、.Top(25) メソッドを使用して$topを追加します。

注:

.Top()に渡される値は、明示的な数値ではなく、上限です。 API は、指定した値までのメッセージ数 返します。

後続のページを取得する

サーバーで使用可能な結果が増える場合、コレクション応答には、次のページにアクセスするための API URL を含む @odata.nextLink プロパティが含まれます。 .NET クライアント ライブラリは、コレクション ページ オブジェクトに NextPageRequest プロパティを提供します。 このプロパティが null 以外の場合は、使用可能な結果が増えます。

NextPageRequest プロパティは、次のページを返すGetAsync メソッドを公開します。

コレクションを並べ替える

関数は、要求に対して OrderBy メソッドを使用して、メッセージの受信時刻 (ReceivedDateTime プロパティ) で並べ替えられた結果を要求します。 最近受信したメッセージが最初に一覧表示されるように、DESC キーワード (keyword)が含まれます。 このメソッドは、 $orderby クエリ パラメーター を API 呼び出しに追加します。

メールを送信する

次に、認証されたユーザーとして電子メール メッセージを送信する機能を追加します。

  1. ./GraphHelper.cs を開き、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. Program.csの空の SendMailAsync 関数 次のように置き換えます。

    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. アプリを実行し、サインインし、オプション 3 を選択して自分にメールを送信します。

    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.
    

    注:

    Microsoft 365 開発者プログラムの開発者テナントでテストしている場合は、送信したメールが配信されず、配信不能レポートが届く場合があります。 テナントからのメール送信のブロックを解除する場合は、Microsoft 365 管理センターからサポートにお問い合わせください。

  4. メッセージが受信されたことを確認するには、オプション 2 を選択して受信トレイを一覧表示します。

SendMailAsync の説明

SendMailAsync関数のコードについて考えてみましょう。

メールの送信

関数は、メール送信 API への要求をビルドする_userClient.Me.SendMail要求ビルダーを使用します。 要求ビルダーは、送信するメッセージを表す Message オブジェクトを受け取ります。

オブジェクトの作成

データのみを読み取る Microsoft Graph の以前の呼び出しとは異なり、この呼び出しではデータが作成されます。 クライアント ライブラリを使用して項目を作成するには、new キーワード (keyword)を使用してデータ (この場合はMicrosoft.Graph.Message) を表す クラスのインスタンスを作成し、目的のプロパティを設定してから、API 呼び出しで送信します。 呼び出しはデータを送信しているため、GetAsyncの代わりに PostAsync メソッドが使用されます。

次の手順