Legacy Dev Forum Posts

 View Only

Sign Up

Bulk Download recordings yields only 25 per day?

  • 1.  Bulk Download recordings yields only 25 per day?

    Posted 06-05-2025 18:06

    fgrimps | 2020-07-02 20:56:10 UTC | #1

    Hi, I am using the C# code to bulk download all recordings for the last year in batches of single days based on the .NET/C# sample here: https://developer.mypurecloud.com/api/tutorials/recordings-downloader/index.html?language=csharp&step=1

    Downloading recordings works, however, I only retrieve a maximum of 25 files for each day. That does not sound right. I cannot find anything in my code that would cause this. Is there some sort of daily limit on how many recordings are stored or how many can be retrieved?

    using System;
    using System.IO;
    using System.Net;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using PureCloudPlatform.Client.V2.Api;
    using PureCloudPlatform.Client.V2.Client;
    using PureCloudPlatform.Client.V2.Extensions;
    using PureCloudPlatform.Client.V2.Extensions.Notifications;
    using PureCloudPlatform.Client.V2.Model;
    using Newtonsoft.Json;
    
    namespace PureCloudRecordingsExporterCmd
    {
        class Program
        {
            const string basePath = @"G:\Recordings";
            static string _path = basePath;
            static void Main(string[] args)
            {
                string clientId = "xxx";
                string clientSecret = "zzz";
    
                try
                {
                    // Create the Date Interval
                    var start = new DateTime(2019, 7, 1, 0, 0, 0);// Interval (YYYY-MM-DDThh:mm:ss/YYYY-MM-DDThh:mm:ss)
                    System.IO.Directory.CreateDirectory(_path); //usually already exists..
                    for (; start < DateTime.Now; start = start.AddDays(1))
                    {
                        //prepare download directory for single days
                        _path = basePath + "\\" + start.ToString("yyyy-MM-dd");
                        //prepare interval string for a single day
                        string interval = start.ToString("yyyy-MM-ddTHH:mm:ss") + "/" + start.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ss");  // e.g. "2019-05-24T00:00:00/2019-05-25T00:00:00";
                        SafeDownloadInterval(clientId, clientSecret, interval);
                    }
                }
                catch (Exception ex)
                {
                    LogWriter.LogWrite(ex.Message);
                }
            }
    
            private static void SafeDownloadInterval(string clientId, string clientSecret, string interval)
            {
                //retry two times if there is an exception
                for (int attempts = 0; attempts < 3; attempts++)
                {
                    try
                    {
                        string accessToken = GetToken(clientId, clientSecret);
                        PureCloudPlatform.Client.V2.Client.Configuration.Default.AccessToken = accessToken;
                        // Instantiate APIs
                        ConversationsApi conversationsApi = new ConversationsApi();
                        // Call conversation API, pass date inputted to extract conversationIds needed
                        AnalyticsConversationQueryResponse conversationDetails = conversationsApi.PostAnalyticsConversationsDetailsQuery(new ConversationQuery(Interval: interval));
                        // Pass conversation details to download function
                        extractConversationDetails(conversationDetails);
                        //success, no further attempts needed
                        break;
                    }
                    catch (Exception ex)
                    {
                        LogWriter.LogWrite(ex.Message);
                        if (attempts == 2)
                            LogWriter.LogWrite("Give up after two retries: Consider redownloading "+ interval);
                    }
                }
            }
    
            private static void extractConversationDetails(AnalyticsConversationQueryResponse conversationDetails)
            {
                // Push all conversationId from conversationDetails to conversationIds
                foreach (var conversationDetail in conversationDetails.Conversations)
                {
                    getRecordingMetaData(conversationDetail.ConversationId);
                }
            }
    
            private static void getRecordingMetaData(string conversationId)
            {
                RecordingApi recordingApi = new RecordingApi();
                List<Recording> recordingsData = recordingApi.GetConversationRecordingmetadata(conversationId);
    
                // Pass recordingsMetadata to a function
                iterateRecordingsData(recordingsData);
            }
    
            private static void iterateRecordingsData(List<Recording> recordingsData)
            {
                foreach (var iterateRecordings in recordingsData)
                {
                    getSpecificRecordings(iterateRecordings);
                }
            }
    
            private static void getSpecificRecordings(Recording iterateRecordings)
            {
                List<BatchDownloadRequest> batchRequest = new List<BatchDownloadRequest>();
                BatchDownloadRequest batchDownloadRequest = new BatchDownloadRequest(ConversationId: iterateRecordings.ConversationId, RecordingId: iterateRecordings.Id);
                batchRequest.Add(batchDownloadRequest);
    
                // Create the batch job with the request list
                BatchDownloadJobSubmission batchSubmission = new BatchDownloadJobSubmission(BatchDownloadRequestList: batchRequest);
    
                BatchDownloadJobSubmissionResult recordingBatchRequestId = new BatchDownloadJobSubmissionResult();
                RecordingApi recordingApi = new RecordingApi();
                recordingBatchRequestId = recordingApi.PostRecordingBatchrequests(batchSubmission);
    
                recordingStatus(recordingBatchRequestId);
            }
    
            private static void recordingStatus(BatchDownloadJobSubmissionResult recordingBatchRequestId)
            {
                BatchDownloadJobStatusResult getRecordingBatchRequestData = new BatchDownloadJobStatusResult();
                RecordingApi recordingApi = new RecordingApi();
                getRecordingBatchRequestData = recordingApi.GetRecordingBatchrequest(recordingBatchRequestId.Id);
    
                if (getRecordingBatchRequestData.ExpectedResultCount == getRecordingBatchRequestData.ResultCount)
                {
                    // Pass the getRecordingBatchRequestData to getExtension function
                    getExtension(getRecordingBatchRequestData);
                }
                else
                {
                    Thread.Sleep(3000);
                    recordingStatus(recordingBatchRequestId);
                }
            }
    
            private static void getExtension(BatchDownloadJobStatusResult getRecordingBatchRequestData)
            {
                // Store the contentType to a variable that will be used later to determine the extension of recordings.
                string contentType = getRecordingBatchRequestData.Results[0].ContentType;
                // Split the text and gets the extension that will be used for the recording
                string ext = contentType.Split('/').Last();
    
                createDirectory(ext, getRecordingBatchRequestData);
            }
    
            private static void createDirectory(string ext, BatchDownloadJobStatusResult getRecordingBatchRequestData)
            {
                Console.WriteLine("Processing please wait...");
    
                string conversationId = getRecordingBatchRequestData.Results[0].ConversationId;
                string recordingId = getRecordingBatchRequestData.Results[0].RecordingId;
                string url = getRecordingBatchRequestData.Results[0].ResultUrl;
    
                string path;
                //string path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                //path = path.Substring(0, path.LastIndexOf("bin"));
                System.IO.Directory.CreateDirectory(_path + @"\" + conversationId + "_" + recordingId);
    
                downloadRecording(url, ext, _path + @"\" + conversationId + "_" + recordingId);
            }
    
            private static void downloadRecording(string url, string ext, string targetDirectory)
            {
                // string downloadFile = conversationId + '_' + recordingId + '.' + ext;
                string filename = targetDirectory.Substring(targetDirectory.LastIndexOf('\\') + 1, 73);
    
                using (WebClient wc = new WebClient())
                    wc.DownloadFile(url, targetDirectory + "\\" + filename + "." + ext); // NOTE: overwrites file if exists (which is desired)
            }
    
            private static string GetToken(string clientId, string clientSecret)
            {
                var accessTokenInfo = Configuration.Default.ApiClient.PostToken(clientId, clientSecret);
                string token = accessTokenInfo.AccessToken;
    
                return token;
            }
        }
    }

    AgnesCorpuz | 2020-07-03 01:35:50 UTC | #2

    In your function call to PostAnalyticsConversationsDetailsQuery, the ConversationQuery must have the "Paging" property. The Paging property should use the PagingSpec object that has PageSize and PageNumber properties. Without specifying this, it defaults to 25.

    You may also try using the API Explorer in the Developer Tools. On the left side menu, navigate to the Analytics > Conversations> POST Query for conversation details. https://developer.mypurecloud.com/developer-tools/#/api-explorer


    fgrimps | 2020-07-06 15:48:19 UTC | #3

    Thank you, Agnes. I see. That makes sense and solves the mystery here. Welp, I will have to restart the whole process and downloading using this approach is so incredible slow (I guess we have too much data). Or is there something faster? Thanks, again. Best, Florian


    AgnesCorpuz | 2020-07-07 00:12:55 UTC | #4

    As suggested in this other similar post, you can open a case with Genesys Cloud (PureCloud) Care to investigate the download speeds.

    You may also want to try multi threading or using asynchronous functions. This can speed up the downloading process of your app.


    system | 2020-08-07 00:12:59 UTC | #5

    This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.


    This post was migrated from the old Developer Forum.

    ref: 8174