News & Announcements User Community Developer Community

Welcome to the RingCentral Community

Please note the community is currently under maintenance and is read-only.

Search
Make sure to review our Terms of Use and Community Guidelines.
  Please note the community is currently under maintenance and is read-only.
Home » Developers
C# app that downloads the call recordings.
Tags: call recording
Oct 27, 2021 at 12:35pm   •   6 replies  •  0 likes
Jim Lin

I am looking for a simple C# that can download call recordings.

I have looked at https://github.com/ringcentral/RingCentral.Net

Set up a sandbox app made a test call and recorded it. But I am lacking in the ability to just have a simple app that downloads to a local folder on the computer it runs on.

Does anyone have something I can use?

6 Answers
answered on Oct 29, 2021 at 7:42am  

so I want to use this in production mode I got the app Active for Production Status. it worked it was downloading all the recordings then it stopped with this error.


System.AggregateException: 'One or more errors occurred. (The remote server returned an error: (429) Too Many Requests.)'

WebException: The remote server returned an error: (429) Too Many Requests.


How can I fix that?


Also, how can I pull the Meta-data from the call log so I have some info on who made the call and the time/day of the call?


 0
answered on Oct 29, 2021 at 9:05am  

How do you handle reading 7000 call logs? Each time you read the call log you will get max 1000 records per page. So with 7000 records, you have yo read 7 times using the next page tokens. You must also take care of the API rate limit (40 calls per 60 secs) of the call log list endpoint. Then when you download the recordings, the rate limit is 10 downloads per 60 secs. Read this article to learn more about API rate limit and how to handle it.

You do need to handle exception and check each call recording record.recording.contentUri is not null.

All in all, my snippet code is a sample and you need to fine tune it for your production code.


 0
answered on Oct 28, 2021 at 8:48am  

I don't see you call the download function. Modify your code as follows

        const string RINGCENTRAL_CLIENTID = "0_m0q2SexxxxxxKNQ";
        const string RINGCENTRAL_CLIENTSECRET = "S1xxxxxxxxxZMiFFHzzzzzrb_sWSjUg";
        const bool RINGCENTRAL_PRODUCTION = false;
 
        const string RINGCENTRAL_USERNAME = "15555555555";
        const string RINGCENTRAL_PASSWORD = "Password123!";
        const string RINGCENTRAL_EXTENSION = "101";
        static RestClient rcsdk;
        static void Main(string[] args)
        {
            // Display the number of command line arguments.
            Console.WriteLine(args.Length);
            rcsdk = new RestClient(RINGCENTRAL_CLIENTID, RINGCENTRAL_CLIENTSECRET, RINGCENTRAL_PRODUCTION);
            rcsdk.Authorize(RINGCENTRAL_USERNAME, RINGCENTRAL_EXTENSION, RINGCENTRAL_PASSWORD).Wait();
            download_call_log_callrecording().Wait();
        }
        static private async Task download_call_log_callrecording()
        {
            var parameters = new ReadCompanyCallLogParameters();
            parameters.dateFrom = "2021-07-05T00:00:00.000Z";
            parameters.view = "Simple";
            parameters.recordingType = "All";

            var path = "recording_content/";
            System.IO.Directory.CreateDirectory(path);
            long timePerApiCall = 6000;

            var resp = await rcsdk.Restapi().Account().CallLog().List(parameters);
            foreach (var record in resp.records)
            {
                Console.WriteLine("-----");
                Console.WriteLine("Call recording: " + record.recording.contentUri);
                var fileName = path + "call_" + record.recording.id + "_recording";
                var start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var result = await rcsdk.Restapi().Account().Recording(record.recording.id).Get();
                if (result.contentType == "audio/mpeg")
                {
                    fileName += ".mp3";
                }
                else // can check if "audio/x-wav"
                {
                    fileName += ".wav";
                }
                var contentUrl = result.contentUri + "?access_token=" + rcsdk.token.access_token;
                WebClient webClient = new WebClient();
                webClient.DownloadFile(contentUrl, fileName);
                Console.WriteLine("Save recording file to the local machine.");
                var end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var delay = (end - start) * 1000;
                Console.WriteLine(delay);
                if (delay < timePerApiCall)
                {
                    Thread.Sleep((int)(timePerApiCall - delay));
                }
            }
        }
 

 0
