Legacy Dev Forum Posts

 View Only

Sign Up

Associating an external contact with a conversation

  • 1.  Associating an external contact with a conversation

    Posted 06-05-2025 18:16

    Facundo_Nowicky | 2020-01-13 23:20:31 UTC | #1

    I'm attempting to automatically assign ("verify") an external contact, to an incoming chat interaction before the chat is actually assigned to the agent; to automate the process of "verifying" the contact associated with it.

    TL;DR here, Detailed Explanation below

    To do this, after looking for an existing contact or creating it, using either GET - /api/v2/externalcontacts/contacts -Search for external contacts or POST - /api/v2/externalcontacts/contacts - Create an external contact

    and obtaining the Communication ID from GET - /api/v2/conversations/chats/{conversationId} - Get chat conversation

    I'm invoking

    PUT - /api/v2/externalcontacts/conversations/{conversationId} - Associate an external contact with a conversation

    { "externalContactId": "", <- I have this because I searched/created the contact "conversationId": "", <-This is known during the flow, it's Chat.ConversationId "communicationId": "", <-I Obtained this through another API Action. "mediaType": "" <-It's CHAT }

    However, when the Webchat arrives to the agent, the External contact is not verified/assigned. It still shows the normal "search" window with the External Contacts that match the name of the incoming "firstName/lastName" data.

    I opened a ticket in support, but they kicked me back here


    Detailed Explanation:

    We receive incoming Webchats with several attached UserData: firstName, lastName, tipoCliente (which is a method of customer segmentation) and DNI which refers to the "Documento Nacional de Identidad" (National Identity Document) number which is unique to each person in the country.

    I'm using custom Integrated Actions to search and manipulate External Contacts because the integrated search in Architect does not search by Title (returning no results when searching by it).

    In the Incoming Flow I use this logic:

    Integrated Action; ExisteContactoExtPorDNI - This uses /api/v2/externalcontacts/contacts?pageSize=1&amp;pageNumber=1&amp;q=${input.DNI} to search External Contacts, I'm searching for the DNI stored in the "Title" field, because we don't have a custom field. This outputs the total amount of External contacts that match this DNI number (This is needed because the possibility exists for a smaller number to bring more than one contact, Example, if you have "title=12345678" and "title=123456" a search for 123456 will yield 2 results)

    output:

    { "translationMap": { "totalres": "$.total" }, "translationMapDefaults": {}, "successTemplate": "{\r\n \t\"Total\": ${totalres}\r\n }" }

    If I get 0 matching contacts, I create a new External Contact using the firstName, lastName and DNI (stored in the Title), with Integrated Action: "CrearContactoExternoConDNI" - Which uses POST - /api/v2/externalcontacts/contacts - Create an external contact: Input

    { "type": "object", "properties": { "Nombre": { "type": "string" }, "Apellido": { "type": "string" }, "DNI": { "type": "string" } }, "additionalProperties": true }

    This Outputs the Id of the created External Contact:

    { "translationMap": { "id": "$.id" }, "translationMapDefaults": {}, "successTemplate": "{\r\n \t\"Id\": ${id}\r\n }" }

    IF I get 1 or more contacts, I check the contacts with "ObtenerContactoPorCargo" which calls: /api/v2/externalcontacts/contacts?pageSize=1&amp;pageNumber=${input.Pagina}&amp;q=${input.DNI} and from the response I get:

    { "translationMap": { "name": "$.entities[0].firstName", "documento": "$.entities[0].title", "id": "$.entities[0].id", "apellido": "entities[0].lastName" }, "translationMapDefaults": {}, "successTemplate": "{\r\n \t\"Nombre\": ${name},\r\n \t\"DNIContacto\": ${documento},\r\n \t\"IDContacto\": ${id},\r\n \t\"Apellido\": ${apellido}\r\n }" }

    I use the response to double check the incoming DNI is exactly equal to the obtained DNI (stored in the Title).

    I iterate through all the External Contacts found using "input.Pagina" to get the different results, until I either find a perfectly matching one or run out of results.

    If I can't find a matching DNI I simply create a contact like previously explained. If I find a matching DNI, I now have that ExternalContact Id.

    THIS IS THE MOST IMPORTANT SECTION

    At this point I call "ObtenerChatCommunicationId" : Which uses /api/v2/conversations/chats/${input.ConversationID} (Using the available variable Chat.ConversationId) with this output:

    { "translationMap": { "commid": "$.participants[1].id" }, "translationMapDefaults": {}, "successTemplate": "{\r\n \t\"CommunicationID\": ${commid}\r\n }" }

    (In several tests, a Chat in a Flow has the customer participant data in the first block within participants, and in the second block the data of the communication itself)

    Now I have both the CommunicationID, the ExternalContactId, the ConversationId and MediaType are already known.

    So I call AsignarContactoAConversacion: Input Contract:

    { "type": "object", "properties": { "IdContactoExt": { "type": "string" }, "IdConversacion": { "type": "string" }, "IdCommunication": { "type": "string" }, "MediaType": { "type": "string" } }, "additionalProperties": true }

    Request Body Template:

    { "externalContactId": "${input.IdContactoExt}", "conversationId": "${input.IdConversacion}", "communicationId": "${input.IdCommunication}", "mediaType": "${input.MediaType}" }

    In live Tests this answers with a 200 OK Response, however, the external contact is not verified/assigned to the Chat. This can be verified by the fact that, the agent still gets the option to create a new contact or verify one, according to first/lastName searches .

    I tested this both using the "Test" tab in the Actions, retrieving manually all data, with the chat already opened with an Agent, and with the Chat waiting in queue. A flow using this was also attempted.

    It's possible that my method of obtaining the CommunicationId is flawed. But I'm certain that the location of the id in the response from GET /api/v2/conversations/chats/${input.ConversationID} , is accurate.

    Out of a live chat interaction. this is the list of participants I see:

    { "id": "4fdb509a-b98a-4c87-b5e7-09df3a54027b", "participants": [ { "id": "82f4a8a1-9c03-4c8f-8cf0-3d878c5cf27f", <- This is the customer participant "name": "Cliente Apellido", "startTime": "2020-01-13T23:05:05.942Z", "connectedTime": "2020-01-13T23:05:05.952Z", "purpose": "customer", "state": "connected", "held": false, "wrapupRequired": false, "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "attributes": { "context.Nombre": "Cliente", "context.firstName": "Cliente", "context.genesysOS": "Windows", "context.tipoCliente": "FIRST", "context.genesysbrowser": "Chrome", "context.lastName": "Apellido", "context.genesysreferrer": "http://*com/final.html", "context.genesysurl": "http://**.com/final.html?i=1", "context.genesyssource": "web", "context.genesyspageTitle": "PureCloud WebChat", "context.DNI": "12582152", "context.genesys.legacyRoutingTargetQueueAddress": "" }, "provider": "PureCloud Webchat v2" }, { "id": "4abf5d2a-5366-4114-b18a-b1187e57c11c", <- THIS IS THE COMMUNICATION, RIGHT? "startTime": "2020-01-13T23:05:05.943Z", "connectedTime": "2020-01-13T23:05:05.980Z", "endTime": "2020-01-13T23:05:14.964Z", "purpose": "workflow", "state": "disconnected", "disconnectType": "transfer", "held": false, "wrapupRequired": false, "attributes": { "context.Flow Name": "ChatPatagoniaSOW" }, "provider": "PureCloud Webchat v2" }, { "id": "27d4b561-4b2e-4e7c-9c5f-edf351f32f8e", <- This is the Queue * "name": "Patagonia-Chat",** "startTime": "2020-01-13T23:05:14.966Z", "connectedTime": "2020-01-13T23:05:15.008Z", "endTime": "2020-01-13T23:05:19.919Z", "purpose": "acd", "state": "disconnected", "disconnectType": "transfer", "held": false, "wrapupRequired": false, "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "attributes": {}, "provider": "PureCloud Webchat v2", "conversationRoutingData": { "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "priority": 8, "skills": [], "scoredAgents": [] } }, { "id": "88131421-a501-4abe-82e8-e45d83b1345e", <- And this is the final conversation with the Agent. "startTime": "2020-01-13T23:05:15.062Z", "connectedTime": "2020-01-13T23:05:19.920Z", "purpose": "agent", "state": "connected", "held": false, "wrapupRequired": true, "wrapupPrompt": "timeout", "user": { "id": "94f673da-d957-486f-bfa4-31ff367a0482", "selfUri": "/api/v2/users/94f673da-d957-486f-bfa4-31ff367a0482" }, "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "attributes": {}, "script": { "id": "c9bb0059-1b7d-4614-b573-fdbccf881076", "selfUri": "/api/v2/scripts/c9bb0059-1b7d-4614-b573-fdbccf881076" }, "wrapupTimeoutMs": 120000, "alertingTimeoutMs": 30000, "provider": "PureCloud Webchat v2", "conversationRoutingData": { "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "priority": 8, "skills": [], "scoredAgents": [] } } ], "otherMediaUris": [], "selfUri": "/api/v2/conversations/chats/4fdb509a-b98a-4c87-b5e7-09df3a54027b" }

    • Am I getting the correct Communication ID?
    • Is it wrong to attempt to assing the External contact to the interaction in the Flow?

    Regards.


    tim.smith | 2020-01-15 18:13:19 UTC | #2

    What's the case number from Care?

    Facundo_Nowicky, post:1, topic:6864
    { "translationMap": { "commid": "$.participants[1].id" },

    This is probably what's incorrect, for two reasons:

    1. The second participant (array position [1]) in the chat is probably the ACD queue, not the customer. The first participant is usually the customer. Instead of accessing by position, it would be better to choose the array member based on the purpose property being customer.
    2. The communication ID is not the same as the participant ID. The communication ID refers to the media of the participant and would be found at participants[0].chats[0].id.

    If you need help figuring out the JSON path for those items, post back here with your data action's configuration so we can take a look.


    Facundo_Nowicky | 2020-01-15 22:41:52 UTC | #3

    First of all, Thank you Tim for your help.

    tim.smith, post:2, topic:6864
    The communication ID is not the same as the participant ID. The communication ID refers to the media of the participant and would be found at participants[0].chats[0].id .

    Correct, the first "participant" is the customer, I mention that during the explanation of ObtenerChatCommunicationId, that's the action I'm using for the ID. It uses */api/v2/conversations/chats/${input.ConversationID}* (Using the available variable Chat.ConversationId ). Which I assumed was the correct function. I posted it's translation map, which you quouted, and an example of the plain output (It's the large code section near the end). As you can see, there is no "chat" array in the participant information. I created a new action and tested a live chat again with this output:

    { "id": "688a7340-917f-4d42-bb53-1f6e9f228032", "participants": [ { "id": "c4725e5e-2391-44e8-825c-d56434c81016", "name": "Cliente Apellido", "startTime": "2020-01-15T21:35:46.534Z", "connectedTime": "2020-01-15T21:35:46.542Z", "purpose": "customer", "state": "connected", "held": false, "wrapupRequired": false, "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "attributes": { "context.Nombre": "Cliente", "context.firstName": "Cliente", "context.genesysOS": "Windows", "context.tipoCliente": "FIRST", "context.genesysbrowser": "Chrome", "context.lastName": "Apellido", "context.genesysreferrer": "", "context.genesysurl": "http://**/final.html", "context.genesyssource": "web", "context.genesyspageTitle": "PureCloud WebChat", "context.DNI": "35399588", "context.genesys.legacyRoutingTargetQueueAddress": "" }, "provider": "PureCloud Webchat v2" }, { "id": "90c3a1e0-7c74-4ad4-9249-7d074728050f", "startTime": "2020-01-15T21:35:46.535Z", "connectedTime": "2020-01-15T21:35:46.570Z", "endTime": "2020-01-15T21:35:50.768Z", "purpose": "workflow", "state": "disconnected", "disconnectType": "transfer", "held": false, "wrapupRequired": false, "attributes": { "context.Flow Name": "ChatPatagoniaSOW" }, "provider": "PureCloud Webchat v2" }, { "id": "ca49b9d3-ee2e-4b67-8d51-1286f14c3a56", "name": "Patagonia-Chat", "startTime": "2020-01-15T21:35:50.770Z", "connectedTime": "2020-01-15T21:35:50.802Z", "purpose": "acd", "state": "connected", "held": false, "wrapupRequired": false, "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "attributes": {}, "provider": "PureCloud Webchat v2", "conversationRoutingData": { "queue": { "id": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "selfUri": "/api/v2/routing/queues/602080a3-b0d9-4a2b-8ded-2177de8a2c11" }, "priority": 8, "skills": [], "scoredAgents": [] } } ], "otherMediaUris": [], "selfUri": "/api/v2/conversations/chats/688a7340-917f-4d42-bb53-1f6e9f228032" }

    However, upon considering your recomendation, I'm thinking that I should be using. /api/v2/analytics/conversations/{conversationId}/details, in the previous example, the output is:

    { "conversationId": "688a7340-917f-4d42-bb53-1f6e9f228032", "conversationStart": "2020-01-15T21:35:46.534Z", "originatingDirection": "inbound", "participants": [ { "participantId": "c4725e5e-2391-44e8-825c-d56434c81016", "participantName": "Cliente Apellido", "purpose": "external", "sessions": [ { "mediaType": "chat", "sessionId": "fb389a4f-18d5-48d5-bc02-2ad0e6d15105", "direction": "inbound", "segments": [ { "segmentStart": "2020-01-15T21:35:46.534Z", "segmentType": "interact", "conference": false } ], "metrics": [ { "name": "nConnected", "value": 1, "emitDate": "2020-01-15T21:35:46.534Z" } ], "provider": "PureCloud Webchat v2" } ] }, { "participantId": "90c3a1e0-7c74-4ad4-9249-7d074728050f", "purpose": "workflow", "sessions": [ { "mediaType": "chat", "sessionId": "6b08b1ff-dbb2-4db2-afb5-10832ae8ec58", "direction": "inbound", "peerId": "fb389a4f-18d5-48d5-bc02-2ad0e6d15105", "segments": [ { "segmentStart": "2020-01-15T21:35:46.535Z", "segmentEnd": "2020-01-15T21:35:50.768Z", "disconnectType": "transfer", "segmentType": "interact", "conference": false } ], "provider": "PureCloud Webchat v2", "remote": "Cliente Apellido" } ] }, { "participantId": "ca49b9d3-ee2e-4b67-8d51-1286f14c3a56", "participantName": "Patagonia-Chat", "purpose": "acd", "sessions": [ { "mediaType": "chat", "sessionId": "0d98dbc7-36b5-4d89-a704-92df00881ee7", "direction": "inbound", "peerId": "fb389a4f-18d5-48d5-bc02-2ad0e6d15105", "segments": [ { "segmentStart": "2020-01-15T21:35:50.770Z", "queueId": "602080a3-b0d9-4a2b-8ded-2177de8a2c11", "segmentType": "interact", "conference": false } ], "metrics": [ { "name": "nOffered", "value": 1, "emitDate": "2020-01-15T21:35:50.770Z" } ], "provider": "PureCloud Webchat v2", "remote": "Cliente Apellido" } ] } ], "divisionIds": [ "94a504a0-57c9-4de9-b743-eac83a744249" ] }

    But, this one also lacks a "chat" array. The closest thing I can see here, would be:

    "sessionId": "fb389a4f-18d5-48d5-bc02-2ad0e6d15105", In participants[0].sessions[0].sessionID ; Is that the one I should be using?

    Kind Regards,


    tim.smith | 2020-01-15 22:36:20 UTC | #4

    Facundo_Nowicky, post:3, topic:6864
    In participants[0].sessions[0].sessionID ; Is that the one I should be using?

    TL;DR - yes

    I missed that you were using analytics. I was referencing the response object from GET /api/v2/conversations/{conversationId} when writing my response. Analytics has pretty much the same data, but it's in a little different format than the conversation APIs. The conversation object has properties for each media type and refers to the media as a communication. In Analytics, it groups all media together into the sessions property and refers to that same data as a session. You can use either the conversation or analytics APIs for this as long as you're getting the data you need.


    Facundo_Nowicky | 2020-01-15 22:38:11 UTC | #5

    tim.smith, post:4, topic:6864
    You can use either the conversation or analytics APIs for this as long as you're getting the data you need.

    Brilliant!. Thank you, trying to find this Id without supporting documentation was a pain... I was using the API reference but it's never mentioned as Communication ID, do you have a source you used as a guide?


    tim.smith | 2020-01-15 22:49:40 UTC | #6

    Facundo_Nowicky, post:5, topic:6864
    do you have a source you used as a guide?

    The explicit differences between conversation and analytics models aren't documented, to my knowledge. The session/communication discrepancy is one of the very few that is named differently and is not just a marginally different organization of the data model.


    system | 2020-02-15 22:49:41 UTC | #7

    This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.


    This post was migrated from the old Developer Forum.

    ref: 6864