I am trying to send mail on behalf of some users using the Microsoft Graph API through my Winforms application. I registered the app in Application Registration at Azure Portal in my tenant and assigned application permissions for sending mail to the app. I am using client credentials flow for sending mail.
The mail is successfully sent when sending the mail on behalf of my tenant user. Then I granted the admin consent to my app from another tenant and tried to send mail on behalf of that tenant's user but I get an error
Code: ErrorInvalidUser
Message: The requested user 'foo#tenanttwo.onmicrosoft.com' is invalid.
That user has a valid license of O365.
Can we send the mail on behalf of other tenant's user using the Microsoft Graph API? If yes then please help me what else I need to do?
This is the code I'm using:
var scopes = new[] { "https://graph.microsoft.com/.default" };
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(tenantID, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var message = new Microsoft.Graph.Message
{
Subject = strSubject,
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = strBody
},
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = strTo
}
}
}
};
var saveToSentItems = true;
await graphClient.Users[senderMail]
.SendMail(message, saveToSentItems)
.Request()
.PostAsync();
Related
I tried to use MS Graph API to implement a backend API to access other users email setting (for getting out-of-office message). As it is backend API, client credential flow is used. I already granted the permissions "MailboxSettings.Read" and "MailboxSettings.ReadWrite" with application type.
I used my free Azure account for testing. Assume my login account is test#hotmail.com, then my Azure domain is testhotmail.onmicrosoft.com.
I created one more user client#testhotmail.onmicrosoft.com
I can get the result using Graph Explorer as below
https://graph.microsoft.com/v1.0/users/test#hotmail.com
https://graph.microsoft.com/v1.0/users/test#hotmail.com/mailboxSettings
https://graph.microsoft.com/v1.0/users/client#testhotmail.onmicrosoft.com
But it return error for below using Graph Explorer
{
"error": {
"code": "ErrorInvalidUser",
"message": "The requested user 'client#testhotmail.onmicrosoft.com' is invalid."
} }
https://graph.microsoft.com/v1.0/users/client#testhotmail.onmicrosoft.com/mailboxSettings
3a. If call by MS Graph SDK to get the user info for client#testhotmail.onmicrosoft.com as below, it is success
var scopes = new[] { "https://graph.microsoft.com/.default" };
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var user = await graphClient.Users["client#testhotmail.onmicrosoft.com"].Request().GetAsync();
3b. If call by MS Graph SDK to get the user info for test#hotmail.com, it returns error
Microsoft.Graph.ServiceException: 'Code: Request_ResourceNotFound
Message: Resource 'test#hotmail.com' does not exist or one of its
queried reference-property objects are not present.
var user = await graphClient.Users["test#hotmail.com"].Request().GetAsync();
If call by MS Graph SDK to get the mailbox setting as below, it returned error
Microsoft.Graph.ServiceException: 'Code: ErrorInvalidUser Message: The
requested user 'test#hotmail.com' is invalid.
var scopes = new[] { "https://graph.microsoft.com/.default" };
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var mail = await graphClient.Users["test#hotmail.com"].Request().Select("MailboxSettings").GetAsync();
Or returned error for below
Microsoft.Graph.ServiceException: 'Code: ResourceNotFound Message:
Resource could not be discovered.
var mail = await graphClient.Users["client#testhotmail.onmicrosoft.com"].Request().Select("MailboxSettings").GetAsync();
using Microsoft.Graph;
using Azure.Identity;
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "aad_app_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var user = await graphClient.Users["xx#xx.onmicrosoft.com"]
.Request()
.Select("MailboxSettings")
.GetAsync();
var automaticRepliesSetting = user.MailboxSettings.AutomaticRepliesSetting;
Could you pls try this? By the way you may also try to add the 2 application permissions which mentioned in the document: MailboxSettings.Read, MailboxSettings.ReadWrite. And the most important is, your error message is invalid user, so I'm afraid you can use user_PrincipalName instead of myuser#hotmail.com. You can try to get the user_id in Azure AD potal or from the result for await graphClient.Users["myuser#hotmail.com"].Request().GetAsync();.
You are using hotmail.com , as per the doc you should also have either a personal Microsoft account with a mailbox on Outlook.com, or a Microsoft work or school account.
Hope this helps
Thanks
I'm working to send a message to Teams by using Graph API.
my application is a daemon application that sends a message automatically in the background.
I have written code like an official reference link below:
https://learn.microsoft.com/en-gb/graph/sdks/choose-authentication-providers?tabs=CS#client-credentials-provider
in my case, I use the client-credentials-provider but, I still can't send a message, and always get the below error message.
surely I have already registered my application in Azure and set for the grant of scope
How can I fix this?
Following this api document, you need to give Application api permission Teamwork.Migrate.All, and try this code below:
using Azure.Identity;
using Microsoft.Graph;
public void sendMesgAsync()
{
var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "your_tenant_name.onmicrosoft.com";
var clientId = "azure_ad_app_client_id";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var chatMessage = new ChatMessage
{
Body = new ItemBody
{
Content = "Hello World"
}
};
await graphClient.Teams["{team-id}"].Channels["{channel-id}"].Messages
.Request()
.AddAsync(chatMessage);
}
Unable send mail using Microsoft-Graph-API (Azure AD B2c).
I have tried following code but not working
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(appId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
Message message = new Message
{
Subject = "Subject of mail",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "Mail content",
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = email,
}
}
},
};
await graphClient.Me.SendMail(message).Request().PostAsync();
It gives following error :
Code: OrganizationFromTenantGuidNotFound
Message: The tenant for tenant guid 'xxxxxx' does not exist.
Inner error:
AdditionalData:
requestId: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
date: 2020-08-05T02:17:07
request-id: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
ClientRequestId: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
Note : Also Given permission for Mail.Send
This is because your Azure AD B2C tenant doesn't have an Exchange online license under O365 subscription.
So the B2C user doesn't have a mailbox to send the email although its UPN looks like an email address.
Try to assign an O365 subscription to the tenant and add an Exchange online license to the B2C user if possible.
I want to authorize user through bot and get proper information from database while chatting.
User is registered to my website database using facebook account.
So far, I have this:
var resultMessage = context.MakeMessage();
resultMessage.Type = "message";
resultMessage.Attachments = new List<Attachment>();
List<CardAction> cardButtons = new List<CardAction>();
List<CardAction> plButton = new List<CardAction>();
plButton.Add(new CardAction
{
Value = "myurl/link",
Type = "signin",
Title = "LogIn"
});
SigninCard plCard = new SigninCard("You need to authorize me", plButton);
Attachment plAttachment = plCard.ToAttachment();
resultMessage.Attachments.Add(plAttachment);
On the other side, where I should authorize the user, I have this:
public Uri link(string resource, string clientId, Uri redirectUri, User userId, string extraQueryParameters)
{
return redirectUri;
}
But that's not correct.
What parameters should I send?
How to handle this?
How to redirect user on Facebook Messenger, again?
How to authenticate and get (stored) userdata from my database into bot ?
Thank you in advance for your replies!
is there any way for accessing Gmail's Mail by IMAP using OAUTH2 authentication in asp.net c#?
using google api, I am able to get the MessageID. But unable to retrieve the details of that message:
var gmailservice = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = appName,
});
List<Message> objList = ListMessages(gmailservice, "me", AnyFromEmailAddress);
foreach (Message objM in objList)
{
// I can retrieve objM.Id but how to get message detail?
}
Or is there any free IMAP client which use OAUTH2 for login like Limilab's Mail.dll
Using MailKit and Google's OAuth2 framework from NuGet, you can do it like this:
using (var client = new ImapClient ()) {
client.Connect ("imap.gmail.com", 993, true);
var certificate = new X509Certificate2 (#"C:\path\to\certificate.p12", "password", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential (new ServiceAccountCredential.Initializer ("your-developer-id#developer.gserviceaccount.com") {
// Note: other scopes can be found here: https://developers.google.com/gmail/api/auth/scopes
Scopes = new[] { "https://mail.google.com/" },
User = "user#gmail.com"
}.FromCertificate (certificate));
// Note: result will be true if the access token was received successfully
bool result = await credential.RequestAccessTokenAsync (cancel.Token);
// use the access token as the password string
client.Authenticate ("user#gmail.com", credential.Token.AccessToken);
// ...
client.Disconnect (true);
}