answered on Oct 28, 2021 at 8:29am  

ok so i got this put together


using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using RingCentral;

namespace Recordings
{
    class Program
    {
        static void Main(string[] args)
        {
            // Display the number of command line arguments.
            Console.WriteLine(args.Length);
        }


        const string RINGCENTRAL_CLIENTID = "0_m0q2SexxxxxxKNQ";
        const string RINGCENTRAL_CLIENTSECRET = "S1xxxxxxxxxZMiFFHzzzzzrb_sWSjUg";
        const bool RINGCENTRAL_PRODUCTION = false;

        const string RINGCENTRAL_USERNAME = "15555555555";
        const string RINGCENTRAL_PASSWORD = "Password123!";
        const string RINGCENTRAL_EXTENSION = "101";

        static private async Task download_call_log_callrecording()
        {
            RestClient rc = new RestClient(RINGCENTRAL_CLIENTID, RINGCENTRAL_CLIENTSECRET, RINGCENTRAL_PRODUCTION);
            await rc.Authorize(RINGCENTRAL_USERNAME, RINGCENTRAL_EXTENSION, RINGCENTRAL_PASSWORD);
            var parameters = new ReadCompanyCallLogParameters();
            parameters.dateFrom = "2021-09-05T00:00:00.000Z";
            parameters.view = "Simple";
            parameters.recordingType = "All";

            var path = "recording_content/";
            System.IO.Directory.CreateDirectory(path);
            long timePerApiCall = 6000;

            var resp = await rc.Restapi().Account().CallLog().List(parameters);
            foreach (var record in resp.records)
            {
                Console.WriteLine("-----");
                Console.WriteLine("Call recording: " + record.recording.contentUri);
                var fileName = path + "call_" + record.recording.id + "_recording";
                var start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var result = await rc.Restapi().Account().Recording(record.recording.id).Get();
                if (result.contentType == "audio/mpeg")
                {
                    fileName += ".mp3";
                }
                else // can check if "audio/x-wav"
                {
                    fileName += ".wav";
                }
                var contentUrl = result.contentUri + "?access_token=" + rc.token.access_token;
                WebClient webClient = new WebClient();
                webClient.DownloadFile(contentUrl, fileName);
                Console.WriteLine("Save recording file to the local machine.");
                var end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var delay = (end - start) * 1000;
                Console.WriteLine(delay);
                if (delay < timePerApiCall)
                {
                    Thread.Sleep((int)(timePerApiCall - delay));
                }
            }
        }
    }
}


When I run it I get this in the Debug output


'Ring_ABS.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.8\System.Private.CoreLib.dll'.

'Ring_ABS.exe' (CoreCLR: clrhost): Loaded 'C:\Users\mikea\source\repos\Ring_ABS\bin\Debug\netcoreapp3.1\Ring_ABS.dll'. Symbols loaded.

'Ring_ABS.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.8\System.Runtime.dll'.

'Ring_ABS.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.8\System.Console.dll'.

'Ring_ABS.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.8\System.Threading.dll'.

'Ring_ABS.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.8\System.Runtime.Extensions.dll'.

The program '[36264] Ring_ABS.exe' has exited with code 0 (0x0).




 0
answered on Oct 27, 2021 at 1:59pm  

Try this

