To create an active conference calls page in your CRM you will want to run a few calls into your system to create the page:
For the data related to agents, call time, to, and from you will use the following API:
https://api.ytel.com/api/v4/conference?includeMembers=true
Example Response:
"status": true,
"count": 126,
"page": 1,
"payload": [
{
"accountSid": "00000d15-b682-476d-8661-f91db25b095f",
"confId": "ff403f07-66fd-40b1-b1ef-9ac6bed00000",
"status": "active",
"createdTime": 1709834784827,
"details": {
"called_number": "+15552323232",
"caller_number": "+15556650000",
"client_id": "000054b5-c891-4c57-95ef-e5961cc794be",
"contact_id": "0000a7e9-81ac-417b-a28b-c4bad685fa7d",
"parent_call_sid": "00003f07-66fd-40b1-b1ef-9ac6bed57ee1"
},
"members": null,
"memberData": null
}
For Barge, Whisper and Listen actions
Get the member ID for the agents leg of the call.
const mappedUsers = activeConferences.map((conference) => {
const userConference = userList
.filter((user) => {
const userClientId = user.clientId
const conferenceClientId = conference?.details?.client_id
return userClientId === conferenceClientId
})
.pop()
const isInbound = userConference.webrtcNumber === conference?.details?.called_number
const memberData = conference?.memberData && Object.entries(conference?.memberData)
const memberDataA = memberData?.pop()
const memberDataB = memberData?.pop()
const memberDataAObject = memberDataA?.pop()
const memberDataBObject = memberDataB?.pop()
const memberDataAId = memberDataA?.pop()
const memberDataBId = memberDataB?.pop()
const memberA = memberDataAId &&
memberDataAObject && {
memberId: memberDataAId,
memberData: JSON.parse(memberDataAObject),
}
const memberB = memberDataBId &&
memberDataBObject && {
memberId: memberDataBId,
memberData: JSON.parse(memberDataBObject),
}
let agentMemberId
let contactMemberId
if (memberA?.memberData?.channelName === userConference.webrtcNumber) {
agentMemberId = memberA?.memberId
contactMemberId = memberB?.memberId
} else {
agentMemberId = memberB?.memberId
contactMemberId = memberA?.memberId
}
return {
clientId: userConference.clientId,
username: `${userConference.firstName} ${userConference.lastName}`,
inbound: isInbound,
contact: null,
agentMemberId,
contactMemberId,
agentNumber: userConference.webrtcNumber,
userConference: conference,
}
})
Get a list of all webrtc users from the Gumby webrtc endpoint. These are needed to match webrtc numbers against channelName and clientIds later.
Get the details -> client_id from the active call, and match it against the list of webrtc users by clientId to find the agent for the call
Then I check to see if the details -> called_number field of the active call matches the found agent's webrtcNumber
If they match, then it is an inbound call, otherwise it is outbound
The memberData field contains the memberId's of the two participants in the call. We need them for:
barge - both
hangup - both
whisper - agent memberId
To determine the agent's memberId from the two memberData objects:
Check memberData -> channelName against the webrtc user's webrtcNumber
If they match, then that memberData object is the agent's
Otherwise, it is the other memberData object
Active Call response:
{
"accountSid": "5555960b-e9ba-4621-9e32-05559a1da555",
"confId": "5555776a-564f-4805-ada6-e770c66d7368",
"status": "active",
"createdTime": 1709849242672,
"details": {
"called_number": "+17048135555",
"caller_number": "+18445285555",
"client_id": "c91f9b77-ce9d-4207-98e4-229b76a6555",
"contact_id": "a1133d83-d0a9-4d69-80ce-355bf72e555",
"parent_call_sid": "5f32776a-564f-4805-ada6-e770c66d555"
},
"members": {
"11cd9210-dccf-11ee-ab5e-9f3c7574a173": "11cd9210-dccf-11ee-ab5e-9f3c7574a173",
"3f32776a-564f-4805-ada6-e770c66d7368": "3f32776a-564f-4805-ada6-e770c66d7368"
},
"memberData": {
"503": "{\"callSid\":\"1155510-dccf-11ee-ab5e-9f3c7574a173\",\"channelName\":\"+15558134431\",\"callerId\":\"+17048134431\",\"calledNumber\":\"+15558134431\"}",
"504": "{\"callSid\":\"3f32776a-555-4805-ada6-e770c66d7368\",\"channelName\":\"+15555280600\",\"callerId\":\"c555b77-ce9d-4207-98e4-229b76a6aa50\",\"calledNumber\":\"+15558134451\"}"
}
}
Then you can use the memberId's to manipulate the call. To perform a whisper to only the agent:
Get the agentNumber, contact memberId, and conferenceId
Make a request to the /conference/{confId}/participant endpoint with the following:
{
from: agentNumber,
to: <NEW_MEMBER_PHONE>,
confId,
mute: false,
fullMember: false,
noSpeakToList: [contactMemberId],
}
3. This will dial a call out to the NEW_MEMBER_PHONE from the agentNumber.
4. The noSpeakToList is where you put the memberIds derived earlier. In the case of a barge leave it empty, in the case of a listen put both, hangup put both, and whisper put only the agent's.