We are working on a nightly script that gets a list of conversation Id's for the previous day, we are able to filter on dimensions, or metrics, however we cannot filter on both of them at the same time.
Here's a snippet of the code in question:
api_instance = PureCloudPlatformClientV2.AnalyticsApi(authToken)
query = PureCloudPlatformClientV2.ConversationQuery()
query.interval = "2023-07-03T04:00:00.000Z/2023-07-07T04:00:00.000Z"
query.paging = PureCloudPlatformClientV2.PagingSpec()query.paging.page_number = '1'
query.paging.page_size = '2'query.conversation_filters = [PureCloudPlatformClientV2.ConversationDetailQueryFilter()]
query.conversation_filters[0].type = "and"query.conversation_filters[0].clauses = [PureCloudPlatformClientV2.ConversationDetailQueryClause()]
query.conversation_filters[0].clauses[0].type = "and"
query.conversation_filters[0].clauses[0].predicates = [PureCloudPlatformClientV2.ConversationDetailQueryPredicate()] * 5query.conversation_filters[0].clauses[0].predicates[0].type = "dimension"
query.conversation_filters[0].clauses[0].predicates[0].dimension = "divisionId"
query.conversation_filters[0].clauses[0].predicates[0].operator = "matches"
query.conversation_filters[0].clauses[0].predicates[0].value = "5338ce2b-8a04-4b0e-bea2-cb8b24ad76aa"query.conversation_filters[0].clauses[0].predicates[1].type = "dimension"
query.conversation_filters[0].clauses[0].predicates[1].dimension = "originatingDirection"
query.conversation_filters[0].clauses[0].predicates[1].operator = "matches"
query.conversation_filters[0].clauses[0].predicates[1].value = "inbound"
query.conversation_filters[0].clauses[0].predicates[2].type = "metric"
query.conversation_filters[0].clauses[0].predicates[2].metric = "tTalk"
query.conversation_filters[0].clauses[0].predicates[2].range = PureCloudPlatformClientV2.NumericRange()
query.conversation_filters[0].clauses[0].predicates[2].range.gt = "60000"query.conversation_filters[0].clauses[0].predicates[3].type = "metric"
query.conversation_filters[0].clauses[0].predicates[3].metric = "nBlindTransferred"
query.conversation_filters[0].clauses[0].predicates[3].operator = "notExists"
query.conversation_filters[0].clauses[0].predicates[3].value = None
query.conversation_filters[0].clauses[0].predicates[3].range = Nonequery.conversation_filters[0].clauses[0].predicates[4].type = "metric"
query.conversation_filters[0].clauses[0].predicates[4].metric = "nConsultTransferred"
query.conversation_filters[0].clauses[0].predicates[4].operator = "notExists"
query.conversation_filters[0].clauses[0].predicates[4].value = None
query.conversation_filters[0].clauses[0].predicates[4].range = None
When running these filters we get the error:
Traceback (most recent call last):
File "c:\Users...\gcConversationSearch.py", line 41, in
query.conversation_filters[0].clauses[0].predicates[2].dimension = None
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\models\conversation_detail_query_predicate.py", line 115, in dimension
if dimension.lower() not in map(str.lower, allowed_values):
AttributeError: 'NoneType' object has no attribute 'lower'
PS C:\Users\maxwed2> & "C:/Program Files/Python310/python.exe" "c:/Users/maxwed2/OneDrive - Nationwide/Desktop/gcConversationSearch.py"
Traceback (most recent call last):
File "c:\Users...\Desktop\gcConversationSearch.py", line 98, in
api_response = api_instance.post_analytics_conversations_details_query(query)
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\apis\analytics_api.py", line 2542, in post_analytics_conversations_details_query
response = self.api_client.call_api(resource_path, 'POST',
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\api_client.py", line 530, in call_api
return self.__call_api(resource_path, method,
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\api_client.py", line 343, in __call_api
response_data = self.request(method, url, query_params=query_params,
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\api_client.py", line 565, in request
return self.rest_client.POST(url,
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\rest.py", line 225, in POST
return self.request("POST", url,
File "C:\Users...\AppData\Roaming\Python\Python310\site-packages\PureCloudPlatformClientV2\rest.py", line 197, in request
raise ApiException(http_resp=r)
PureCloudPlatformClientV2.rest.ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Content-Length': '195', 'Connection': 'keep-alive', 'Date': 'Mon, 10 Jul 2023 18:25:30 GMT', 'ININ-Correlation-Id': '3de06140-aac7-4c06-82f6-3ced2a917ecd', 'Strict-Transport-Security':
'max-age=600; includeSubDomains', 'Cache-Control': 'no-cache, no-store, must-revalidate', 'X-Cache': 'Error from cloudfront', 'Via': '1.1 8c2dc914428d194718c8f636a78a5f74.cloudfront.net (CloudFront)', 'X-Amz-Cf-Pop': 'DFW57-P3', 'X-Amz-Cf-Id': 'NoXTrlsOH05nps4qL0Bs_8eaGjDs89BgGbf5dURLZoyx5oqupI_Ygg=='})
HTTP response body: {"message":"dimension must be null when using a metric predicate","code":"bad.request","status":400,"messageParams":{},"contextId":"3de06140-aac7-4c06-82f6-3ced2a917ecd","details":[],"errors":[]}
The part that stands out is:
HTTP response body: {"message":"dimension must be null when using a metric predicate","code":"bad.request","status":400,"messageParams":{},"contextId":"3de06140-aac7-4c06-82f6-3ced2a917ecd","details":[],"errors":[]}
Based on this error "dimension must be null when using a metric predicate" we tried updating our code to have dimension = None like below for all of our metric types but hit another error (example just shows 1 of 3 places we updated it):
query.conversation_filters[0].clauses[0].predicates[3].type = "metric"
query.conversation_filters[0].clauses[0].predicates[3].metric = "nBlindTransferred"
query.conversation_filters[0].clauses[0].predicates[3].operator = "notExists"
query.conversation_filters[0].clauses[0].predicates[3].value = None
query.conversation_filters[0].clauses[0].predicates[3].range = None
query.conversation_filters[0].clauses[0].predicates[3].dimension = None
It gives this error:
When adding Dimension = None we get NoneType has not object .lower()
We also originally weren't using "clauses" so if you remove any reference to "clauses" the exact same thing applies as I said above, we were just grasping at ideas to get this to work.
In the definition for dimensions you have this:
allowed_values = ["conversationEnd", "conversationId", "conversationInitiator", "conversationStart", >"customerParticipation", "divisionId", "externalTag", "mediaStatsMinConversationMos", "originatingDirection"]
if dimension.lower() not in map(str.lower, allowed_values):
# print("Invalid value for dimension -> " + dimension)
self._dimension = "outdated_sdk_version"
So it's not handling None/Null's and it seems like this is where the issue is coming from, however admittedly I've found the documentation on consuming this via python pretty lacking so I'm expecting we're doing something silly somewhere and hoping someone can help identify what's going on here. Like I said, if we only do Dimension filters, or only do Metric filters it works perfectly fine, only when we try to do both do things go haywire.