Search code examples
c#azuremicrosoft-graph-apimicrosoft-teamstranscription

Microsoft Graph - Accessing OnlineMeetings Transcripts - The expression cannot be evaluated


Ok I have the following C# code used in a console app:

var deviceCodeCredential = new DeviceCodeCredential(new DeviceCodeCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    ClientId = AzureClientID,
    TenantId = AzureTenantID,
    DeviceCodeCallback = (code, cancellation) =>
    {
        Console.WriteLine(code.Message);
        return Task.FromResult(0);
    }
});

var graphClient = new GraphServiceClient(deviceCodeCredential, 
    new[] { "User.Read", "OnlineMeetingTranscript.Read.All" });            
var result = await graphClient.Me.OnlineMeetings.GetAsync();

When I run this I get the following error(after logging in):

Microsoft.Graph.Models.ODataErrors.ODataError - The expression cannot be evaluated. A common cause of this error is attempting to pass a lambda into a delegate.

In fact with all sort of combinations of things I get the same error:

graphClient.Me.OnlineMeetings["BigStringFromURL"].GetAsync()
graphClient.Me.OnlineMeetings["BigStringFromURL"].Transcripts["0"].GetAsync()
etc..

I'm confident that the rest of the application is working as I can call:

graphClient.Me.GetAsync();

Without issue, however any enumeration of the "OnlineMeetings" object results in this error. I have two big questions:

  1. How can see the real error message being returned? This error doesn't return any meaningful information...

  2. What am I doing incorrectly in my call to "onlineMeetings" that doesn't allow me to access or view this object?

Update 1

@Sridevi Got me close, yes two issues, the error handling and the permissions/filters are resolved by the suggested changes, however even with these two change I can't fully obtain the transcript, so as an example:

var meeting = await graphClient.Me.OnlineMeetings.GetAsync((requestConfiguration) =>
{
    requestConfiguration.QueryParameters.Filter = "joinWebUrl eq '" + TeamsURL + "'";
});

var transcript = await graphClient.Me.OnlineMeetings[meeting.Value[0].Id].Transcripts.GetAsync();

var transcriptText = await graphClient.Me.OnlineMeetings[meeting.Value[0].Id].Transcripts[transcript.Value[0].Id].GetAsync();

If I run this I get an object:

enter image description here

With a NULL content, if I try to call the content item directly:

Invalid format 'application/octet-stream, application/json' specified.

I think there's just one small thing I'm missing here, I did attempt to use the code suggested but it just prints the same thing:

"Content": null,

Update 2

I've split out this issue per discussion with @Sridevi: See here


Solution

  • Initially, I too got same error when I ran your code in my environment without catching the exception:

    enter image description here

    To know the exact error message, make use of below modified code by including try-catch method in it where I got "Forbidden" like this:

    using Microsoft.Graph.Models.ODataErrors;
    
    var deviceCodeCredential = new DeviceCodeCredential(options);
    var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
    
    try
    {
        var result = await graphClient.Me.OnlineMeetings.GetAsync();
    }
    catch (ODataError odataError)
    {
        Console.WriteLine($"Error Code: {odataError.Error.Code}");
        throw;
    }
    

    Response:

    enter image description here

    To resolve the error, make sure to add OnlineMeetings.Read permission of Delegated type that is required to list online meetings:

    enter image description here

    Now, I used below modified code to get the online meeting ID by filtering them with joining URL:

    using Azure.Identity;
    using Microsoft.Graph;
    using Microsoft.Graph.Models.ODataErrors;
    
    namespace MSOnlineMeeting
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                var scopes = new[] { "User.Read", "OnlineMeetingTranscript.Read.All" };
                var AzureTenantID = "tenantId";
                var AzureClientID = "appId";
    
                var options = new DeviceCodeCredentialOptions
                {
                    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                    ClientId = AzureClientID,
                    TenantId = AzureTenantID,
                    DeviceCodeCallback = (code, cancellation) =>
                    {
                        Console.WriteLine(code.Message);
                        return Task.FromResult(0);
                    },
                };
    
                var deviceCodeCredential = new DeviceCodeCredential(options);
                var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
    
                try
                {
                    var result = await graphClient.Me.OnlineMeetings.GetAsync((requestConfiguration) =>
                    {
                        requestConfiguration.QueryParameters.Filter = "joinWebUrl eq 'xxxxxxxxx'";
                    });
    
                    if (result != null && result.Value != null)
                    {
                        foreach (var meeting in result.Value)
                        {
                            Console.WriteLine($"Meeting ID: {meeting.Id}");
                            Console.WriteLine($"Meeting Subject: {meeting.Subject}");
                            Console.WriteLine();
                        }
                    }
                    else
                    {
                        Console.WriteLine("No online meetings found.");
                    }
                }
                catch (ODataError odataError)
                {
                    Console.WriteLine($"Error Code: {odataError.Error.Code}");
                    throw;
                }
            }
        }
    }
    

    Response:

    enter image description here

    You can now use this meeting ID to fetch the online meeting transcripts by running below code:

    using System.Text.Json;
    using Azure.Identity;
    using Microsoft.Graph;
    using Microsoft.Graph.Models.ODataErrors;
    
    namespace MSOnlineMeeting
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                var scopes = new[] { "User.Read", "OnlineMeetingTranscript.Read.All" };
                var AzureTenantID = "tenantId";
                var AzureClientID = "appId";
    
                var options = new DeviceCodeCredentialOptions
                {
                    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
                    ClientId = AzureClientID,
                    TenantId = AzureTenantID,
                    DeviceCodeCallback = (code, cancellation) =>
                    {
                        Console.WriteLine(code.Message);
                        return Task.FromResult(0);
                    },
                };
    
                var deviceCodeCredential = new DeviceCodeCredential(options);
                var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
    
                try
                {
                    var result = await graphClient.Me.OnlineMeetings["meetingID"].Transcripts.GetAsync();
                    var jsonresult = JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true });
                    Console.WriteLine(jsonresult);
                }
                catch (ODataError odataError)
                {
                    Console.WriteLine(odataError.Error.Code);
                    Console.WriteLine(odataError.Error.Message);
                    throw;
                }
            }
        }
    }
    

    Response:

    enter image description here

    Reference: List transcripts - Microsoft Graph v1.0