static private async Task download_call_log_callrecording()
{
    RestClient rc = new RestClient(RINGCENTRAL_CLIENTID, RINGCENTRAL_CLIENTSECRET, RINGCENTRAL_PRODUCTION);
    await rc.Authorize(RINGCENTRAL_USERNAME, RINGCENTRAL_EXTENSION, RINGCENTRAL_PASSWORD);
    var parameters = new ReadCompanyCallLogParameters();
    parameters.dateFrom = "2021-09-05T00:00:00.000Z";
    parameters.view = "Simple";
    parameters.recordingType = "All";

    var path = "recording_content/";
    System.IO.Directory.CreateDirectory(path);
    long timePerApiCall = 6000;

    var resp = await rc.Restapi().Account().CallLog().List(parameters);
    foreach (var record in resp.records)
    {
        Console.WriteLine("-----");
        Console.WriteLine("Call recording: " + record.recording.contentUri);
        var fileName = path + "call_" + record.recording.id + "_recording";
        var start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        var result = await rc.Restapi().Account().Recording(record.recording.id).Get();
        if (result.contentType == "audio/mpeg")
        {
            fileName += ".mp3";
        }
        else // can check if "audio/x-wav"
        {
            fileName += ".wav";
        }
        var contentUrl = result.contentUri + "?access_token=" + rc.token.access_token;
        WebClient webClient = new WebClient();
        webClient.DownloadFile(contentUrl, fileName);
        Console.WriteLine("Save recording file to the local machine.");
        var end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        var delay = (end - start) * 1000;
        Console.WriteLine(delay);
        if (delay < timePerApiCall)
        {
            Thread.Sleep((int)(timePerApiCall - delay));
        }
    }
}

 0
answered on Oct 28, 2021 at 10:12am  

ok it's working great and for anyone that sees this post here is the full code.


using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using RingCentral;

namespace Recordings
{
    class Program
    {
      


        const string RINGCENTRAL_CLIENTID = "0_mdddddddddQ";
        const string RINGCENTRAL_CLIENTSECRET = "S1h7dddddsWSjUg";
        const bool RINGCENTRAL_PRODUCTION = false;

        const string RINGCENTRAL_USERNAME = "15555555555";
        const string RINGCENTRAL_PASSWORD = "PASSWORD321!";
        const string RINGCENTRAL_EXTENSION = "101";

        static RestClient rcsdk;
        static void Main(string[] args)
        {
            
            rcsdk = new RestClient(RINGCENTRAL_CLIENTID, RINGCENTRAL_CLIENTSECRET, RINGCENTRAL_PRODUCTION);
            rcsdk.Authorize(RINGCENTRAL_USERNAME, RINGCENTRAL_EXTENSION, RINGCENTRAL_PASSWORD).Wait();
            download_call_log_callrecording().Wait();
        }
        static private async Task download_call_log_callrecording()
        {
            var parameters = new ReadCompanyCallLogParameters();
            parameters.dateFrom = "2021-07-05T00:00:00.000Z";
            parameters.view = "Simple";
            parameters.recordingType = "All";

            //Makes the file path
            var path = "c:/recording_content/";
            System.IO.Directory.CreateDirectory(path);
            long timePerApiCall = 6000;

            var resp = await rcsdk.Restapi().Account().CallLog().List(parameters);

            foreach (var record in resp.records)
            {
                Console.WriteLine("-----");
                Console.WriteLine("Call recording: " + record.recording.contentUri);
                var fileName = path + "call_" + record.recording.id + "_recording";
                var start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var result = await rcsdk.Restapi().Account().Recording(record.recording.id).Get();
                if (result.contentType == "audio/mpeg")
                {
                    fileName += ".mp3";
                }
                else // can check if "audio/x-wav"
                {
                    fileName += ".wav";
                }
                var contentUrl = result.contentUri + "?access_token=" + rcsdk.token.access_token;
                WebClient webClient = new WebClient();
                webClient.DownloadFile(contentUrl, fileName);
                Console.WriteLine("Save recording file to the local machine.");
                var end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
                var delay = (end - start) * 1000;
                Console.WriteLine(delay);
                if (delay < timePerApiCall)
                {
                    Thread.Sleep((int)(timePerApiCall - delay));
                }
            }
        }
    }
}



 0



A new Community is coming to RingCentral!

Posts are currently read-only as we transition into our new platform.

We thank you for your patience
during this downtime.

Try Workflow Builder

Did you know you can easily automate tasks like responding to SMS, team messages, and more? Plus it's included with RingCentral Video and RingEX plans!

Try RingCentral Workflow Builder

PRODUCTS
RingEX
Message
Video
Phone
OPEN ECOSYSTEM
Developer Platform
APIs
Integrated Apps
App Gallery
Developer support
Games and rewards

RESOURCES
Resource center
Blog
Product Releases
Accessibility
QUICK LINKS
App Download
RingCentral App login
Admin Portal Login
Contact Sales
© 1999-2024 RingCentral, Inc. All rights reserved. Legal Privacy Notice Site Map Contact Us