RingCentral Telephony Session Events Notifications

Phong Vu
RingCentral Developers
13 min readJul 28, 2020

What is a telephony session?

A telephone call has its life cycle that comprises of a sequence of stages. From a user perspective, a typical telephone call life cycle has three main stages, i.e. “RINGING” — “CONNECTED” — “DISCONNECTED”. It begins when a caller dials a number that causes a phone of a callee ringing — the call is ringing. The callee accepts the call and starts talking with the caller — the call is connected. Then at some point in time, one of them hangs up to end the call — the call is disconnected. From a technical perspective, the sequence of stages could be more complicated with some interim stages that a user might not be aware of. Depending on how the call is being initiated and routed, the sequence includes some stages before the callee phone rings, during the call is being established and even after the call is disconnected. The entire telephone call life cycle is called a telephony session with each stage is captured and notified via a telephony session event.

RingCentral platform lets you catch every stage of a telephone session via the platform push notification service.

Telephony session event notifications

RingCentral platform supports PubNub notification and Webhook notification frameworks. You can register for receiving notifications of many types of events, and for the telephony session event type, use can choose one of the following event filters:

  • Account level: “/restapi/v1.0/account/{accountId}/telephony/sessions”
  • Extension level: “/restapi/v1.0/account/{accountId}/extension/{extensionId}/telephony/sessions”

Using the account level filter, you will be able to receive telephony session events of all the extensions under that account. And using the extension level, you will be able to receive telephony session events of a particular extension specified by the extension id. If you want to receive telephony session events of more than one extension, but not all the extensions under the account, you can specify an event filter array as show below:

var eventFilters = [
"/restapi/v1.0/account/~/extension/11111111/telephony/sessions",
"/restapi/v1.0/account/~/extension/22222222/telephony/sessions",
"/restapi/v1.0/account/~/extension/33333333/telephony/sessions"
]

It’s worth to mention that you don’t need to be an admin user to subscribe for the account level notification, or for multiple extensions notification. Also, you will not be allowed to use the call information to control active calls of other extensions even if you are an admin user. I will explain more about call control use cases later in this blog.

You can decide which type of event filter should be used based on the purpose of your application. Perhaps, the two popular application types are call control and call monitor applications. For call control applications, you should use the single extension level filter. And for call monitor applications, you can use either the account level or multiple extensions filter. The benefit of using multiple extensions filter is that you can easily exclude those users you don’t want to monitor, or you are not allowed to monitor, e.g. the company executives.

Note: There is no limitation on the number of extension filters in the event filter array!

Telephony session event payload

Telephony session notifications comprise of a series of events. Each event comes with a sequence number and a timestamp that can be used to identify the order of the events. However, there is no guarantee that they will arrive in the order due to some network situation. Some sequence could also be omitted depend on the type of the call.

Each notification event contains some generic data such as the event identifier “uuid”, the “timestamp”, the “subscriptionId” etc. and the event payload enclosed in the event’s body data object.

The payload of a telephony session event notification provides useful data about a call at each call stage. You can use the data for many different purposes. In this blog, I will explain and highlight only the essential data needed in some common use cases. For full data description, please refer to the API reference.

A Typical Telephony Session “Ringing” Event

Call session unique identifiers and how to use them

A telephony session is identified by a unique session identifier and a unique telephony session identifier. All events of the same telephony session will share the same session and telephony session ids. It’s worth to note that the session id is a legacy telephony session identifier, and the telephony session id is a new telephony session identifier.

A typical session id and telephony session id in an event payload

You can use either one to identify a unique call session, however, the decision can be based on the purpose of an application and here are the tips:

  1. If you build a call control application, you will need the telephony session id because most of the call control APIs requires the “telephonySessionId” to identify a call.
  2. If you build a call monitor application, you should use the session id because you may want to collect more call metadata from the RingCentral call log database, e.g. to get a call recording URI. In this case, you can use the “sessionId” to fetch the call recording from the call log database more effectively.

In addition, there is a party id which is a unique identifier of each party in a call. A typical phone call has two parties, a caller and a callee. And a conference call may have several parties. The unique id of each party is the telephony session id with a “p-” prefix instead of “s-” and a suffix of a hyphen and a number.

