question

Rashad Nasir avatar image
Rashad Nasir asked Rashad Nasir commented

ReadCallRecording Permission

We're attempting to read and save call logs, following this guide: https://medium.com/ringcentral-developers/how-to-get-a-new-call-recording-notification-ee9f2a6e41a0 by @Phong Vu

Our app is in sandbox mode and it DOES have "ReadCallRecording" as a permission.

When we run this:

platform.get(record.recording.contentUri) 

We're getting this error: "In order to call this API endpoint, application needs to have [ReadCallRecording] permission"

Code: CMN-401

We're able to retrieve the contentUri successfully, but the above call is failing.

Any help would be appreciated.

errors
1 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Rashad Nasir avatar image
Rashad Nasir answered

Update: seems like it just took a little while to take effect... error stopped occurring with no changes to the code.

1 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Phong Vu avatar image
Phong Vu answered Rashad Nasir commented

I guess that you just add the missing permission and test it. If that is the case, wait for a few minutes for the system to apply the changes, then try again.

By the way, here is a new code to get new call recording notifications. I will update the tutorial later though.

function presenceEvent(msg){
  var user = {
    extensionId: msg.body.extensionId,
    sessionId: msg.body.activeCalls[0].sessionId,
    telephonyStatus: msg.body.telephonyStatus
  }
  checkTelephonyStatusChange(user)
}

function checkTelephonyStatusChange(user){
  var newUser = true
  for (var i=0; i<usersList.length; i++){
    if (usersList[i].extensionId == user.extensionId){
      console.log("OLD -> NEW: " + usersList[i].telephonyStatus + " -> " + user.telephonyStatus)
      newUser = false
      if (usersList[i].telephonyStatus == "NoCall" && user.telephonyStatus == "Ringing"){
        usersList[i].telephonyStatus = user.telephonyStatus
        console.log("ExtensionId " + usersList[i].extensionId + " has an incoming call")
        break
      }
      if (usersList[i].telephonyStatus == "Ringing" && user.telephonyStatus == "CallConnected"){
        usersList[i].telephonyStatus = user.telephonyStatus
        console.log("ExtensionId " + usersList[i].extensionId + " has a accepted a call")
        break
      }
      if (usersList[i].telephonyStatus == "Ringing" && user.telephonyStatus == "NoCall"){
        usersList[i].telephonyStatus = user.telephonyStatus
        console.log("ExtensionId " + usersList[i].extensionId + " has a missed call")
        break
      }
      if (usersList[i].telephonyStatus == "CallConnected" && user.telephonyStatus == "NoCall"){
        usersList[i].telephonyStatus = user.telephonyStatus
        console.log("ExtensionId " + usersList[i].extensionId + " has a terminated call")
        // wait for about 20 secs then check for call recordings
        var thisUser = usersList[i]
        setTimeout(function(){
          readExtensionCallLogs(thisUser)
        }, 20000)
        break
      }
    }
  }
  if (newUser){
    console.log("NEW USER: " + " -> " + user.telephonyStatus)
    if (user.telephonyStatus == "Ringing"){
      console.log("ExtensionId " + user.extensionId + " has an incoming call")
    }
    usersList.push(user)
  }
}

function readExtensionCallLogs(user){
  var endpoint = '/account/~/extension/'+ user.extensionId +'/call-log'
  var params = {}
  params['sessionId'] = user.sessionId
  platform.get(endpoint, params)
  .then(function(resp){
    async.each(resp.json().records,
      function(record, callback){
        if (record.hasOwnProperty("recording")){
          console.log("THIS CALL HAS A RECORDING: " + record.recording.contentUri)
          saveAudioFile(record)
          callback(null, "done")
        }
      },
      function(err){
        console.log("No call with call recording within this period of time.")
      }
    );
  })
  .catch(function(e){
    var err = e.toString();
    console.log(err)
  })
}


9 comments
1 |1000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Rashad Nasir avatar image Rashad Nasir commented ·

I'm glad there's an official revision to this, because I had to do some trial and error and already implemented some of this code (e.g. the "hasOwnProperty" check) .

That said, this full revised version is throwing an error, here: msg.body.activeCalls[0].sessionId

TypeError: Cannot read property '0' of undefined

Is there a change to the subscription I should have as well? The data I get from the subscription does not include an "activeCalls" parameter.

Currently only using '/restapi/v1.0/account/~/presence' as an eventFilter.

0 Likes 0 ·
Rashad Nasir avatar image Rashad Nasir Rashad Nasir commented ·

Looks like this has to be used as the eventFilter, your original eventFilter will not provide the activeCalls array:


"/restapi/v1.0/account/~/extension/~/presence?detailedTelephonyState=true"


0 Likes 0 ·
Phong Vu avatar image Phong Vu ♦♦ Rashad Nasir commented ·

Correct!

0 Likes 0 ·
Rashad Nasir avatar image Rashad Nasir Rashad Nasir commented ·

Noticing this behavior:

  1. user calls and there's a call recording - works fine
  2. a user calls back again, no recording is made. the code is still seeing the old sessionId, and it is retrieving the last call recording.

How can that be prevented?

0 Likes 0 ·
Phong Vu avatar image Phong Vu ♦♦ Rashad Nasir commented ·

Sorry, I did not share the function saveAudioFile() where I reset the sessionId. You should reset it after reading the call log.

0 Likes 0 ·
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.