Microsoft Graph API returns no data or unexpected errors for Viva Learning

Bruno 0 Reputation points
2024-04-26T09:44:11.1233333+00:00

Hello,

I'm exploring options to create a custom learning management system for my company. The first thing I would like to do is to pull data from Microsoft Viva Learning via the Microsoft Graph API, for example to see which courses the employees have completed. The next step will be to write that data on a SharePoint site. I'm using the C# Microsoft Graph quick start example as a base, so I can make use of the Microsoft Graph SDK for C#. This is a .NET 7 project, so I upgraded it to a .NET 8 project with the latest versions of the packages:

  • Azure.Identity version 1.11.2
  • Microsoft.Graph version 5.49.0

For authentication, I have 2 different clients in my code:

  • ApplicationGraphClient which is using a ClientSecretCredential with a client secret provided by my administrator
  • UserGraphClient which is using an InteractiveBrowserCredential, so that I can log in with my own account

The following permissions have been given to the app by the administrator:

  • application permissions
    • User.Read.All
    • LearningAssignedCourse.Read.All
    • LearningContent.ReadWrite.All
    • LearningSelfInitiatedCourse.Read.All
    • Sites.ReadWrite.All
  • delegated user permissions
    • User.Read
    • offline_access
    • LearningAssignedCourse.Read
    • LearningContent.ReadWrite.All
    • LearningSelfInitiatedCourse.Read
    • LearningProvider.ReadWrite
    • Sites.ReadWrite.All

According to the docs, it's possible to list the learning course activities both for the signed-in user, but also for any user by ID. However, in both cases, I'm getting an empty collection as a result, despite the facts that I've completed several courses in Viva Learning. There is no error or exception.

  • in UserGraphClient: await graphClient.Me.EmployeeExperience.LearningCourseActivities.GetAsync(); // returns an empty collection
  • in ApplicationGraphClient: await graphClient.Users[myUser.Id].EmployeeExperience.LearningCourseActivities.GetAsync(); // returns an empty collection

My administrator also made me a knowledge admin, so I have access to the admin tab of Viva Learning in Teams, and I'm able to export the course activity data for my user. The exported Excel file does contain the expected completed courses.

I've also tried to get all the learning activities for all the employees, with a top 10 limit, but this fail with an unknown error and code 404, so I suppose it's implemented in the SDK but not supported by the API. In ApplicationGraphClient:

await graphClient.EmployeeExperience.LearningCourseActivities.GetAsync(config =>
{
    config.QueryParameters.Top = 10;
});

Lastly, I've tried to list the learning providers using both the UserGraphClient and ApplicationGraphClient, and in both cases I get the error message "Insufficient privileges to complete the operation.". As you could see above, I do have the delegated LearningProvider.ReadWrite permission, so it should at least work for my signed-in user.

Thank you in advance for your help.

Viva Learning
Viva Learning
A Microsoft Viva module that provides employees with formal and informal learning.
84 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
10,662 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,279 questions
{count} votes

1 answer

Sort by: Most helpful
  1. CarlZhao-MSFT 37,216 Reputation points
    2024-04-29T07:58:05.7866667+00:00

    Hi @Bruno

    These API endpoints do not support application permissions, so do not attempt to create an ApplicationGraphClient object.

    They are only applicable in a delegated context, so you can try using the auth code flow or ROPC flow to create a UserGraphClient object. If you are receiving empty responses or insufficient permissions errors, then try exporting your access token and decoding it to check if it contains the targeted permissions.

    var tokenResponse = await authCodeCredential.GetTokenAsync(
                    new Azure.Core.TokenRequestContext(scopes));
    
    Console.WriteLine(tokenResponse.Token);
    

    Hope this helps.

    If the reply is helpful, please click Accept Answer and kindly upvote it. If you have additional questions about this answer, please click Comment.