A typical party id in a call session event

The party id is vital important in call control applications. For example, you can build a call routing application which forwards incoming international calls to an agent who can speak that foreign language. In this use case scenario, you use the telephony session event notification to receive incoming calls notification, then you can parse the “from” number from the event payload, identify the country code and if it is an international number, you can forward that call to a designated number based on your own rules. To forward an incoming call, you get the telephony session id and the party id of the callee from the event payload then call the call forward API with those parameters.

Important: As I mentioned earlier about call control, in order to forward an incoming call to another destination, your app must be authenticated (logged in) by the same extension which supposes to receive the call. For example, if you receive notification of an incoming call to the extension 105 and you want to forward the call to extension 110 or to a PSTN number, you have to login the app with the extension 105 login credentials.

Call statuses and how to use them

The call status tells you the stage of a call during the call session. Each status change event comes with the time when the status changed. The time is the date and time in ISO 8601 format and based on Coordinated Universal Time (UTC) time.

A typical call session event’s payload with event time and call status

The call status is an important piece of information for most applications you’ll build with the telephony session event notification. For example, when you build a call control to forward incoming calls (an example discussed earlier), you have to make sure that the call status is either in “Setup” or “Proceeding” at the moment you forward the call. If you try to forward the call when it is already connected, you will receive an error response. Another example is when you build a call monitor application, you can use the call “Setup” and “Disconnected” to determine the entire call length and to mark the call termination.

Call statuses with short description

If you build a real-time call monitoring application which displays active calls information of a group of users (let’s call them agents), you can use the call statuses and the event timestamps (time from the “eventTime”) to identify the call stage and to calculate the duration of each stage such as agent’s respond time, agent’s actual talk time, agent’s hold time etcetera. E.g. to calculate the agent’s respond time, which is from the time his phone starts ringing until the time he answers the call, you can take the timestamp of the call ringing event, subtract from the timestamp of the event when the call is answered.

You may receive multiple events with the same call status for a single telephony session. For example, you will receive two “Setup” events for an inbound call, one with the direction as “Outbound” and the other with the direction as “Inbound”.

Setup events of an Inbound call

As you can see from the example events above, the first event (sequence 2) and the second event (sequence 3) has the same “Setup” status, one for each call party.

Proceeding (Ringing) events of an Outbound call

Similarly, for an outbound call, you will receive two “Proceeding” events, one with the direction as “Inbound” and the other with the direction as “Outbound”.

In most use cases, you’ll probably want to capture the status and other data of an agent, not a customer (the foreign party). In that case, you can rely on an event which contains the extension id within the “parties” data object, and simply ignore the other event with the same status. In the example “Proceeding” events above, you should capture the data from the sequence 4 event and ignore the sequence 3 event.

Detect if extensionId field exists

When a call is put on hold by the agent, you will receive an event with the “Hold” status. And when the agent resumes the on-hold call, you will receive an event with the “Answered” status. Thus, if you want to calculate the call on-hold duration, you will need to keep track of the previous status of the call to mark the end of the holding time.

Hold and Un-hold events of a call

You will be notified when an inbound call is forwarded to the agent’s voice mailbox. The status of that event is “Voicemail”. However, there is no guarantee if a caller eventually leaves a voicemail message or not. If you are interested of a voicemail notification, use the Voicemail Event Notification filter instead.

A call is forwarded to the agent’s voice mailbox

There are two ways to detect missed calls using telephony session event notification:

  1. An inbound call with the events changing from “Proceeding” to “Disconnected” is considered as a missed call.
A call status is changed from “Proceeding” to “Disconnected” can indicate a missed call

2. The agent’s “Disconnected” event (event with extension id within the “parties” data object) has the “missedCall” flag set.

The “missedCall” flag is true

When an agent parks a call, you will receive several events about the incident. The sequence is fairly complicated and hard to handle, so let’s have a look at each of them separately in the following example.

Here is a typical latest event when an inbound call is answered by an agent.

A typical call “Answered” event

When the call is parked, the system will create a new party for the existing call with the same session id and telephony session id. The party id is the telephony session id with a new suffix “-3” which is the identifier of this new call party. The status of this event is “Parked” tells you that this is a parked call. As this parked call does not belong to any extension, you will not see the extension id within the “parties” data object.

