LogoLogo
  • Go to Docs Center
  • Meet Plum Fuse
  • Tutorial
    • Basics
    • Deployment
    • Building A Complex Application
  • How to...
    • Send SMS messages using the REST module
    • Use the SMS Module
    • Upload an Audio Recording to Storage
    • Use Plum's Transcription API
  • Fuse Navigation
  • Application Manager
    • New Application
    • Managing Applications
    • Folders
  • Template Center
  • Deployments
    • Deployments Table
    • Creating Deployments
    • Updating Deployments
    • Deleting Deployments
    • Outbound Deployments
  • Logs
  • Reports
  • My Account
    • Global Options
    • Admin Options
  • Users & Sharing
    • Single Sign On
  • Application Editor
    • Application Editor Overview
    • Settings
      • Language Settings
        • Text-To-Speech (TTS) Options
      • User Input Settings
      • Connection Settings
      • Post-Call Webservice
      • JavaScript Libraries
    • Audio Manager
      • Languages
      • Prompt Table
      • Audio Formats
      • Bulk Uploading Audio Prompts
    • Modules
  • Modules
  • Call-Flow
    • Prompt
    • Transfer
    • Go To App
    • Go To Page
    • Compare Variable
    • Counter
    • Exit
    • Call Log
    • Label
    • Subdialog
  • Input
    • Address
    • Yes/No
    • Custom Field
    • Date/Time
    • Number
    • Digits
    • Language
    • Menu
    • Dynamic Menu
    • Name
    • Record
  • Data
    • Email
    • SMS
    • Set Variable
    • Call Recording
    • Evaluate JS
    • REST
    • SOAP
  • Integration
    • Setting up authentication
    • Dialogflow
    • DynamoDB
    • AWS S3
  • Variables
    • Shadow Variables
  • Module Settings
  • Key Fuse Info
  • 📞Outbound
    • Queuing Calls with CSV
    • View Pending Calls
    • Viewing Completed Calls
    • Detecting Voicemail
    • Outbound Parameters
    • Outbound FAQs
  • 🔒Data Security
    • 'Private' Mode
    • Managing Secure Phone Numbers
    • Sensitive Data Types
  • 🔑APIs
    • Authentication
    • Outbound Calls
      • Queue Call
      • Queue Multiple Calls
      • Get Outbound Call Status
      • Cancel Outbound Calls
    • Logs
      • Get Call Logs
      • Get Call Logs With Details
      • Get A Detailed Call Log
  • 🗒️Release Notes
Powered by GitBook
On this page
  • Uploading Call Recording to Your Web Server
  • Uploading from Your Web Server to Cloud Storage
  • Sample Code
  1. How to...

Upload an Audio Recording to Storage

PreviousUse the SMS ModuleNextUse Plum's Transcription API

Last updated 3 years ago

Plum Fuse makes it easy to generate audio recordings from phone calls. Using the module you can record specific segments of a phone call or simply record all audio that occurs during a call. Using the module you can record specific caller input, similar to voicemail.

Regardless of how you utilize Fuse's call recording capabilities, the question of how to save those recordings remains.

For security and compliance reasons, Fuse does not save any recording data. All recordings are the client's responsibility and, therefore, are held in temporary memory until the call disconnects. At that point, the audio recording gets erased.

If you want to save one or more audio recordings made during a phone call, you must send the recorded audio to your own web server. Once the audio is on your web server, you can do anything with it you want to do.

In short, the basic workflow for call recording is as follows:

  • Fuse captures call audio.

  • Client uses a to send audio to their web server.

    • This step repeats within a given call if you're capturing more than one continuous recording during a call. (See Reminder below)

  • Fuse disconnects the call and deletes all call recording data generated during that call.

  • Your call recording now resides on your web server.

Uploading Call Recording to Your Web Server

The example below outlines the entire process in simplified terms. It shows how you can collect a call recording, save it via REST API to Amazon S3, and use the file URL returned by the API in an e-mail module. The primary steps are as follows:

  • A sets a custom filename for the call recording.

  • The begins.

  • The caller hears two prompts.

  • The call recording ends.

Note: If you anticipate the caller hanging up before they get to the end of the call-flow, send the generated audio file using a post-call web service instead of a REST module.

Uploading from Your Web Server to Cloud Storage

Once your audio recording gets uploaded to your web server, you can do whatever you want with the audio file(s). If you want to upload call recording audio from your web server to storage, you can use the SDK for your cloud servers or modify the following PHP sample code to run on your web server so it works with your system(s).

Sample Code

