如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

huangapple go评论57阅读模式
英文:

How to send email with AAD Graph API with personal outlook account

问题

我正在尝试创建一个控制台应用程序,将我的个人Outlook帐户设置为计划任务进行读取。我已经使用个人Outlook帐户设置了一个AAD帐户。

以下是我尝试的代码:

尝试
{
    // ...  // 你的代码部分

    var user = await graphServiceClient.Users[userId].GetAsync();

    Console.WriteLine(user.Id + ":" + user.DisplayName + " <" + user.Mail + ">" + user.MailboxSettings);

    await graphServiceClient.Users[userId]
        .SendMail
        .PostAsync(requestbody);

    //await graphServiceClient.Users[userId]
    //      .SendMail(message, false)
    //      .Request()
    //      .PostAsync();

}
catch (ODataError odataError)
{
    Console.WriteLine(odataError.Error.Code);
    Console.WriteLine(odataError.Error.Message);
}

调用API成功,因为我成功检索到了用户的Id(即我的用户对象ID)和我的用户名,但是邮件为空,错误消息为"未找到资源,无法发现资源"。

我进行了一些研究,似乎我需要在AAD中为这个Outlook帐户分配365办公套件的许可证,以使邮箱和发送邮件功能正常工作。但我对我在网上找到的信息有些不知所措,不确定哪种方法是正确的。

任何建议或指导将不胜感激。谢谢。

英文:

Im trying to have a console application that will read my personal outlook account set as scheduled task, I have setup an AAD account with personal outlook account.

Here is the code that I have tried.

try
        {

            string tenantId = &quot;xxxxxx&quot;;
            string clientId = &quot;xxxxxxxx&quot;;
            string clientSecret = &quot;xxxxxxxxx&quot;;
            string userId = &quot;xxxxxxxxx&quot;;
            //The following scope is required to acquire the token
            string[] scopes = new string[] { &quot;https://graph.microsoft.com/.default&quot; };

            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            var clientSecretCredential = new ClientSecretCredential(
            tenantId, clientId, clientSecret, options);

            GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);


            var message = new Message
            {
                Subject = &quot;Your subject here&quot;,
                Body = new ItemBody
                {
                    ContentType = BodyType.Html,
                    Content = &quot;Email Content&quot;
                },
                ToRecipients = new List&lt;Recipient&gt;()
            {
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = &quot;xxxx@gmail.com&quot;
                    }
                }
            },
                CcRecipients = new List&lt;Recipient&gt;()
            {
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = &quot;xxxxxx@email.com&quot;
                    }
                }
            }
            };

          
            Microsoft.Graph.Users.Item.SendMail
            .SendMailPostRequestBody requestbody = new()
            {
                Message = message,
                SaveToSentItems = false // or true, as you want
            };

            var user = await graphServiceClient.Users[userId].GetAsync();

                Console.WriteLine(user.Id + &quot;: &quot; + user.DisplayName + &quot; &lt;&quot; + user.Mail + &quot;&gt;&quot; + user.MailboxSettings);

            await graphServiceClient.Users[userId]
                .SendMail
                .PostAsync(requestbody);

            //await graphServiceClient.Users[userId]
            //      .SendMail(message, false)
            //      .Request()
            //      .PostAsync();

        }
        catch (ODataError odataError)
        {

            Console.WriteLine(odataError.Error.Code);
            Console.WriteLine(odataError.Error.Message);

        }

The call to API was successful as I have manage to retrieve the user.Id which is my userobjectId, and my user name, but the mail is null, the error was no ResourcesNotFound, Resource could not be discovered.

I have did some research, it seems I need to assign license of 356 office in AAD to this outlook account in order to have the mailbox and the sendMail will work. But I'm a little but overwhelming by the information that I found online and not sure which is the correct approach.

Any advice or guidance will be appreciated. Thanks.

答案1

得分: 0

我将以下内容翻译为中文:

我已将“O365许可证”分配给了通过个人Outlook帐户邀请的用户,如下所示:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

当我在我的环境中运行了您的代码后,即使分配了“O365许可证”给用户,我仍然收到了相同的错误

try
{

    string tenantId = "xxxxxx";
    string clientId = "xxxxxxxx";
    string clientSecret = "xxxxxxxxx";
    string userId = "xxxxxxxxx";
    //The following scope is required to acquire the token
    string[] scopes = new string[] { "https://graph.microsoft.com/.default" };

    var options = new TokenCredentialOptions
    {
        AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
    };

    var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);

    GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);


    var message = new Message
    {
        Subject = "您的主题在这里",
        Body = new ItemBody
        {
            ContentType = BodyType.Html,
            Content = "电子邮件内容"
        },
        ToRecipients = new List<Recipient>()
    {
        new Recipient
        {
            EmailAddress = new EmailAddress
            {
                Address = "xxxx@gmail.com"
            }
        }
    },
        CcRecipients = new List<Recipient>()
    {
        new Recipient
        {
            EmailAddress = new EmailAddress
            {
                Address = "xxxxxx@gmail.com"
            }
        }
    }
    };


    Microsoft.Graph.Users.Item.SendMail
    .SendMailPostRequestBody requestbody = new()
    {
        Message = message,
        SaveToSentItems = false // or true, as you want
    };

    var user = await graphServiceClient.Users[userId].GetAsync();

        Console.WriteLine(user.Id + ": " + user.DisplayName + " <" + user.Mail + ">" + user.MailboxSettings);

    await graphServiceClient.Users[userId]
        .SendMail
        .PostAsync(requestbody);

    //await graphServiceClient.Users[userId]
    //      .SendMail(message, false)
    //      .Request()
    //      .PostAsync();

}
catch (ODataError odataError)
{

    Console.WriteLine(odataError.Error.Code);
    Console.WriteLine(odataError.Error.Message);

}

