Пример #1
0
        /// <summary>
        /// Get a page of recordings to move to azure (we do this in a paginated way)
        /// </summary>
        /// <returns>A list of recordings, which includes the most relevant information of the recording</returns>
        private static Tuple <List <TwilioRecordingInfo>, int> GetRecordingsToMove()
        {
            //I've seen that sometimes twilio fails to response to the  "get recordings" api call, it times out. However if I try a couple of times, it works, so we do up to 10 retries
            int retries = 10;

            while (retries > 0)
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        //We only move recordings that are older than XX days. You can set it to 0 in the web.config if you want to move all the existing recordings to azure.
                        int      daysOldRequired         = int.Parse(ConfigurationManager.AppSettings["GetRecordings.DaysOldRequired"]);
                        int      pageSize                = int.Parse(ConfigurationManager.AppSettings["GetRecordings.PageSize"]);
                        DateTime moveRecordingsOlderThan = DateTime.Today.AddDays(-daysOldRequired);

                        string getRecordingsUrl = "https://api.twilio.com/2010-04-01/Accounts/" + ConfigurationManager.AppSettings["Twilio.AccountSID"] + "/Recordings.json?PageSize=" + pageSize + "&DateCreated<=" + moveRecordingsOlderThan.ToString("yyyy-MM-dd");

                        NetworkCredential credentials = new NetworkCredential();
                        credentials.UserName = ConfigurationManager.AppSettings["Twilio.AccountSID"];
                        credentials.Password = ConfigurationManager.AppSettings["Twilio.AuthToken"];
                        client.Credentials   = credentials;

                        string  response     = client.DownloadString(getRecordingsUrl);
                        dynamic responseJson = JObject.Parse(response);

                        if (((int)responseJson.total) == 0)
                        {
                            return(new Tuple <List <TwilioRecordingInfo>, int>(new List <TwilioRecordingInfo>(), 0)); //There is nothing to process
                        }
                        else
                        {
                            string lastPageUri = (string)responseJson.last_page_uri;

                            string  lastPageResponse     = client.DownloadString("https://api.twilio.com" + lastPageUri);
                            dynamic lastPageResponseJson = JObject.Parse(response);

                            List <TwilioRecordingInfo> recordingSids = new List <TwilioRecordingInfo>();
                            foreach (var recording in lastPageResponseJson.recordings)
                            {
                                TwilioRecordingInfo recInfo = new TwilioRecordingInfo();
                                recInfo.SID         = (string)recording.sid;
                                recInfo.CallSID     = (string)recording.call_sid;
                                recInfo.DateCreated = (string)recording.date_created;
                                recInfo.Duration    = (int)recording.duration;

                                recordingSids.Add(recInfo);
                            }

                            return(new Tuple <List <TwilioRecordingInfo>, int>(recordingSids, (int)lastPageResponseJson.total));
                        }
                    }
                }
                catch (Exception)
                {
                    retries--;
                    System.Threading.Thread.Sleep(2000); //Wait 2 seconds before retrying
                }
            }

            throw new Exception("Too many retries"); //Stop the execution, too many retries... twilio might not be responding.
        }
Пример #2
0
        /// <summary>
        /// Uploads the recording from twilio to azure and after that it checks that the content saved in azure matches the content in twilio
        /// </summary>
        /// <param name="recording"></param>
        /// <returns></returns>
        private static bool UploadAndCheckRecording(TwilioRecordingInfo recording)
        {
            string fileName    = recording.SID + ".wav";
            string filePath    = Path.Combine("TempRecordings", fileName);
            string contentType = null; //We are going to try to use the content type that twilio send us

            //Download the recording from twilio
            using (WebClient client = new WebClient())
            {
                string recordingUrl = "https://api.twilio.com/2010-04-01/Accounts/" + ConfigurationManager.AppSettings["Twilio.AccountSID"] + "/Recordings/" + recording.SID;
                client.DownloadFile(recordingUrl, filePath);

                if (client.ResponseHeaders.AllKeys.Contains("Content-Type"))
                {
                    contentType = client.ResponseHeaders["Content-Type"];
                }
            }


            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["Azure.StorageConnectionString"]);
            CloudBlobClient     blobClient     = storageAccount.CreateCloudBlobClient();

            CloudBlobContainer container = blobClient.GetContainerReference(ConfigurationManager.AppSettings["Azure.ContainerName"]);

            BlobContainerPermissions permissions = new BlobContainerPermissions();

            permissions.PublicAccess = BlobContainerPublicAccessType.Off;

            // Create the container if it doesn't already exist.
            bool wasCreated = container.CreateIfNotExists();

            if (wasCreated)
            {
                container.SetPermissions(permissions);
            }


            //Check if this file is already uploaded
            try
            {
                CloudBlockBlob blockBlob          = container.GetBlockBlobReference(fileName);
                string         azureCheckFilePath = Path.Combine("TempRecordings", recording.SID + ".azure.wav");

                // Save blob contents to a file.
                using (var fileStream = System.IO.File.OpenWrite(azureCheckFilePath))
                {
                    blockBlob.DownloadToStream(fileStream);
                }

                //Check if both files are equal
                if (GetFileMDS(filePath) == GetFileMDS(azureCheckFilePath))
                {
                    return(true); //The file is already uploaded and checked, so there is nothing to do, we just need to delete the recording from twilio
                }
            }
            catch (Exception)
            {
                //The blob was not found
            }

            //Upload the file to azure
            CloudBlockBlob recordingBlob = container.GetBlockBlobReference(fileName);

            using (var fileStream = System.IO.File.OpenRead(filePath))
            {
                recordingBlob.UploadFromStream(fileStream);

                if (string.IsNullOrEmpty(contentType))
                {
                    recordingBlob.Properties.ContentType = "audio/x-wav";
                }
                else
                {
                    recordingBlob.Properties.ContentType = contentType;
                }

                recordingBlob.SetProperties();

                //We set relevant information about this recording in the metadata, so we can grab it afterwards from the blob.
                recordingBlob.Metadata["CallSID"]           = recording.CallSID;
                recordingBlob.Metadata["Duration"]          = recording.Duration.ToString();
                recordingBlob.Metadata["DateCreatedTwilio"] = recording.DateCreated;

                recordingBlob.SetMetadata();
            }

            string azureCheckFilePath2 = Path.Combine("TempRecordings", recording.SID + ".azure2.wav");

            //Now we download what we have just uploaded, and we do an MD5 checksum comparison. We are triple checking that the same file that is on twilio is on azure, because we are going to delete it from twilio.
            using (var fileStream = System.IO.File.OpenWrite(azureCheckFilePath2))
            {
                recordingBlob.DownloadToStream(fileStream);
            }

            return(GetFileMDS(filePath) == GetFileMDS(azureCheckFilePath2));
        }