Skip to main content
Question

Needs Advice on List User Call Records API


Hello Ring Central Community,

I am very new to getting data via API but I do have a working script that successfully retrieve our company's call data in the format I wanted. Now my next obstacle is that perPage parameter only allows a maximum of 250 records returned for Detailed view.

Is there a way to retrieve more than 250 records?

If there is no way to retrieve more than 250 records, what is the best practices from here? I reviewed Ring Central Data Archival but because we don't have a database, I am not sure what to do. We have AWS S3 but currently it is not being used for company reporting. Should we set up an S3 bucket for this?

I am also not sure how often the API supposed to be called? Do I need to figure out on average how many coming through every hour and schedule the script to retrieve and append data every hour? What if there is an influx of incoming call and there are more than 250 calls during that certain hour?

Thank you in advance for any help or guidance you can provide!

10 replies

PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2320 replies
  • November 28, 2023

You can use the pagination value to navigate thru the pages (which each page contains 250 records).

Here is an example how to read the account call log using the RingCentral JS SDK

async function read_account_calllog(){
  var queryParams = {
    dateFrom: "2023-11-01T16:42:12.577Z",
    dateTo: "2023-11-05T16:42:12.577Z",
    view: "Detailed",
    perPage: 250
  }
  try {
    var resp = await platform.get('/restapi/v1.0/account/~/call-log', queryParams)

    var jsonObj = await resp.json()
    
    for (var record of jsonObj.records){
        // parse record and save it to your db
        console.log(JSON.stringify(record))
        console.log("======= ^^^^^ ========")
    }
    // Check if there are next pages
    var navigationObj = jsonObj.navigation
    if (navigationObj.hasOwnProperty("nextPage")){
      read_calllog_nextpage(navigationObj.nextPage.uri)
    }else{
        console.log("no next page. Done")
    }
  }catch(e){
    console.log(e.message)
  }
}

async function read_calllog_nextpage(url){
  try {
    var resp = await platform.get(url)
    var jsonObj = await resp.json()
    for (var record of jsonObj.records){
        // parse record and save it to your db
        console.log(JSON.stringify(record))
        console.log("======= ^^^^^ ========")
    }
    // Check if there are next pages
    var navigationObj = jsonObj.navigation
    if (navigationObj.hasOwnProperty("nextPage")){
        read_calllog_nextpage(navigationObj.nextPage.uri)
      }else{
        console.log("no more next page. Done")
      }
    } catch (e){
      console.log(e.message)
    }
}

You can combine the 2 functions into one and handle the queryParams accordingly.


  • Participating Frequently
  • 7 replies
  • August 16, 2024

