Call Screening and Call Whispering

When establishing a voice call between two parties, it can be helpful to provide the call recipient with additional information about the caller before establishing the call, thereby allowing the call recipient to make a decision about whether to answer the call or not which could not be determined simply on the basis of the recipient's own caller ID. Moreover, there are cases (such as when using number masking) where this decision would not be possible for a call recipient to make, and so the only way to provide information about a caller may require audible information to be first provided to the call recipient.

Messagebird's Voice API provides a solution for advanced call screening options using special options available to the transfer step, which allows one to use "Call Whispering" to send privately audio to the recipient of the transfer while the caller hears a ringback tone (RBT).

A Call Screening scenario:

Let's start off with a quick example to help frame the problem and our eventual solution.

The Problem:

Pablo runs an e-commerce website targeted at hobbyists and DYI'ers, thus privacy is a major concern for the platform's users. Both the seller and the buyer need to maintain their anonymity throughout the interaction. Pablo already uses Messagebird, and is aware of how to use Number Masking so he's been able to ensure the privacy of his users already. Now when a seller receives a call from a buyer, they only see the number Pablo has assigned to their account, and not the buyer's information. So far, things are going great, and his users are really happy with the experience!

Sometimes, however, Pablo hears feedback that sellers on the platform want to have more information about the calls they get from their buyers before they pick up. Having some basic information about the buyer, like their name and order number, would help improve the buyer's experience by allowing the seller to take a moment to organize all of the relevant details about the buyer's order before picking up the call.

To solve this problem, Pablo decides to implement Call Screening to provide the sellers with this information, which is easy for him to do because he already has all of the buyers' information in advance. Let's see how he does it.

Transfer Steps with nested steps

In a standard transfer step, only the destination number of the transfer is required. Used in this way, the transfer that connects the second call participant is triggered immediately, and the user would automatically hear a ringback tone while the destination number is being called. Upon pickup, the call would be answered and the two parties would be placed into the call. In a Call Flow, that looks like the following:

<CallFlow>
<Transfer destination="123456789" />
</CallFlow>

The transfer step, however, also accepts a "steps" parameter, or nested tags (XML) that Pablo can take advantage of. When nested steps are provided, these steps are executed for the recipient of the transfer in order before the transfer is completed. That allows Pablo to compose a Call Flow that looks like this (see the end of this document for the same Call Flow in JSON format):

<CallFlow>
<Transfer destination="123456789">
<Say id="user-information" language="en-US" voice="female">
Oh hi Mark, Lisa is inquiring about a refund for her order (number 12345).
</Say>
<Pause id="dramatic-pause" length="2s" />
<Say id="prompt" language="en-US" voice="male">
Press 1 or stay on the line to be connected. Press 2 or hangup to disconnect.
</Say>
<Pause id="wait-for-keypress" length="10s" onKeypressVar="screenpressedkey" onKeypressGoto="screenivr" />
<Hangup id="keypress-timeout"/>
<If id="screenivr" condition="screenpressedkey != 1">
<Say id="reject" language="en-US" voice="male">Rejected</Say>
<Hangup id="reject-hangup-seller"/>
</If>
<If condition="screenpressedkey == 1">n
<Say id="connecting" language="en-US" voice="male">Connecting</Say>
</If>
</Transfer>
<Play id="prerecorded-thank-you" media="https://pablonet.org/thanks-for-calling.wav" />
</CallFlow>

This call flow now accomplishes what Pablo set out to do: allow his sellers to screen calls from buyers. As you can see, this is a case where the XML call flow offers syntactic advantages that improve the readability of the Call Flow over the JSON format, but everything that is accomplished in this tutorial using XML can also be done using JSON. Let's step through it.

First the transfer is initiated to the destination number. At this point the buyer, Lisa, will hear a ringback tone until either her call is picked up by the destination number or the call is rejected and the call disconnects.

Notification icon

The ringback tone occurs automatically only for inbound calls. If using Call Screening in an outbound call scenario, it's advised to add a play step before performing the transfer so the user is prepared to wait in silence. For this reason it's better to attach this call flow to a number and instruct users to dial manually.

<Transfer destination="123456789"> ... </Transfer>

When the call is answered by the destination number, a series of Say and Pause steps are executed. These inform our seller, Mark, that he is getting a call from Lisa who is asking for a refund. It provides the order number for her purchase, and gives him options about what to do next. This series of Say (or Play) steps are called "Call Whispering" because only one person on the call is able to hear the audio that's being played.

