I need help Parsing Microsoft Graph API Call Records in C#

Nate Waldron 0 Reputation points
2025-03-24T15:12:57.1966667+00:00

I need help with parsing the response from the Microsoft Graph API's GET /callRecords endpoint. The JSON response I received is 3100 lines long. I have deserialized it into a Microsoft.Graph.CallRecord object and can inspect the 15 sessions it contains. I also included the expand=segments parameter to inspect the segments within each session. I need guidance on how to transform this data into a human-readable call flow using C#. Specifically, I want to outline the sequence of events, such as who called whom, which bots facilitated the connections, and any call transfers.

I'm hoping to be able to figure out each step that the call took. For example, "Diego Siciliani placed the call (known via 'organizer'). The first leg the call took was connecting Diego to a clientUserAgent serviceEndpoint (known via 'odata type'). The second leg the call took was connecting in the recording bot according to the user's policy (known from 'userAgent.role'). The third leg was connecting to Microsoft.Skype.Platform.Echo.Logic (known via userAgent.headerValue). The fourth leg was connecting to Adele Vance (known via 'user.displayName')... etc.

Can you help me understand how to do this?

Here's the start of my C# code:


var config = new ConfigurationBuilder()
    .SetBasePath(projectDirectory)
    .AddJsonFile("appsettings.json", false, true)
    .Build();
var authenticationProvider = CreateAuthorizationProvider(config);
var graphServiceClient = new GraphServiceClient(authenticationProvider);
var config = LoadAppSettings();
var graphClient = GetAuthenticatedGraphClient(config);
var testCallId = config["testCallId"];
var options = new List<QueryOption> { new QueryOption("$top", "1") };
var graphResult = await graphClient.Communications.CallRecords[testCallId]
	.Request()
	.Expand("sessions($expand=segments)")
	.GetAsync();
var jsonResult = JsonSerializer.Serialize(graphResult, new JsonSerializerOptions { WriteIndented = true });
var callRecord = JsonSerializer.Deserialize<CallRecord>(jsonResult);
Microsoft Security | Microsoft Graph
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Michael Taylor 60,161 Reputation points
    2025-03-24T15:40:11.6+00:00

    Please provide us the raw JSON that you're using to build up your communication information so we can better understand the rules you are using. Redact the sensitive information first. Then provide us the general rules you're going to use to determine that field 1 represents X, field 2 represents Y, etc.

    In terms of your code, you appear to be using the older syntax for Azure SDK calls. I notice you're getting the typed results as graphResults. Then you are converting to JSON and then deserializing it again to get to the call records. This is unnecessary because the GetAsync call has already done all this work for you. If for some reason you wanted to serialize the data again then there is a Serialize method for that, but you shoudln't need to do that here.

    I don't use Graph for communications but I believe this is the equivalent code you want.

    var graphResult = await graphServiceClient.Communications.CallRecords["123"]                
            .GetAsync(config => {
                config.QueryParameters.Expand = ["sessions($expand=semgents)"];
            });
    
    //Returned data is already represented as a CallRecord
    if (graphResult != null)
    {
        //Enumerate the sessions, could be null
        foreach (var session in graphResult.Sessions)
        {
            //Enumerate the segments of the session, could be null
            foreach (var segment in session.Segments)
            {
                //Do your work here
            };
        };
    };
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.