Do you have c# example for this code. special on this part.

 

    var resp = await platform.get(url)    var jsonObj = await resp.json()    for (var record of jsonObj.records){        // parse record and save it to your db        console.log(JSON.stringify(record))        console.log("======= ^^^^^ ========")    }

 

Thanks, Yihan


PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2320 replies
  • August 17, 2024
ywang wrote:

Do you have c# example for this code. special on this part.

 

    var resp = await platform.get(url)    var jsonObj = await resp.json()    for (var record of jsonObj.records){        // parse record and save it to your db        console.log(JSON.stringify(record))        console.log("======= ^^^^^ ========")    }

 

Thanks, Yihan

 

Here you are

static private async Task read_user_calllog()
{
  try
  {
    var queryParams = new ReadUserCallLogParameters();
    queryParams.dateFrom = "2024-01-01T00:00:00.000Z";
    queryParams.dateTo = "2024-01-31T23:59:59.009Z";
    queryParams.view = "Detailed";

    var resp = await restClient.Restapi().Account().Extension().CallLog().List(queryParams);
    foreach (CallLogRecord record in resp.records)
    {
      Console.WriteLine(JsonConvert.SerializeObject(record, Formatting.Indented));
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine("Cannot read user call log data. " + ex.Message);
  }
}

 


  • Participating Frequently
  • 7 replies
  • August 19, 2024

Thank you, PhongVu!

 

I have questions for paging through all records after init API call, how do I use c# call the API with navigationObj.nextPage.uri 

// Check if there are next pages    var navigationObj = jsonObj.navigation    if (navigationObj.hasOwnProperty("nextPage")){      read_calllog_nextpage(navigationObj.nextPage.uri)    }else{        console.log("no next page. Done")    }

How do I make API call by navigationObj.nextPage.uri?

C# code for this part?

var resp = await platform.get(url)

var jsonObj = await resp.json()

for (

var record of jsonObj.records){ // parse record and save it to your db console.log(JSON.stringify(record)) console.log("======= ^^^^^ ========")

}

Thank you, Yihan


PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2320 replies
  • August 19, 2024
ywang wrote:

Thank you, PhongVu!

 

I have questions for paging through all records after init API call, how do I use c# call the API with navigationObj.nextPage.uri 

How do I make API call by navigationObj.nextPage.uri?

C# code for this part?

 

You can implement like this

static private async Task read_account_calllog(string page)
{
  CallLogResponse resp = null;
  if (page == "")
  {
    var parameters = new ReadCompanyCallLogParameters();
    parameters.dateFrom = "2023-11-17T00:00:00.999Z";
    parameters.view = "Detailed";
    parameters.perPage = 250;
    resp = await restClient.Restapi().Account().CallLog().List(parameters);
  }
  else
  {
    resp = await restClient.Get<CallLogResponse>(page);
  }

  // parse and do something with the response

  if (resp.navigation.nextPage != null)
  {
    Console.WriteLine("Read the next page");
    // Mind the API rate limit 10 requests per minute => cause some delay if there are more than 10 pages to read
    await read_account_calllog(resp.navigation.nextPage.uri);
  }
  else
  {
    Console.WriteLine("No more page");
  }
}

 


  • Participating Frequently
  • 7 replies
  • August 19, 2024

Thanks for help, PhongVu!!

I got runtime error when I make next page call by pass navigation.nextPage.uri

System.NullReferenceException: 'Object reference not set to an instance of an object.'
 

rcCallLogResponse = await rc.Get<CallLogResponse>(nextURL);

 

AnyIdea?

 

Here is my code.

CallLogResponse rcCallLogResponse = null;

            RestClient rc = new RestClient(
               Environment.GetEnvironmentVariable("RC_CLIENT_ID"),
               Environment.GetEnvironmentVariable("RC_CLIENT_SECRET"),
               Environment.GetEnvironmentVariable("RC_SERVER_URL")
           );

            if(nextURL == "")
            {
                // OPTIONAL QUERY PARAMETERS
                ReadCompanyCallLogParameters readCompanyCallLogParameters = new ReadCompanyCallLogParameters
                {

                    //page = nextIndex,
                    perPage = 500,
                    view = "Detailed",
                    type = voiceOnly,
                    dateFrom = fromDateTime
                };
                rc.Authorize(Environment.GetEnvironmentVariable("RC_JWT")).Wait();

                rcCallLogResponse = await rc.Restapi().Account(accountId).CallLog().List(readCompanyCallLogParameters);
            }
            else
            {
                rcCallLogResponse = await rc.Get<CallLogResponse>(nextURL);
            }

Do I need to get new Token for next page data call?

 rc.Authorize(Environment.GetEnvironmentVariable("RC_JWT")).Wait();

 

Thanks, Yihan


PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2320 replies
  • August 19, 2024

I don’t see your entire function so I don’t really know how to actually implemented and call the function.

Follow this getting started sample code and add the extra code to read next page accordingly. Remember that the getting started sample code shows how to read a user call log. The code I shared above shows how to read account call log. Modify them accordingly as what you want to read. No need to set the .Account(accountId)…

https://developers.ringcentral.com/guide/voice/call-log/quick-start#c#


  • Participating Frequently
  • 7 replies
  • August 19, 2024

Thank you so much for your help! I added token refresh event for next page API call. It is working.

Here is my function:


       

 private static async Task ReadCallLogNextPage(string nextURL)
        {

            // https://developers.ringcentral.com/my-account.html#/applications
            // Find your credentials at the above url, set them as environment variables, or enter them below

            // PATH PARAMETERS
            string accountId = "xxxxxxxxx";

            //start time
            var fromDateTime = DateTime.Now.ToString("yyyy-MM-dd") + "T00:00:00.000Z";

            string[] voiceOnly = new String[1];
            voiceOnly[0] = "Voice";

            CallLogResponse rcCallLogResponse = null;


            RestClient rc = new RestClient(
               Environment.GetEnvironmentVariable("RC_CLIENT_ID"),
               Environment.GetEnvironmentVariable("RC_CLIENT_SECRET"),
               Environment.GetEnvironmentVariable("RC_SERVER_URL")
           );
            rc.Authorize(Environment.GetEnvironmentVariable("RC_JWT")).Wait();

            if (nextURL == "")
            {
                // OPTIONAL QUERY PARAMETERS
                ReadCompanyCallLogParameters readCompanyCallLogParameters = new ReadCompanyCallLogParameters
                {
                    perPage = 500,
                    view = "Detailed",
                    type = voiceOnly,
                    dateFrom = fromDateTime
                };
                

                rcCallLogResponse = await rc.Restapi().Account(accountId).CallLog().List(readCompanyCallLogParameters);
            }
            else
            {
                rcCallLogResponse = await rc.Get<CallLogResponse>(nextURL);
            }
           

            if (rcCallLogResponse != null)
            {
                // insert RingCentralCallLogs
                foreach (var item in rcCallLogResponse.records)
                {
                    RingCentralCallLog insertRCLog = new RingCentralCallLog()
                    {
                        // add ringcentral call logs

                    //insert call legs if RingCentralCallLog session id is not in table which means new record just added.
                    if (returnRCLog == null)
                    {
                        Console.WriteLine("insert new ringcentral call:" + "ID: " + insertRCLog.id + " NewCallLog exist? " + returnRCLog);

                        foreach (var rcLogLeg in item.legs)
                        {
                            //add legs
                        }
                    }
                }

                // Check if there are next pages
                var navigation = rcCallLogResponse.navigation;
                if (navigation != null)
                {
                    if (navigation.nextPage != null)
                    {
                        Console.WriteLine("next Page -------- " + navigation.nextPage.uri);

                        //call ReadCallLogNextPage again if CallLogResponse has next page
                        await ReadCallLogNextPage(navigation.nextPage.uri);                       
                    }
                    else
                    {
                        Console.WriteLine("no next page. Done");
                    }
                }
            }

        }

 


PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2320 replies
  • August 19, 2024

Don’t call the authorize() function every time you call that function. Do exactly as the getting started sample code shows. Otherwise, you will hit the API rate limit and your app will stop working.


  • Participating Frequently
  • 7 replies
  • August 19, 2024

Got it. Thank you for great support!!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings