Search code examples
downloadtwiliorecordingconference

Twilio - Downloaded call recordings are sometimes empty


I'm currently wrestling with an issue where a small number of recordings are empty (when downloading them from Twilio's servers) when they shouldn't be.

My application is currently responsible for around 10,000 calls a day. Each one of these calls, if answered, is recorded and that recording is then downloaded to my server.

For whatever reason a small number of these downloaded mp3 files are empty, their size sits at 363 bytes (no audio, just the file itself) even though I know there should be content in the mp3 file. For example some calls will last between 30-40 minutes but have an empty recording when downloaded.

I'm developing in PHP and have attached the code being used to download the recording below. Does anything look like it could cause issues occasionally? I've tried searching for similar issues that others may have experienced by have not found anything so far.

Keep in mind this code works for 90% of the cases...it's just those 10% that don't download correctly.

Thanks a lot for your time!

public function index()
{
    if (isset($_REQUEST['RecordingUrl'])) {

        // Get the call ID from the url
        $confId = $this->security->xss_clean($_GET['confId']);
        $callId = $this->security->xss_clean($_GET['callId']);
        $userId = $this->security->xss_clean($_GET['userId']);

        // Twilio account information
        $accountSid = $this->config->item('twilio_accountSid');
        $authToken  = $this->config->item('twilio_authToken');

        // Download the recording to our server
        $callUrl = 'recordings/calls/' . $callId . '.mp3';
        $this->getMp3($_REQUEST['RecordingUrl'], $callUrl);

        // Delete the recording from Twilio's servers
        $this->deleteMp3($_REQUEST['RecordingUrl'], $accountSid, $authToken);

        // Mark this call as completed and update its log
        $this->call->logEndOfCall($callId);

        // Load a blank Twilio response to keep the server from throwing an error
        $this->load->view('twilio/blank_twiml');
    }
}

private function getMp3($sourceUrl = '', $destinationUrl = '')
{
    // Add the '.mp3' onto the end of the url to return an mp3 file
    $sourceUrl = $sourceUrl . '.mp3';

    // Set the variables and initialize cURL
    $destinationUrl = '/' . $destinationUrl;
    $fp = fopen($destinationUrl, 'w+');
    $ch = curl_init();
    $timeout = 300;

    // Sleep for two seconds to prevent a race condition with Twilio
    sleep(2);

    // Set the options for cURL to download the file
    curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_URL, $sourceUrl);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);

    // Execute the cURL
    curl_exec($ch);

    // Save any information for future debugging purposes
    $info = curl_getinfo($ch);

    // Close the new mp3 file and cURL
    curl_close($ch);
    fclose($fp);
}

private function deleteMp3($url = '', $username, $password)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
    $result = curl_exec($ch);
    curl_close($ch);
}

Solution

  • I was unable to get a response from Twilio on their website, and my own searching did not turn up any results.

    What I did to get past this issue for now was to implement a loop that would call getMp3 multiple times until it was confirmed that the file was downloaded correctly. I did this using PHP's filesize function.