Keep in mind that during each of these subsequent steps, the caller is still listening to the ringback tone, so it's a good idea to try to keep these steps short. If the caller hears the ringback tone for too long, they could get impatient and hangup, or in some cases a network timeout could occur and the call could be disrupted by the service provider automatically. For this reason, we use only two say steps, and one short pause of two seconds, followed by a 10 second pause for the IVR. That means that within just a few seconds of ringing Mark has the option to connect quickly with Lisa.

<Say id="user-information" language="en-US" voice="female">
Oh hi Mark, Lisa is inquiring about a refund for her order (number 12345).
</Say>
<Pause id="dramatic-pause" length="2s" />
<Say id="prompt" language="en-US" voice="female">
Press 1 or stay on the line to be connected. Press 2 or hangup to disconnect.
</Say>
Notification icon

Note that as indicated in the Say step, taking no action would result in the call being connected with Lisa. That's because when a nested transfer runs out of steps to execute, it bridges the call. If you prefer to have the call hangup instead, that can be accomplished by adding a Hangup step before the end of the inner steps.

Next, we provide the seller with an IVR that allows him to fast-forward to a couple options: either joining or ending the call with Lisa.

<Pause id="wait-for-keypress" length="10s" onKeypressVar="screenpressedkey" onKeypressGoto="screenivr" />
<Hangup id="keypress-timeout"/>
<If id="screenivr" condition="screenpressedkey != 1">
<Say id="reject" language="en-US" voice="male">Rejected</Say>
<Hangup id="reject-hangup-seller"/>
</If>
<If condition="screenpressedkey == 1">
<Say id="connecting" language="en-US" voice="male">Connecting</Say>
</If>

After the call has been bridged (or after Mark decides to hang up, whether the call was bridged or not), the steps after the transfer will be executed:

<Transfer destination="123456789"> ... </Transfer>
<Play id="prerecorded-thank-you" media="https://pablonet.org/thanks-for-calling.wav" />

In this case, Pablo takes an opportunity to play a pre-recorded message using a play step to thank the user for using his e-commerce platform. Adding steps after the transfer could be helpful, for example, if an IVR would be desired to collect feedback about the buyer's experience.

Review of concepts

We covered a lot in this short example. In particular we discussed:

  • How to make a nested transfer using the XML syntax
  • The types of steps that can be used in a nested transfer (Play, Say, If, Pause, and Hangup)
  • Important caveats regarding ringback during inbound and outbound calls

For more information on how to use each of these different types of steps, please consult the Voice API documentation. We can't wait to see what you create using these tools!

Call Flow in JSON Format

{
"steps": [
{
"action": "transfer",
"options": {
"destination": "123456789",
"steps": [
{
"id": "user-information",
"action": "say",
"options": {
"payload": "Oh hi Mark, Lisa is inquiring about a refund for her order (number 12345).",
"language": "en-US",
"voice": "female"
}
},
{
"id": "dramatic-pause",
"action": "pause",
"options": {
"length": "2s"
}
},
{
"id": "prompt",
"action": "say",
"options": {
"payload": "Press 1 or stay on the line to be connected. Press 2 or hangup to disconnect.",
"language": "en-US",
"voice": "male"
}
},
{
"id": "wait-for-keypress",
"action": "pause",
"options": {
"length": "10s"
},
"onKeypressGoto": "screenivr",
"onKeypressVar": "screenpressedkey"
},
{
"id": "keypress-timeout",
"action": "hangup"
},
{
"id": "screenivr",
"action": "say",
"options": {
"payload": "Rejected",
"language": "en-US",
"voice": "male"
},
"conditions": [
{
"variable": "screenpressedkey",
"operator": "!=",
"value": "1"
}
]
},
{
"id": "reject-hangup-seller",
"action": "hangup",
"conditions": [
{
"variable": "screenpressedkey",
"operator": "!=",
"value": "1"
}
]
},
{
"id": "connecting",
"action": "say",
"options": {
"payload": "Connecting",
"language": "en-US",
"voice": "male"
},
"conditions": [
{
"variable": "screenpressedkey",
"operator": "==",
"value": "1"
}
]
}
]
},
{
"id": "prerecorded-thank-you",
"action": "play",
"options": {
"media": "https://pablonet.org/thanks-for-calling.wav"
}
}
}
]
}

Questions?

We’re always happy to help with code or other doubts you might have! Check out our Quickstarts, API Reference, Tutorials, SDKs, or contact our Support team.

Cookie Settings