Since the beginning of our integration with Purecloud API that we made some assumptions that recently started to reveal some problems related to API changes that we dont control.
We would like you to clarify the following assumptions/questions.
Assumptions:
There will always be only one participant with "purpose:customer" in a conversation;
Field "endTime" is only filled when the correspondent participant state is disconnected or terminated;
Field "connectedTime" is only filled when the correspondent participant state changes to "connected";
“Confined” field only applies to consult transfers. We are using this field to implemente the “On-Hold” toggle. For other conversations we use “Held” instead;
Within a consersation, we consider the last participant of “purpose:agent” (for which the userId matches the agent) as the most up-to-date;
If “consultParticipantId” is filled we are in a consult transfer;
For every participant of “purpose:agent” the field “consultInitiator” is always filled, no matter the state.
If “wrapUp” is not filled, it’s because the conversation was never “Wrapped up” (equivalent of pressing “Done” on PureCLoud web cient)
“dialerPreview” is filled only if we are in the scope of an outbound campaign;
Further questions:
How should we interpret “wrapupRequired” and “wrapupPrompt” and why do they exist for both “agent” and “customer”;
What is the difference between participant’s “connectedTime” and call’s “disconnectedTime”;
What is the difference between participant’s “endTime” and call’s “connectedTime”;
What is the most resilient way to get a customer("purpose : customer") caller id: “address”, “ani” or “dnis”?
Is there any native property in the conversation that indicates that it has been transferred?
I'll do my best to answer these both for their current state today, and also what we hope to do in the future, noting specifically which changes will not be made in the current version.
Assumptions:
One participant purpose:customer - This is true for the majority of ACD interactions but there are also cases where there may be a participant with purpose:external instead. It's best not to make too many assumptions about the conversation based on which of these two values is used. We are increasingly using "external" but have some legacy where either value can be present and don't want to change this for fear of breaking apps that may have made assumptions about it. If the call is non-ACD there may also only be purpose:user participants present.
endTime is only present when a participant state is disconnected - This should be true, though it's generally still safer to base your rules on the actual states of the interactions and not use the presence or absence of a timestamp as a pseudo-boolean. We may be expanding the model in the future to capture something like "participant state" to simplify the logic needed to understand when an interaction is still active. Right now this is still based on whether all communications are disconnected/terminated and whether wrapup is both required and set, or not required.
connected time is only present when communications are connected - Similar to endTime, this should be true but the safest way to know if a connected communication is present is to look for a connected communication.
Confined vs. Held - In practice this will likely only show up in consult transfers, but these are conceptually slightly different. Confining a user allows you to isolate their audio from the rest of the participants. This is different from placing your own call on hold, isolating yourself from the rest of the participants.
Participant order - I'm not sure how to answer this one. What do you mean by 'the most up-to-date'? Participants are generally sorted by the order that they join a conversation, though no JSON array order should be taken as perfect. Communications are sorted in the reverse order, keeping the most recently connected at the start/top of the array. However, multiple communications/participants may be changing at any time. Consult transfers that do not complete (are cancelled) are a good example of bringing a new participant into a conversation but not necessarily having them be the 'last' to change.
6 - ConsultParticipantId - This is correct. We are currently working on expanding this model to make it more clear but for now this is a safe assumption.
ConsultInitiator is always filled - I don't think I can guarantee this one. Unfortunately this field has fairly weak semantics, which is why we're hoping to make some model changes in the future to clarify how this works. Why would you need to assume this field is always present?
Wrapup behavior - If the wrapup field is not present, wrapup has not been applied. If the "wrapupRequired" field is present and wrapup is not, this conversation will still be tracked as active for that agent. The exact UI behavior varies by media type so I'm not comfortable equating this directly to the "done" button specifically, but that field is what captures the wrapup that has been set.
9 - dialerPreview filled for outbound campaigns - Yes this field is only used in that context. However, it is not always used in that context. See the documentation for dialer preview campaigns.
Further Questions:
I partially explained what wrapupRequired means in question 8 above. wrapupPrompt captures the wrapup configuration specified by the queue for this particular interaction. wrapupRequired will be true if an agent successfully connected to the given interaction and is expected to apply wrapup to be finished and able to take the next interaction. It will be false if the agent alerted but failed to answer the interaction. As for existing on both participants, I would have to do some digging but I suspect this is probably just legacy. To be backwards compatible we have to make purely additive changes between major API versions. There are a hand full of things that aren't ideal with the current object model that we have plans to change, but cannot do so at this time. Wrapup is only relevant on agent participants.
2/3. I'm not sure what you are asking here. The mixture of connected vs disconnected in your question makes most of those items incomparable. At a high-level, participants can have more than one communication and capture that particular user/entity's interaction on a conversation. The communications correspond directly to the channel (eg voice session) and their timestamps are derived from the underlying media layer. The participant times are derived at the abstraction layer that is linking those sessions together into a "conversation".
ANI/DNIS vs Address is a common challenge with our current APIs. There is a feature which was just released which adds an additional ANI/DNIS field to conversations to support analytics view filtering on these fields. We have not exposed them on all APIs and will likely wait until we have more history with the new fields. The "address" fields are very specific to that voice session so you may be seeing things like the address of specific stations. This is relevant for the telephony platform but is not the high-level view that API consumers often want. I'd recommend reviewing the new ANI/DNIS work on the analytics APIs to see if this fits what you are needing.
Not today, though this is in progress right now. In an attempt to clean up some of the consult transfer fields/behavior and also capture when repeated disconnect attempts have failed for a given conversation, we are likely going to introduce a top-level array of commands for a conversation. This will allow you to track ongoing transfers and the status of any major command issued against that conversation to provide better 202 response behavior by giving a clearer object to track the status of that command. I can't give any concrete details on this work or timelines yet but it is an ongoing effort to try to improve a number of facets of conversation API usage.
Regarding your explanation it appears to be a bug (as reported in other post) related to that, as we have situations where "endTime" is filled in "connected" state. As you suggested we started to look to state field also when we evaluate "endTime" in order to know if its time to interpret it.
(consultInitiator) We use this field in order to know which agent is the consultant, because we display different options regarding the agent we are dealing with. Once you stop showing it when the state is disconnected/terminated we stop knowing which one is the initiator. Assuming that we need to manage this situation in another way. (we wil try to manage that).
Regarding the questions 2 and 3, there is a mistake in the refered states (sorry for that), however I understood your explanation and it was enough to clarify our issues.
I hope that we continue to clarify some other issues that may come.