Voicemail Drop

Craig Chan
RingCentral Developers

--

Here’s a question I’ve heard asked often and we don’t say much about, “Do you have Voicemail Drop?” The answer is “Yes!” but the next question, “How do I use Voicemail Drop?” is often left unanswered, until now.

What is Voicemail Drop?

Voicemail Drop is often used by Inside Sales to accelerate the process of leaving voicemail messages. When inside sales calls a customer, and the call goes to voicemail, Voicemail Drops enables representatives to leave a pre-recorded voicemail message by “dropping” that voicemail with a single click. They can then jump to the next call immediately instead of spending time leaving a voicemail for the customer.

Why is Voicemail Drop Important?

Voicemail Drop is designed to save inside sales reps a lot of time. We have reports that Inside Sales reps can spend 45–60 minutes a day leaving voicemails which can lead to 15–22 hours a month just leaving voicemails. But with Voicemail Drop, reps can click a button to leave the voicemail and move on to the next call, saving that time to reach more customers.

Great! So How Do I Do That?

While it’s not difficult to configure Voicemail Drop, it is different than you might expect which is why this article will help step you through what you need to do to set up Voicemail Drop with RingCentral.

We start by going into our Service Web (service.ringcentral.com) where we set up an Announcement-Only Extension as the message we want to leave the customer. First, login as an administrator so you access the Admin Portal of Service Web. Then under the Phone System tab, there is a Groups drawer where the Announcement-Only Extension is set. I created an example called “Voicemail Drop” at extension 2001. Now, whenever I transfer a call to that extension, the message will play.

Figure 1 — setting up an Announcement-Only Extension

You can customize your voicemail with a prerecorded message, or record one right now. You can also create more than one Announcement-Only Extension if you are ready to implement more buttons for different voicemail messages you wish to leave, but for this example, we’ll stick with just one.

Trigger the Voicemail Drop

Now let’s write some code. It had to come at some point since this article is for developers, right?

First, you can now create WebSocket connections with our SDKs as our new method for subscribing to notifications. For this example, I am using the Python SDK to subscribe to telephony session notifications. To do so, we create a WebSocket client and connect it. We then subscribe to telephony session notifications by creating a subscription to:

/restapi/v1.0/account/~/extension/~/telephony/sessions 

I’ll need to create a WebSocket connection, create a subscription, and then listen for subscription notification events which can be accomplished with just a few lines of code (Python in my case)

web_socket_client = sdk.create_web_socket_client()
web_socket_client.on(WebSocketEvents.connectionCreated, on_ws_created)
web_socket_client.on(WebSocketEvents.subscriptionCreated, on_sub_created)
web_socket_client.on(WebSocketEvents.receiveSubscriptionNotification, on_notification)
await asyncio.gather(
web_socket_client.create_new_connection(),
web_socket_client.create_subscription([“/restapi/v1.0/account/~/extension/~/telephony/sessions”])
)

Now I’ll start receiving telephony events like when a call is made, ringing, answered, disconnected, etc. Let’s listen for those events and print them on the console.

print(“\n Subscription notification:\n”)
# We are grabbing the notification body which is the second object in this list.
jsonObj = message[1]
statusCode = jsonObj[‘body’][‘parties’][0][‘status’][‘code’]
print(“Status code: “ + statusCode)

In this instance, we want to know when the call is answered so we can prompt the agent to drop a voicemail to the customer. Here, you can see I’m transferring the call to extension 2001, which is my announcement-only extension we set up earlier.

if statusCode == “Answered”:
telephonySessionId = jsonObj[‘body’][‘telephonySessionId’]
partyId = jsonObj[‘body’][‘parties’][0][‘id’]
print(“Telephony Session ID: “ + telephonySessionId)
print(“Party ID: “ + partyId)
input("Press enter to transfer to voicemail drop…")
endpoint = "/restapi/v1.0/account/~/telephony/sessions/"+telephonySessionId+"/parties/"+partyId+"/transfer"
bodyParams = {
'extensionNumber': '2001'
}
platform.post(endpoint, bodyParams)

This means when the call is answered, either by the person or voicemail, we can let the agent determine if they want to leave a live voicemail or drop a pre-recorded message to the voicemail. Just press “enter” and leave a voicemail!

So let’s give you the full code so you can try it yourself. Make sure to set your .env file with you RC_CLIENT_ID, RC_CLIENT_SECRET, RC_SERVER_URL and RC_JWT token. Drop a comment and let me know how it goes!

from ringcentral import SDK
from dotenv import load_dotenv
import asyncio
import os, json, time
from ringcentral.websocket.events import WebSocketEvents

load_dotenv(override=True)
sdk = SDK(
os.environ['RC_CLIENT_ID'],
os.environ["RC_CLIENT_SECRET"],
os.environ["RC_SERVER_URL"],
)
platform = sdk.platform()
platform.login(jwt=os.environ["RC_JWT"])

def on_notification(message):
print("\n Subscription notification:\n")
# We are grabbing the notification body which is the second object in this list.
jsonObj = message[1]
#print( json.dumps(jsonObj, indent=2, sort_keys=True) )
statusCode = jsonObj['body']['parties'][0]['status']['code']
print("Status code: " + statusCode)

if statusCode == "Answered":
telephonySessionId = jsonObj['body']['telephonySessionId']
partyId = jsonObj['body']['parties'][0]['id']
print("Telephony Session ID: " + telephonySessionId)
print("Party ID: " + partyId)

input("Press enter to transfer to voicemail drop...")

endpoint = "/restapi/v1.0/account/~/telephony/sessions/"+telephonySessionId+"/parties/"+partyId+"/transfer"
bodyParams = {
'extensionNumber': '2001'
}
platform.post(endpoint, bodyParams)

def on_sub_created(sub):
print("\n Subscription created:\n")
print(sub.get_subscription_info())
print("\n Ready to receive telephony notifications \n")

def on_ws_created(web_socket_client):
print("\n New WebSocket connection created:")
print(web_socket_client.get_connection_info())

async def main():
try:
web_socket_client = sdk.create_web_socket_client()
web_socket_client.on(WebSocketEvents.connectionCreated, on_ws_created)
web_socket_client.on(WebSocketEvents.subscriptionCreated, on_sub_created)
web_socket_client.on(WebSocketEvents.receiveSubscriptionNotification, on_notification)
await asyncio.gather(
web_socket_client.create_new_connection(),
web_socket_client.create_subscription(["/restapi/v1.0/account/~/extension/~/telephony/sessions"])
)
except KeyboardInterrupt:
print("Stopped by User")


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())

--

--

Craig Chan
RingCentral Developers

Director of PM, Platforms, with a passion for helping developers build automation and integration to the Engage Voice and RingCentral Telephony experience.