One to one calls
Note
If you are already familiar with our product, you can skip this section and jump right into development section by checking the quick start guides and tutorials:
Using the “invitation” method to call someone
As explained in section comunication setup, the way that Quobis handles the calls always implies the usage of a conference room. This also applies for basic one to one calls, where a user wants to communicate with another user. In such a case, Quobis WAC just treats this situation as a conference with “N” participants where N=2, i.e, there are only two users in the same conference room. Let’s explain the high-level process that happens when a user (Alice) wants to call another user (Bob):
Alice creates a conference room and joins it
Alice requests Bob to join its conference room
Bob joins that same conference room
One Alice and Bob are in the same conference room they are publishing and subscribing their media so they can start talking and seeing each other. In addition, both Alice and Bob can add more participants to the conference room, transfer another participant, etc. From the point of view of the end-users, the experience is the same as “receiving” a traditional phone call, but what is happening behind the scene is what we have already described: two users sharing a conference room. This approach gives a lot of flexibility in order to create complex use cases, specially those where we want to add or remove participants “on the fly”.
Note
There are two important things to highlight here to understand how the “A calls B” process works in Quobis WAC:
There isn’t a direct connection between Alice and Bob, as traditional telephony systems do. Instead, what we have is Alice and Bob talking in the same conference room and a the QSS that signals the events that the end-user will expect such as “answering”, “ringing”, “hanging-up”, etc… Alice conference room has a different ID each time a call is placed. In other words, there is no such a thing as “Alice’s own conference room” as it changes every time.
Alice does not “ring” Bob, Alice invites Bob to join a conference room. This is what we call a “QSS invite” message, please no dot confuse it with a “SIP invite” method message as the way it works is different. In other words, when a user receives a “incoming call” what he/she is receiving is an invitation to join a specific conference room.
Call flow
The process of setting a basic one to one call between Alice and Bob is summarized in the sequence diagram below. As explained above, the key point to understand here is the use of the “Invitation Request” message from the QSS. Please note that a number of other low-level messages and internal processes, such as audio and media negotiation have been removed for clarity.
1.- Alice creates a conference room and joins it
A
createRoom
message is sent to the QSS.rooms-basic service. The QSS creates the conference room.Alice joins the conference room that has just been created by starting the audio and media negotiation.
2.- Alice requests Bob to join its conference room
Alice sends a
invitation
message to the QSS.invites service, telling that she wants Bob to join the room.The QSS.invites service resolves Bob’s identity and invites Bob to join the conference room and adds Bob to the conference’s room ACL
3.- Bob joins that same conference room
Bob notifies the QSS.invites service that he accepts the invitation
QSS.invites service tells alice that Bob has accepted the invitation and that has joined the conference room
Bob joins the conference room that has just been created by starting the audio and media negotiation.
After these three steps, Alice and Bob are in communication and can talk & see each another. The following ladder diagram shows the actual message interchange.
Rejecting a one-to-one call
It can happen that Bob doesn’t want to talk to Alice so he rejects the call. In such a situation, Alice will an code error message “603” from the QSS.
data: "{
"answer":"invitation",
"requestID":"B6yXaxJfBdKlG1K3yI-fX",
"from":"5da6e65772aa8c46876107d6",
"error":603
}"
Unanswered calls
It can happen that Bob doest not answer the incoming call. In such a situation, Alice will send this message to the QSS:
data: "{
"type":"request",
"payload": {
"endpoint":"close",
"payload":{"medium":"sipcall"},
"id":"zMcZeXFM-g9wXKHgZ94ub"
}
}"
and then receive back this message:
data: "{
"cancel":"invitation",
"error":408,
"requestID":"dbUXozlylze1-b8SW1vi5",
"to":"5da6e65772aa8c46876107d6",
"from":"5f21f8239797901f01535828"
}"
Answering calls with multiple sessions
Our platform supports multi-device and multi-sessions, which means that the user can be logged in more than one device or in several browser tabs at the same time. In such a situation, the behaviour of the system when the user receives and incoming call is as follow:
If the users answers the call in any of the sessions, the other sessions will stop ringing
If the user declines the call in any of the sessions, the other sessions will keep ringing (and the caller won’t be notified)
For example, imagine that we have an user logged via web browser (with an application developed with the Javascript SDK) and is also logged in a mobile app (developed with the iOS SDK, for example). If she reject an incoming call in the mobile app, that incoming call will keep ringing on her PC. If she finally declines the incoming call in her PC, then -and only then- the caller will receive a “User rejected the call” message.
Message flow
Let’s see the actual message flow in a call between Alice and Bob
Alice creates the conference room so she sends a invitation
message to the QSS
{
"answer":"invitation",
"requestID":"BPrV0y-26KQ7hISlENIie",
"from":"+34986999888"
}
Bob receives the invitation message from the QSS with more information:
{
"requestID":"AiYoyeZXKvVa1jDtSPQuX",
"request":"invitation",
"to":"5f21f8239797901f01535828",
"from":"5da6e65772aa8c46876107d6",
"fromType":"system",
"mediatypes":{"audio":true,"video":false},
"context":{"contextInfo":{}},
"systemFrom":"5da6e65772aa8c46876107d6",
"payload":{
"uuid":"1d63845a7b93c9b7ca6b3792ee99928257ac20b18284ded51632958cb3e803df",
"sipUri":"sip:88814738571@audiomixer-sfu1:5080",
"owner":"",
"timestamp":1614031357210,
"server": {"https":"wss://collaborator.quobis.com/sfu1/socket.io","wss":"wss://collaborator.quobis.com/ws-sfu1"},
"bitrate":1024,
"record":false,
"ice":[{"urls":"stun:stun.l.google.com:19302"}],
"room":"1d63845a7b93c9b7ca6b3792ee99928257ac20b18284ded51632958cb3e803df",
"token":"3af66884b2a752f4e73bfa8bd10cbe36",
"participants":["5da6e65772aa8c46876107d6","5f21f8239797901f01535828"]
}
}
Bob hangs up the call, so he sends a leaveRoom
message to the QSS:
{
"request":"leaveRoom",
"requestID":"1neElgQ3-_hRJ4MS5qcdc",
"payload":{"room":"8ffbf6016d96ed82019817751afc4b15dd45d36fab46f7d30d40087eb5f332de"}
}
Aftewards, Bob will receive the following message, as he’s no longer in the ACL:
{
"cancel":"leaveRoom",
"error":403,
"message":"user not included into ACL"
}
Call restrictions
The Quobis communication platform supports blocking the incoming calls using receiveCalls permission assignment.
Permission assignment
You can change the receiveCalls permission in order to control the incoming calls, which by default is enable, via request through REST API. A user with this permission disable wont receive incoming calls but still can call other users
User
You can disable the receiveCalls to specific users.
To do so, launch the POST request Add User Permission
, that you can find in the WAC Permissions collection, followed by the user id you want to modify. In the Body you must modify the values of the parameters according to your needs.
Example:
1 curl --location --request POST 'https://web.sippo/sapi/permissions/user/{id}' \
2 --header 'Authorization: Bearer {bearerToken}' \
3 --header 'Content-Type: application/json' \
4 --data-raw '{
5 "receiveCalls": {
6 "enabled": false
7 }
8 }'
Once sent, and if everything has worked correctly, you should receive as a response: 201 Created.
Domain
You can disable receiveCalls at a domain level.
To do so use the POST request Add Domain Permission
, that you can find in the WAC Permissions collection, followed by the domain id you want to modify. In the Body you must modify the values of the parameters according to your needs.
Example:
1 curl --location --request POST 'https://web.sippo/sapi/permissions/domain/{id}' \
2 --header 'Authorization: Bearer {bearerToken}' \
3 --header 'Content-Type: application/json' \
4 --data-raw '{
5 "receiveCalls": {
6 "enabled": false
7 }
8 }'
Once sent, and if everything has worked correctly, you should receive as a response: 201 Created
.