<?php
$S3_CONFIG = [
    'key' => '<aws key>',
    'secret' => '<aws secret key>',
    'region' => '<aws region>',
    'bucket' => '<aws bucket name>'
];

header('Content-Type: application/json');
if(isset($_POST["filename"]) && isset($_FILES)) {
	$result = upload_file($S3_CONFIG, $_FILES['recording']['tmp_name'], $_POST["filename"].".wav");
	echo(json_encode($result));
}
else {
	echo json_encode(array("status"=>"failure"));
}

function upload_file($config, $filepath, $new_name) {
    $retval = [];
    $ch = null;

    try {
        $service = 's3';
        $content_type = 'audio/wav';
        $filename = $new_name;
        $file = file_get_contents($filepath);
        $host = $config['bucket'] . ".$service." . $config['region'] . '.amazonaws.com';
        $timestamp = gmDate("Ymd\THis\Z"); // Amazon web stamp format
        $date = gmDate('Ymd');

        // HTTP request headers as key & value
        $request_headers = [];
        $request_headers['Content-Type'] = $content_type;
        $request_headers['Date'] = $timestamp;
        $request_headers['Host'] = $host;
        $request_headers['x-amz-content-sha256'] = hash('sha256', $file);
        // Sort it in ascending order
        ksort($request_headers);


        $canonical_headers = [];
        foreach($request_headers as $key => $value) {
            $canonical_headers[] = strtolower($key) . ":" . $value;
        }
        $canonical_headers = implode("\n", $canonical_headers);


        // Signed headers
        $signed_headers = [];
        foreach($request_headers as $key => $value) {
            $signed_headers[] = strtolower($key);
        }
        $signed_headers = implode(";", $signed_headers);

        // Cannonical request
        $canonical_request = [];
        $canonical_request[] = "PUT";
        $canonical_request[] = "/" . $filename;
        $canonical_request[] = "";
        $canonical_request[] = $canonical_headers;
        $canonical_request[] = "";
        $canonical_request[] = $signed_headers;
        $canonical_request[] = hash('sha256', $file);
        $canonical_request = implode("\n", $canonical_request);
        $hashed_canonical_request = hash('sha256', $canonical_request);


        // AWS Scope
        $scope = [];
        $scope[] = $date;
        $scope[] = $config['region'];
        $scope[] = $service;
        $scope[] = "aws4_request";

        // String to sign
        $string_to_sign = [];
        $string_to_sign[] = "AWS4-HMAC-SHA256";
        $string_to_sign[] = $timestamp;
        $string_to_sign[] = implode('/', $scope);
        $string_to_sign[] = $hashed_canonical_request;
        $string_to_sign = implode("\n", $string_to_sign);


        // Signing key
        $kSecret = 'AWS4' . $config['secret'];
        $kDate = hash_hmac('sha256', $date, $kSecret, true);
        $kRegion = hash_hmac('sha256', $config['region'], $kDate, true);
        $kService = hash_hmac('sha256', $service, $kRegion, true);
        $kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);

        // Signature
        $signature = hash_hmac('sha256', $string_to_sign, $kSigning);


        // Authorization
        $authorization = [
            'Credential=' . $config['key'] . '/' . implode('/', $scope),
            'SignedHeaders=' . $signed_headers,
            'Signature=' . $signature,
        ];
        $authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization);

        // Curl headers
        $curl_headers = [ 'Authorization: ' . $authorization ];
        foreach($request_headers as $key => $value) {
            $curl_headers[] = $key . ": " . $value;
        }

        $url = 'http://' . $host . '/' . $filename;
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $file);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        curl_close($ch);

        $retval['status'] = 'success';
        $retval['url'] = $url;
    } catch(Exception $ex) {
        if(!empty($ch)) {
            curl_close($ch);
        }
        $retval['status'] = 'fail';
        $retval['message'] = $ex->getMessage();
    }

    return $retval;

Reminder

For example, if you want to record audio on the first and third pages of your Fuse app, you need to upload the recording from the first page before the recording on the third page can start. Therefore, you need to start, stop, and upload the recording on page one. Then follow the same process for page three.

Each non-contiguous segment of recorded audio needs its own REST upload.

If you intend to capture more than one separate audio file in a single call, be sure to plan for multiple REST calls to send recorded audio when building your application.

A prompts the caller to take action; the caller makes a selection.

A uploads the audio file to the client's web server.

A checks the status of the REST call.

notify the client of the success or failure of the file upload.

The allows you to record specific sections of a call. However, if you want to record multiple, non-consecutive segments in your voice app, you need to follow the process above for each recording.

Menu module
REST module
compare module
Email modules
Call Recording module
Call Recording
Record
REST module
javascript module
call recording