Get emails, not MS Teams messages from MS Graph - microsoft-graph-api

When I GET https://graph.microsoft.com/v1.0/me/messages, it returns messages I received in MS Teams.
How can I query for only emails using the MS Graph API?

As AAvery said, I believe as well that Teams send you the messages to your Outlook after a while of inactivity. Try to remove those emails(notifications) from MS Teams and try to GET again.
Eventually, try this: https://graph.microsoft.com/v1.0/me/mailFolders/Inbox/messages/delta

I came here to ask same question but I was able to get some clue which helped me to get my code working.
my old code:
public async void ReadMails(IAuthenticationProvider authProvider)
{
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var messages = await graphClient.Me.Messages
.Request()
.Select(e => new
{
e.Sender,
e.Subject,
e.Body
})
.GetAsync();
}
New code code which reads only emails now.
public async void ReadMails(IAuthenticationProvider authProvider)
{
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var messages = await graphClient.Me.MailFolders.Inbox.Messages
.Request()
.Select(e => new
{
e.Sender,
e.Subject,
e.Body
})
.GetAsync();
}
I hope this helps.

Related

Mail properties not being saved in UpdateAsync

I am starting out in MS Graph. I have below code to pick up all mail messages from Inbox of a specific user. Then I go through each message, process it and set its Subject. When I try to save back message using UpdateAsync it executes fine but change in mail subject text doesn't seem to get saved.
What am I doing wrong?
Thanks
Regards
var inboxMessages = await graphClient
.Users[user.Id]
.MailFolders.Inbox
.Messages
.Request()
.OrderBy("receivedDateTime DESC")
.GetAsync();
foreach(Microsoft.Graph.Message x in inboxMessages) {
//Process message
// ...
x.Subject = "Processed: " + x.Subject
//Save changes to message Subject
await graphClient
.Users[user.Id]
.MailFolders.Inbox
.Messages[$"{x.Id}"]
.Request()
.UpdateAsync(x);
}
According to the documentation you can update Subject only for messages that have isDraft = true but not for those that have already been sent.

MS Graph - how to check for return code 204 after subscription is deleted?

Just new to ms graph and also to .net.
I'm trying to write a method that deletes a notification subscription. The code itself seems to work. But i need to know how to look up the actual return code from the upstream API instead of just sending back a 204.
Here's the code:
[Route("msgraphnotification/{subscriptionId}")]
[HttpDelete]
[AllowAnonymous]
public async Task<Int> delete(string subscriptionId)
{
try{
GraphServiceClient graphClient = await getAuthToken();
await graphClient.Subscriptions["{subscription-id}"]
.Request()
.DeleteAsync();
return 204; // this is what I want to fix.
}
catch(Exception ex){
Console.Write(ex);
return 404;
}
}
If you really need to know the response code you can send HTTP request with the .Net Microsoft Graph client library.
// Get the request URL for deleting a subscription
var requestUrl = client.Subscriptions["{subscription-id}"].Request().RequestUrl;
// Create the request message.
var hrm = new HttpRequestMessage(HttpMethod.Delete, requestUrl);
// Authenticate HttpRequestMessage
await client.AuthenticationProvider.AuthenticateRequestAsync(hrm);
// Send the request and get the response.
var response = await client.HttpProvider.SendAsync(hrm);
// Get the status code.
if (!response.IsSuccessStatusCode)
{
throw new ServiceException(
new Error
{
Code = response.StatusCode.ToString(),
Message = await response.Content.ReadAsStringAsync()
});
}
else
{
var statusCode = (int)response.StatusCode;
}
...

Unable to send email using graph API

The below code is used to retrieve token
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(clientsec)
.Build();
AuthorizationCodeProvider authprovider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
//ClientCredentialProvider authprovider = new ClientCredentialProvider(confidentialClientApplication);
var authResult = await confidentialClientApplication
.AcquireTokenForClient(scopes)
.ExecuteAsync().ConfigureAwait(false);
return authResult.AccessToken;
and calling sending mail using Me is not working.
await graphServiceClient.Me
.SendMail(email, false)
.Request()
.PostAsync();
Can someone assist what is the wrong here?
In my scenario I have to send mails to using multiple from addresses.
You are using the ClientCredentials (that means there is no user) so .Me() isn’t available.
To send a mail as a specific user, you’ll need to reference the user.
Here is a sample How that works for teams. https://learn.microsoft.com/en-us/graph/sdks/create-requests?tabs=CS#updating-an-existing-entity-with-patch
var userId = "71766077-aacc-470a-be5e-ba47db3b2e88";
await graphClient.Users[userId]
.SendMail(email, false)
.Request()
.PostAsync();
I’m not sure if you can also use the username (upn) instead of the id.

