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:
How can see the real error message being returned? This error doesn't return any meaningful information...
What am I doing incorrectly in my call to "onlineMeetings" that doesn't allow me to access or view this object?
@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:
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,
I've split out this issue per discussion with @Sridevi: See here
Initially, I too got same error when I ran your code in my environment without catching the exception:
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:
To resolve the error, make sure to add OnlineMeetings.Read
permission of Delegated type that is required to list online meetings:
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:
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:
Reference: List transcripts - Microsoft Graph v1.0