How to start, stop and resume recording a call programmatically?

Phong Vu
RingCentral Developers
4 min readSep 29, 2021

To record phone calls in RingCentral voice call is easy, and it can be set to automatic or on-demand call recording. While automatic call recording is self-explanatory, on-demand call recording on the other hand, requires a user to dial *9 on a phone’s dial pad, or to click the Record button on the RingCentral phone app to start recording at any time during the call.

RingCentral platform also provides API to control call recording. This enables developers to implement their own logic or a remote control to start, stop or resume recording a call from their application.

To record a call using the API, you will need the following information of the call:

1. The call telephony session id, which is the unique id of the phone call session.

2. The party id which identifies the RingCentral user party in the call (not the remote party of the call).

3. The call status must be in ‘Answered’ (Connected) state.

It’s worth mentioning that you can only record your own phone calls, a call in which you are one of the call parties. This means that you must authenticate your app using the login credentials of a user whose phone call will be recorded.

To get the required call info for recording a call, you can subscribe for the extension telephony session event notification. Please read this blog for details.

Below is a typical payload of a telephony session event notification when an incoming call is answered:

Typical body data of an incoming call event

You can parse the event data to get the required call info for the recordings API

var callInfo = {
sessionId: '', // capture this id if you want to read the call record from the call log later
telSessionId: '', // use this id to create the recording endpoint path
partyId: '', // use this id to create the recording endpoint path
recordingId: '' // use this to pause/resume a call recording
}
subscription.on(subscription.events.notification, async function(msg) {
var body = msg.body
var party = body.parties[0]
if (party.hasOwnProperty("extensionId")){
if (party.direction == "Inbound" && party.status.code == "Answered"){
if (!party.hasOwnProperty('recordings')){
callInfo.sessionId = body.sessionId
callInfo.telSessionId = body.telephonySessionId
callInfo.partyId = party.id
// start recording immediately or make a delay
startRecording()
}
}
}else{
console.log("Can ignore remote party call events")
}
});

Start recording a call

To start record a call, make a POST request to the following endpoint with the required call info.

/restapi/v1.0/account/~/telephony/sessions/[telephonySessionId]/parties/[partyId]/recordings

async function startRecording(){
console.log("startRecording")
if (callInfo.telSessionId == '' || callInfo.partyId == '')
return
var endpoint = `/restapi/v1.0/account/~/telephony/sessions/${callInfo.telSessionId}/parties/${callInfo.partyId}/recordings`
try {
var resp = await platform.post(endpoint)
var jsonObj = await resp.json()
callInfo.recordingId = jsonObj.id
console.log(jsonObj)
}catch(e){
console.log(e.message)
}
}
}

Pause recording a call

To pause a call recording, make a PATCH request to the following endpoint with the ‘recordingId’ you got after starting the recording.

/restapi/v1.0/account/~/telephony/sessions/[telephonySessionId]/parties/[partyId]/recordings/[recordingId]

async function pauseRecording(){
if (callInfo.telSessionId == '' || callInfo.partyId == '' || callInfo.recordingId == '')
return
var endpoint = `/restapi/v1.0/account/~/telephony/sessions/${callInfo.telSessionId}/parties/${callInfo.partyId}/recordings/${callInfo.recordingId}`
var params = { active: false }
try {
var resp = await platform.patch(endpoint, params)
var jsonObj = await resp.json()
console.log(jsonObj)
}catch(e){
console.log(e)
}
}

Resume recording a call

To resume a call recording, make a PATCH request to the following endpoint with the ‘recordingId’ you got after starting the recording.

/restapi/v1.0/account/~/telephony/sessions/[telephonySessionId]/parties/[partyId]/recordings/[recordingId]

async function resumeRecording(){
if (callInfo.telSessionId == '' || callInfo.partyId == '' || callInfo.recordingId == '')
return
var endpoint = `/restapi/v1.0/account/~/telephony/sessions/${callInfo.telSessionId}/parties/${callInfo.partyId}/recordings/${callInfo.recordingId}`
var params = { active: true }
try {
var resp = await platform.patch(endpoint, params)
var jsonObj = await resp.json()
console.log(jsonObj)
}catch(e){
console.log(e)
}
}

You can pause and resume recording a call as many times as you need to. Pause and resume will not create new recording files. But you will hear the recording warning message every time the recording is resumed.

Download the call recording

If you wish to download the call recording after the call is terminated. You must wait for about 40 secs to allow the system finalizing and syncing the call data to the call log database. You can use the call session Id stored in the callInfo.sessionId to read the call record from the call log, and parse the ‘recording’ object in the response to get the content URI and download the recording binary file. Alternatively, you can use the recording Id stored in the callInfo.recordingId and call the get call recording endpoint to get the content URI and download the binary content.

subscription.on(subscription.events.notification, async function(msg) {
var body = msg.body
var party = msg.body.parties[0]
if (party.hasOwnProperty("extensionId")){
if (party.status.code == "Answered"){
...
}else if (party.status.code == "Disconnected"){
// Want to download the call recording after the call ended?
if (body.sessionId == callInfo.sessionId){
console.log("Download it in 40 seconds")
setTimeout(function(){
downloadRecordingContent()
}, 40000)
}
}
}
});
async function downloadRecordingContent(){
if (callInfo.recordingId == '')
return
var endpoint = `/restapi/v1.0/account/~/recording/${callInfo.recordingId}`
var resp = await platform.get(endpoint)
var jsonObj = await resp.json()
var fileNameExtension = (jsonObj.contentType == 'audio/x-wav') ? '.wav' : '.mp3'
var fileName = `${callInfo.recordingId}${fileNameExtension}`
saveAudioFile(jsonObj.contentUri, fileName)
}
async function saveAudioFile(contentUri, fileName){
var resp = await platform.get(contentUri)
var buffer = await resp.buffer()
fs.writeFileSync(fileName, buffer);
console.log("CALL RECORDING SAVED. " + fileName)
}

Download the entire source code from here. And feel free to further develop this app to make it useful for your business.

Learn more about our Developer Program here: https://developer.ringcentral.com/

--

--