Not able to fetch the status of user from Teams using graph client

Brass Contributor

Hi,

 

We are working on a bot framwerk project where we need to update our bot status based on the status in the ms teams (like available, un available, in a meeting).

 

We have used the below code for getting the status,

 

try
            {
                var clientId = "#client id";
                var clientSecret = "# client secret";
                var tenantId = "# tenant id";

                string authority = $"https://login.microsoftonline.com/{tenantId}";
                string scope = "https://graph.microsoft.com/.default";

                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                    .Create(clientId)
                    .WithClientSecret(clientSecret)
                    .WithAuthority(new Uri(authority))
                    .Build();

                string[] scopes = new[] { scope };


                AuthenticationResult result = await app.AcquireTokenForClient(scopes)
                    .ExecuteAsync();

                string accessToken = result.AccessToken;

                // Create a GraphServiceClient instance using the obtained access token
                GraphServiceClient graphClient = new GraphServiceClient(
                    new DelegateAuthenticationProvider(requestMessage =>
                    {
                        requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
                        return Task.FromResult(0);
                    }));

                // Use the graphClient to make requests to Microsoft Graph API
                var user = await graphClient.Users[emailId].Presence.Request().GetAsync();

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "------------- There was an error while getting  status");
            }

 

But in this code we are passing the default scope. In the actual app registration we have added the graph client permission for 'PRESENSE.READ' and while trying to get the user Presence feature, its throwing a error because of no permission .

 

So explicitly we have assigned the token which has right permission and tried to fetch the status , but still the availability is shown "PRESENSE UNKNOWN" where the user status was Available.

 

Lakshmi_0-1700236132141.png

 

 

It will be good if you can help with use on adding the exact scopes of the particular app registration in code and also need to fetch the correct status of user.

 

8 Replies

Hello @Lakshmi_145 - Thanks for raising your query.

Please find below solution:
1) Please pass the AAD Object Id of user rather than email id while calling the API:
Like below:
https://graph.microsoft.com/v1.0/users/66825e03-7ef5-42da-9069-724602c31f6b/presence

Reference doc: Get presence - Microsoft Graph v1.0 | Microsoft Learn
Because you are passing wrong id, it is returning result as "PresenceUnknown".


2) Secondly, please add scope in your scope variable as "Presence.Read".

Please let us know if you still need any further help here.

Could you please share your valuable feedback via Microsoft Teams Developer Feedback link.

@ChetanSharma-msft 

 

We have updated the code to add the scope Presence.Read in scopes.

 

try
            {
                var clientId = "#client id";
                var clientSecret = "# client secret";
                var tenantId = "# tenant id";

                string authority = $"https://login.microsoftonline.com/{tenantId}";
                string scope = "https://graph.microsoft.com/.default";

                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                    .Create(clientId)
                    .WithClientSecret(clientSecret)
                    .WithAuthority(new Uri(authority))
                    .Build();

                string[] scopes = new[] { scope, "Presence.Read" };


                AuthenticationResult result = await app.AcquireTokenForClient(scopes)
                    .ExecuteAsync();

                string accessToken = result.AccessToken;

                // Create a GraphServiceClient instance using the obtained access token
                GraphServiceClient graphClient = new GraphServiceClient(
                    new DelegateAuthenticationProvider(requestMessage =>
                    {
                        requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
                        return Task.FromResult(0);
                    }));

                // Use the graphClient to make requests to Microsoft Graph API
                var user = await graphClient.Users[connectionRequest.Requestor.User.AadObjectId].Presence.Request().GetAsync();

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "------------- There was an error while getting  status");
            }

 

And getting the below exception,

 

Lakshmi_1-1700462089534.png

 

We are able to fetch the status by giving the correct token explicitly. 

 

 

@Lakshmi_145 -  Please try to add only One scope and remove the other one.
Also, check if your generated token is having the same scope and check if it is working in Postman or Graph Explorer as well.

@ChetanSharma-msft 

 

We tried to give string[] scopes = new[] { "Presence.Read" }; 

and got the exception,

 

Lakshmi_0-1700462884588.png

 

 

@ChetanSharma-msft 

 

We tried to give "Presence.Read" in the below formats and it did not work

 

Lakshmi_0-1700464810887.png

 

Lakshmi_1-1700464871854.png

 

Lakshmi_2-1700464963473.png

 

@ChetanSharma-msft ,

 

Is there any other option to provide the tokens for the specific scope

@Lakshmi_145 - If you have added the Presence.Read permission on the app registration, using .default should work. Also, if you want to specify the exact scope, you can replace "https://graph.microsoft.com/.default" with "https://graph.microsoft.com/Presence.Read" in your scopes array which i think you are already doing.

Secondly, the presence status of a user in Teams can be one of the following: Available, Away, BeRightBack, Busy, DoNotDisturb, Offline, PresenceUnknown. If you are getting "PresenceUnknown", it could be due to one of the following reasons:

  1. The user is not found.
  2. The cloud-based mailbox is not available.
  3. The user or mailbox settings don't allow to share presence.

Could you please verify that?