响应

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

如此MS文档中所述,个人Microsoft帐户需要Mail.Send 委托 权限,这与客户端凭据流程不兼容。

没有用户交互,您无法使用客户端凭据流程通过添加应用程序权限来发送个人Outlook帐户的电子邮件。

要解决此问题,您必须使用涉及用户交互的**委托**流程,例如授权码流程、交互式流程等。

或者,您还可以使用Outlook帐户登录到Graph Explorer,该帐户适用于委托权限,并运行以下查询以发送邮件:

POST https://graph.microsoft.com/v1.0/me/sendMail
Content-type: application/json

{
  "message": {
    "subject": "午餐见面?",
    "body": {
      "contentType": "Text",
      "content": "新的自助餐厅开业了。"
    },
    "toRecipients": [
      {
        "emailAddress": {
          "address": "xxxx@gmail.com"
        }
      }
    ],
    "ccRecipients": [
      {
        "emailAddress": {
          "address": "xxxx@gmail.com"
        }
      }
    ]
  },
  "saveToSentItems": "true"
}

响应:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

当我在Outlook的“已发送项目”中查看时,电子邮件已成功发送,如下所示:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

英文:

I assigned O365 license to the user invited with personal Outlook account like below:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

When I ran your code in my environment, I got same error even after assigning O365 license to the user:

try
        {

            string tenantId = &quot;xxxxxx&quot;;
            string clientId = &quot;xxxxxxxx&quot;;
            string clientSecret = &quot;xxxxxxxxx&quot;;
            string userId = &quot;xxxxxxxxx&quot;;
            //The following scope is required to acquire the token
            string[] scopes = new string[] { &quot;https://graph.microsoft.com/.default&quot; };

            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
            };

            var clientSecretCredential = new ClientSecretCredential(
            tenantId, clientId, clientSecret, options);

            GraphServiceClient graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);


            var message = new Message
            {
                Subject = &quot;Your subject here&quot;,
                Body = new ItemBody
                {
                    ContentType = BodyType.Html,
                    Content = &quot;Email Content&quot;
                },
                ToRecipients = new List&lt;Recipient&gt;()
            {
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = &quot;xxxx@gmail.com&quot;
                    }
                }
            },
                CcRecipients = new List&lt;Recipient&gt;()
            {
                new Recipient
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = &quot;xxxxxx@gmail.com&quot;
                    }
                }
            }
            };

          
            Microsoft.Graph.Users.Item.SendMail
            .SendMailPostRequestBody requestbody = new()
            {
                Message = message,
                SaveToSentItems = false // or true, as you want
            };

            var user = await graphServiceClient.Users[userId].GetAsync();

                Console.WriteLine(user.Id + &quot;: &quot; + user.DisplayName + &quot; &lt;&quot; + user.Mail + &quot;&gt;&quot; + user.MailboxSettings);

            await graphServiceClient.Users[userId]
                .SendMail
                .PostAsync(requestbody);

            //await graphServiceClient.Users[userId]
            //      .SendMail(message, false)
            //      .Request()
            //      .PostAsync();

        }
        catch (ODataError odataError)
        {

            Console.WriteLine(odataError.Error.Code);
            Console.WriteLine(odataError.Error.Message);

        }

Response

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

> As mentioned in this MS Document, personal Microsoft account requires Mail.Send Delegated permission that won't work with client credentials flow.

Without user interaction, you cannot send mail with personal Outlook account using client credentials flow by adding Application permission.

To resolve the issue, you must use delegated flow that involves user interaction like authorization code flow, interactive flow, etc....

Alternatively, you can also sign into Graph Explorer with Outlook account that works with Delegated permissions and run below query to send mail:

POST https://graph.microsoft.com/v1.0/me/sendMail
Content-type: application/json

{
  &quot;message&quot;: {
    &quot;subject&quot;: &quot;Meet for lunch?&quot;,
    &quot;body&quot;: {
      &quot;contentType&quot;: &quot;Text&quot;,
      &quot;content&quot;: &quot;The new cafeteria is open.&quot;
    },
    &quot;toRecipients&quot;: [
      {
        &quot;emailAddress&quot;: {
          &quot;address&quot;: &quot;xxxx@gmail.com&quot;
        }
      }
    ],
    &quot;ccRecipients&quot;: [
      {
        &quot;emailAddress&quot;: {
          &quot;address&quot;: &quot;xxxx@gmail.com&quot;
        }
      }
    ]
  },
  &quot;saveToSentItems&quot;: &quot;true&quot;
}

Response:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

When I checked the same in Outlook Sent Items, email sent successfully like below:

如何使用AAD Graph API发送电子邮件,使用个人Outlook帐户。

huangapple
  • 本文由 发表于 2023年5月11日 16:16:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定