I'm working on getting conversation data from the sdk, our users are getting data from developer tool too, we've noticed some data difference between the two data ways of pulling data from Genesys.
In sdk, I use PostAnalyticsConversationsDetailsJobs to get the job id, then use GetAnalyticsConversationsDetailsJob(jobId) to get the real data. In Developer tool, we use /api/v2/analytics/conversations/details/jobs to get job id then /api/v2/analytics/conversations/details/jobs/{jobId}/results to get data back. Same query is applied to both.
In sdk we got many more null data notes back, which we don't get them in developer tool, is there any way we can filter out the null notes in sdk too?
Additionally, all the node names in developer tool response are all lower cases, while we get first letter upper case in sdk, and some data we get text from developer too, but only numbers from sdk, is there a mapping table to map those data to text based on numbers? I've listed the data difference below.
||Developer Tool|SDK|
|OriginatingDirection|outbound|2|
|Purpose|customer|6|
|Direction|outbound|2|
|MediaType|callback|1|
|UsedRouting|Preferred|6|
|RequestedRoutings|Preferred|6|
|DisconnectedType|peer|10|
|SegmentType|interact|9|
The SDKs provide schema-driven classes for the request and response models.This means that they have properties defined for all possible properties supported on the model. The presence of a property in a schema does not indicate the presence of data at runtime.
The underlying HTTP transport uses JSON, which does not have an explicit schema and only contains properties for which data exists. This data is deserialized by the SDK, which sets properties in the models for any properties in the data. This yields some properties with values set, and some without. Well-formed applications should check for the presence of a value in the response before attempting to use it.
Thanks for replying @tim.smith
This is kind of confusing tho, when we build the application we intent to have the same data that the users getting from the developer tool. I think we maybe able to deal with the null nodes and node name difference in the code, for the values that are showing as text in developer tool, is there anyway we can get a mapping doc for the numbers we get in the sdk? And moving forward, if there's any new values being added, where can we find the updated mapping? This sounds like a development gap between the sdk vs developer tool
You absolutely do. The SDK is just a language-specific wrapper around the REST JSON-based API. It makes requests exactly per the Platform API documentation the same way any application in any language would.
The mapping of .NET SDK models to JSON schema property names is very simple. Take the JSON schema property name and make the first letter capitalized. So a property name like conversationEnd
becomes ConversationEnd
in the SDK.
Yes, just check if (response.SomeProperty == null)
. This is the exact same thing you'd do if you were working directly with a schema-less JSON object; you'd have to check to see if a property has a value before using it.
Thanks Tim, I think those suggestions should work.
Like I said in the previous post, the concern is more about the data difference, if there's a mapping between the text value from developer tool vs the number value from SDK, we can build a mapping in the application to translate the number values to texts before providing the data to the users. Could you provide some guidance on that? We need mapping for all the nodes listed below.
OriginatingDirection
Purpose
Direction
MediaType
UsedRouting
RequestedRoutings
DisconnectedType
SegmentType
Those are all enums contained in the SDK itself;
public enum PurposeEnum
{
OutdatedSdkVersion = 0,
Acd = 1,
Agent = 2,
Api = 3,
Botflow = 4,
Campaign = 5,
Customer = 6,
Dialer = 7,
External = 8,
Fax = 9,
Group = 10,
Inbound = 11,
Ivr = 12,
Manual = 13,
Outbound = 14,
Station = 15,
User = 16,
Voicemail = 17,
Workflow = 18
}
so what you see when you reference them depends on how you reference them.
p = AnalyticsParticipant here.
$"{convo.ConversationId}|{p.ParticipantId}|{p.Purpose}"
will return the enum as it's name for example because the interpolation automatically translates enums.
I'm not even clear how you're seeing the numbers instead of the names because you have to explicitly force the SDK to show it's numbers in most cases;
PurposeEnum p = PurposeEnum.Botflow;
Console.WriteLine( p );
Console.WriteLine( $"{p}" );
Console.WriteLine( string.Format( "{0}" , p ));
All come out with;
Botflow
Botflow
Botflow
The only way I can get to the number under the enum is forcibly casting it or explicitly asking for the value;
Console.WriteLine( p ); // Botflow
Console.WriteLine( (int)p ); // 4
Console.WriteLine( p.ToString() ); // Botflow
1 Like
Hi @Eos_Rios, in my code I don't send anything to convert the text to numbers, as far as I think, the only parameter I'm parsing to PostAnalyticsConversationsDetailsJobs is the asyncConversationQuery, and after getting the job id, that's the only parameter I parsed to GetAnalyticsConversationsDetailsJobResults
Here's the code I use, could you please help me to figure out where the conversion is applied?
var apiInstance = new ConversationsApi();
List<ConversationDetailQueryPredicate> Predicates = new List<ConversationDetailQueryPredicate>();
ConversationDetailQueryPredicate divisionId = new ConversationDetailQueryPredicate
{
Dimension = ConversationDetailQueryPredicate.DimensionEnum.Divisionid,
Value = "xxxxxxxxxxxxxxxxx",
Type = ConversationDetailQueryPredicate.TypeEnum.Dimension,
Operator = ConversationDetailQueryPredicate.OperatorEnum.Matches
};
Predicates.Add(divisionId);
ConversationDetailQueryFilter QueryFilter = new ConversationDetailQueryFilter();
QueryFilter.Type = ConversationDetailQueryFilter.TypeEnum.Or;
QueryFilter.Predicates = Predicates;
List<ConversationDetailQueryFilter> Filters = new List<ConversationDetailQueryFilter>();
Filters.Add(QueryFilter);
List<SegmentDetailQueryPredicate> segmentFilterPredicates = new List<SegmentDetailQueryPredicate>();
SegmentDetailQueryPredicate callbackSegment = new SegmentDetailQueryPredicate
{
Type = SegmentDetailQueryPredicate.TypeEnum.Dimension,
Dimension = SegmentDetailQueryPredicate.DimensionEnum.Mediatype,
Value = "callback",
Operator = SegmentDetailQueryPredicate.OperatorEnum.Matches
};
segmentFilterPredicates.Add(callbackSegment);
SegmentDetailQueryPredicate voiceSegment = new SegmentDetailQueryPredicate
{
Type = SegmentDetailQueryPredicate.TypeEnum.Dimension,
Dimension = SegmentDetailQueryPredicate.DimensionEnum.Mediatype,
Value = "voice",
Operator = SegmentDetailQueryPredicate.OperatorEnum.Matches
};
segmentFilterPredicates.Add(voiceSegment);
SegmentDetailQueryFilter segmentDetailQueryFilter = new SegmentDetailQueryFilter();
segmentDetailQueryFilter.Type = SegmentDetailQueryFilter.TypeEnum.Or;
segmentDetailQueryFilter.Predicates = segmentFilterPredicates;
List<SegmentDetailQueryFilter> filterPredicates = new List<SegmentDetailQueryFilter>();
filterPredicates.Add(segmentDetailQueryFilter);
AsyncConversationQuery asyncConversationQuery = new AsyncConversationQuery
{
Interval = "2022-06-07T15:00:00Z/2022-06-07T15:05:00Z",
Order = AsyncConversationQuery.OrderEnum.Asc,
ConversationFilters = Filters,
OrderBy = AsyncConversationQuery.OrderByEnum.Conversationstart,
Limit = 1000,
SegmentFilters = filterPredicates
};
AsyncQueryResponse conversationDetailResponse = apiInstance.PostAnalyticsConversationsDetailsJobs(asyncConversationQuery);
var jobId = conversationDetailResponse.JobId;
AnalyticsConversationAsyncQueryResponse result = apiInstance.GetAnalyticsConversationsDetailsJobResults(jobId);
foreach (var conversation in result.Conversations)
{
Console.WriteLine(JsonSerializer.Serialize(conversation));
}
You have some fundamental flaws in your understanding of what's going on here.
-
The SDK returns the JSON as already translated objects (POCOs).
-
You are manually re-serializing those POCOs into new JSON expecting it to be the same as the JSON that created them.
If all you want is the original JSON from the API just use the toJson() function of the returned object;
So just Console.Writeline( result.toJson() );
Or use the returned objects as objects instead of trying to re-parse the JSON yourself later and they make sense.
@Eos_Rios
I think we're using the same library, but somehow we're not getting the same results. I tried the toJson function yesterday but not getting the dataset, instead when I put the results in the foreach loop, I can get conversation record, for some reason the toJson doesn't work for me.
This is the result I got after a applying the ToJson function to the result.
FYI, here're the libraries I use

Does it still do that if you add the parenthesis to ToJson() that are missing there?
It works perfect after adding () in the code, thank you!
1 Like