Event notification of a call is about to be parked

The next event indicates that the active call is parked. It has the same status as “Answered” and looks almost identical to the sequence 6 event except it has the “reason” field instead of the “mobilePickupData” field within the “status” data object.

Event notification of an active call is parked

You will receive another event about the newly created party. This time the event contains more meaningful information about the new party, i.e. the park id which tells you where to pick up the parked call later.

Event notification of an active call is parked

The last event you will receive is about the agent call terminated after parking the call. The event contains the reason why the call was disconnected.

Event notification of an agent session terminated due to call parked

Let’s wrap up these events and see how to deal with multiple events with the same event status.

Firstly, let’s deal with the multiple “Answered” events. Assumed that you already picked the timestamp in the sequence 6 event (illustrated in the example event above) to mark when the agent answered the call for calculating the call ringing duration, and will use it to calculate the agent talk duration when the call ends. You can ignore the sequence 8 event by either checking the “reason” in the “status” data object or checking the previous status of the event for the agent. I’d prefer to use the previous status variable to check this condition than using the “reason”. This is because with the previous status, I can deal with the situation where call was put on-hold and un-hold in the same code.

Example code to deal with multiple “Answered” events

Secondly, let’s deal with multiple “Parked” events. As you can see from sequence 7 event, the “status” data object does not have the park data, nor the “park” object contains the park id. It’s up to you to check one of the field’s values to capture the park id and to ignore the other event without the park data or id.

Detect when a call is parked

How about when the parked call is picked up by an agent (this means that an agent dials to a parked id with an asterisk prefix)? When a parked call is picked up, the system creates a new call session with all new call identifiers, even if the parked call is picked up by the same agent who parked that call. Let’s examine the example events of the parked call above when it is picked up.

Events notifications of a parked call is being picked up

As you can see the previous call session id (441806949016) is different from the new call session id (441807094016). And the telephony session ids are also different. The new telephony session events from a parked call is slightly different from those events of a normal call session with some extra data and the status changes almost instantly from “Setup” to “Proceeding” and then to “Answered”. You can capture the timestamp of each status change event the same way as you would do for a normal call, i.e. first detect if the extension id exists, then capture the event timestamp even if the time difference between these events is just a fraction of a second.

If you need to identify a call is a normal call or a parked call pickup, you can detect if the “feature” field exists and the value of the feature’s name “ParkPickup”. You will also receive two extra events with a new status as “Gone”; One with the new session and telephony session id, and the other with the original session and telephony session id. I don’t have a use case which would need the information from these extra events so I can simply ignore those events with status as “Gone”.

You can detect the parked call termination the same way as you would do for a normal call as discussed earlier. As you can see from the example events below, there are two extra “Disconnected” events with the original session id and telephony session id. Since both of the events do not contain the extension id, and probably you already finalize the original call when the agent parked the call, you can simply ignore these extra events.

Events notifications of a parked call termination

Another interesting metric about a call you might want to detect is to find out who hangs up the call; Is it the agent or is it the customer who hangs up first. This is more interesting if the call is terminated during the on-hold stage. To determine who hangs up first, you identify the agent’s and the customer’s “Disconnected” event based on the existent of the “extensionId” field as discussed earlier, then check whose event happens first by comparing the events’ sequence order number.

Disconnected events from each call party - Customer hanged up

Detect Call directions

The call direction is either inbound or outbound call. The direction can be used together with the “to” phone number and the “from” phone number to identify an agent’s number or a customer’s number.

Detect the direction of a call

As mentioned earlier, a call session’s events include both “Inbound” and “Outbound” events. To identify the correct call direction, you should detect the direction of an event which contains the extension id within the “parties” data object.

Stay tuned for my next blogs where I will discuss in detail about how to build a call control app and how to build a real-time call report app.

To learn even more about other features we have make sure to visit our developer site and if you’re ever stuck make sure to go to our developer forum.

Want to stay up to date and in the know about new APIs and features? Join our Game Changer Program and earn great rewards for building your skills and learning more about RingCentral!

--

--