Store authentification data in MVC

I have created a custom Authorize attribute where I use the Office Graph to get AAD groups the current user is member of, and based on those I reject or authorize the user. I want to save the groups, because the call to Office Graph takes some performance. What would be the correct way to save that kind of data? I can see some people saves it to a SQL server, but then I would need to ensure cleanup etc.
Also I can see in some threads the session state is stated to be a bad choice due to concurrency. So the question is what options do you have to store this kind of information?
All suggestions are welcome.
If you were only using the group_id info, there is no need to use Office Graph and store it at all. We can enable Azure AD issue the groups claims by change the manifest of Azure AD like below:(refer this code sample)
"groupMembershipClaims": "All",
And if you are also using other info about groups, you can store these info into claims. Here is a code sample that add the name of groups into claims for your reference:
AuthorizationCodeReceived = async context =>
{
ClientCredential credential = new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst(Globals.ObjectIdClaimType).Value;
AuthenticationContext authContext = new AuthenticationContext(ConfigHelper.Authority, new TokenDbCache(userObjectId));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(
context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigHelper.GraphResourceId);
ActiveDirectoryClient graphClient = new ActiveDirectoryClient(new Uri(ConfigHelper.GraphServiceRoot),
async () => { return await Task.FromResult(result.AccessToken); }
);
try
{
foreach (var groupClaim in context.AuthenticationTicket.Identity.FindAll("groups"))
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri($"https://graph.windows.net/adfei.onmicrosoft.com/groups/{groupClaim.Value}?api-version=1.6"),
Method = HttpMethod.Get,
};
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage httpResponse = httpClient.SendAsync(request).Result;
var retJSON = httpResponse.Content.ReadAsStringAsync().Result;
var dict = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(retJSON);
((ClaimsIdentity)context.AuthenticationTicket.Identity).AddClaim(new Claim("groupName", dict["displayName"].ToString()));
}
}
}
catch (Exception ex)
{
}
},
Then we can these info from controller using the code below:
ClaimsPrincipal.Current.FindAll("groupName")

Microsoft Bot Framework project to add a chatbot to my website. I cannot use the Web Chat client. What other methods can I use ?

I am working on a Microsoft Bot Framework project to add a chatbot to my website.
I need to pass data continuously from the chat UI to the Bot to get user details and current page details. Therefore I cannot use the Web Chat client.
What other methods can I use apart from creating my own chat interface ?
What other methods can I use apart from creating my own chat interface ? According to this statement, WebChat is the easiest way. Because only with an embeded Iframe you are done creating your chatbot. Apart from that,
There is a REST Api to access the botframework. It is called as Direct Line API. You can find documentation from,
HERE
Below is a code sample about how you can use it. I tried with the ASP.NET MVC application.
private async Task<bool> PostMessage(string message)
{
bool IsReplyReceived = false;
client = new HttpClient();
client.BaseAddress = new Uri("https://directline.botframework.com/api/conversations/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", "[YourAccessToken]");
response = await client.GetAsync("/api/tokens/");
if (response.IsSuccessStatusCode)
{
var conversation = new Conversation();
response = await client.PostAsJsonAsync("/api/conversations/", conversation);
if (response.IsSuccessStatusCode)
{
Conversation ConversationInfo = response.Content.ReadAsAsync(typeof(Conversation)).Result as Conversation;
string conversationUrl = ConversationInfo.conversationId+"/messages/";
BotDirectLineApproch.Models.Message msg = new BotDirectLineApproch.Models.Message() { text = message };
response = await client.PostAsJsonAsync(conversationUrl,msg);
if (response.IsSuccessStatusCode)
{
response = await client.GetAsync(conversationUrl);
if (response.IsSuccessStatusCode)
{
MessageSet BotMessage = response.Content.ReadAsAsync(typeof(MessageSet)).Result as MessageSet;
ViewBag.Messages = BotMessage;
IsReplyReceived = true;
}
}
}
}
return IsReplyReceived;
}
In here Message, MessageSet and Conversation are classes created by looking at the Json response in the documentation. If you need, I can add that also.
Cheers!

Resources