Create a Recording

👍

You're ready for this how-to guide if you've got the following:

A FreeClimb account
A registered application
A configured FreeClimb Number
Your tools and language installed


Node.js

Using the FreeClimb SDK, an asynchronous out dial request can be created. At minimum a request to create an out dial request requires a To, From and callConnectUrl. The From number is a number bought through FreeClimb and associated with your account. The To number is any phone number (not provided in this example). Successful invocation of the create method indicates the asynchronous out dial request has successfully been queued. All subsequent updates for the request will be directed to the URLs provided.

Create your package.json file and save in the root directory of your project:

{
  "name": "node-make-a-recording-how-to-guide",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "@freeclimb/sdk": "^3.8.0",
    "body-parser": "^1.19.0",
    "dotenv": "^8.1.0",
    "express": "^4.17.1"
  }
}

Install the package by running the following in the command line/terminal:

yarn install

Example code:

require('dotenv').config()
const express = require('express')
const bodyParser = require('body-parser')
const freeclimbSDK = require('@freeclimb/sdk')
const { PerclScript, Say, RecordUtterance, Play, Hangup } = require('@freeclimb/sdk')

const app = express()
app.use(bodyParser.json())
// Where your app is hosted ex. www.myapp.com
const host = process.env.HOST
const port = process.env.PORT || 80
// your freeclimb API key (available in the Dashboard) - be sure to set up environment variables to store these values
const accountId = process.env.ACCOUNT_ID
const apiKey = process.env.API_KEY
const to = 'YOUR_TO_NUMBER'
const from = 'YOUR_FROM_NUMBER'
const applicationId = process.env.APPLICATION_ID
const configuration = freeclimbSDK.createConfiguration({ accountId, apiKey })
const freeclimb = new freeclimbSDK.DefaultApi(configuration)
// Invoke create method to initiate the asynchronous outdial request
freeclimb.makeACall({ to, from, applicationId, callConnectUrl: `${host}/incomingCall` }).catch(err => { console.log(err) })

The callConnectUrl provided in the original create request will be the recipient of FreeClimb requests for additional actions upon call answer. The additional PerCL actions are contained in the context of the response. In this sample both the Say and RecordUtterance PerCL actions are utilized. The RecordUtterance PerCL actionUrl provided will be invoked upon completion of the action.

app.post('/incomingCall', (req, res) => {
  res.status(200).json(new PerclScript({
    commands: [
      new Say({ text: "Hello. Please leave a message after the beep, then press one." }),
      new RecordUtterance({
        playBeep: true,
        finishOnKey: '1',
        actionUrl: `${host}/finishedRecording`
      })
    ]
  }).build())
})

Successful completion of the RecordUtterance PerCL action will result in the receipt of a FreeClimb request at the Url defined in the action’s original request. Upon receipt of the request additional PerCL actions are created to play back the recording.

app.post('/finishedRecording', (req, res) => {
  res.status(200).json(new PerclScript({
    commands: [
      new Say({ text: "This is what you have recorded" }),
      new Play({ file: req.body.recordingUrl }),
      new Hangup({})
    ]
  }).build())
})

Handle status updates:

// Specify this route with 'Status Callback URL' in App Config
app.post('/status', (req, res) => {
  // handle status changes
  res.status(200)
})

Start the server:

app.listen(port, () => {
  console.log(`started the server on port ${port}`)
})

Java

To initiate any interaction with FreeClimb a FreeClimbClient object must be created. Using the CallsRequester created upon successful creation of the FreeClimbClient an asynchronous out dial request can be created. At minimum a request to create an out dial request requires a To, From and callConnectUrl. Successful invocation of the create method indicates the asynchronous out dial request has successfully been queued. All subsequent updates for the request will be directed to the URLs provided.

Create your build.gradle file and save it to the root directory in your project:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This is a general purpose Gradle build.
 * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds
 */

buildscript {
    repositories {
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
  //Add the dependency
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE"
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'gs-spring-boot'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile "org.springframework.boot:spring-boot-starter-web"
    testCompile "junit:junit"
    compile 'com.github.FreeClimbAPI:FreeClimb-Java-SDK:3.0.0'
}

sourceSets {
    main {
        java {
            srcDirs = ['src'] // changed line
        }
    }
}

Build the file by running the following in your terminal/command line:

gradle build

Example code:

import com.vailsys.freeclimb.webhooks.call.VoiceCallback;
import com.vailsys.freeclimb.webhooks.percl.RecordUtteranceActionCallback;
 
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.RecordUtterance;
import com.vailsys.freeclimb.percl.FinishOnKey;
import com.vailsys.freeclimb.percl.Hangup;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.Pause;
import com.vailsys.freeclimb.api.call.Call;
import com.vailsys.freeclimb.api.call.CallStatus;
import com.vailsys.freeclimb.api.FreeClimbClient;
import com.vailsys.freeclimb.api.FreeClimbException;
try {
      // Create FreeClimbClient object
  		// Your account ID & API key can be found under API credentials on the FreeClimb Dashboard
      FreeClimbClient client = new FreeClimbClient(accountId, apiKey);
 
      Call call = client.calls.create(toNumber, fromNumber, applicationId);
    } catch (FreeClimbException ex) {
      // Exception throw upon failure
    }

The callConnectUrl provided in the original create request will be the recipient of FreeClimb requests for additional actions upon call answer. The additional PerCL actions are contained in the context of the response. In this sample both the Say and RecordUtterance PerCL actions are utilized. The RecordUtterance PerCL actionUrl provided will be invoked upon completion of the action.

//To properly communicate with FreeClimb's API, set your FreeClimb app's VoiceURL endpoint to '{yourApplicationURL}/InboundCall' for this example
//Your FreeClimb app can be configured in the FreeClimb Dashboard
@RequestMapping(value = {
      "/InboundCall" }, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public String inboundCall(@RequestBody String body) {
    VoiceCallback callStatusCallback;
    // Create an empty PerCL script container
    PerCLScript script = new PerCLScript();
    try {
      // Convert JSON into call status call back object
      callStatusCallback = VoiceCallback.createFromJson(body);
    } catch (FreeClimbException pe) {
      // Do something with the failure to parse the request
      return script.toJson();
    }
 
    // Verify call is in the InProgress state
    if (callStatusCallback.getDialCallStatus() == CallStatus.IN_PROGRESS) {
      // Create PerCL say script with US English as the language
      Say say = new Say("Hello. Please leave a message after the beep, then press one or hangup.");
      say.setLanguage(Language.ENGLISH_US);
 
      // Add PerCL say script to PerCL container
      script.add(say);
 
      // Create PerCL record utterance script
      RecordUtterance recordUtterance = new RecordUtterance(recordCallBackUrl);
      // Set indication that audible 'beep' should be used to signal start of
      // recording
      recordUtterance.setPlayBeep(true);
      // Set indication that end of recording is touch tone key 0ne
      recordUtterance.setFinishOnKey(FinishOnKey.ONE);
 
      // Add PerCL record utterance script to PerCL container
      script.add(recordUtterance);
 
    }
    return script.toJson();
 
  }

Successful completion of the RecordUtterance PerCL action will result in the receipt of a FreeClimb request at the Url defined in the action’s original request. Upon receipt of the request additional PerCL actions are created to gracefully terminate the out dial call. The sample uses additional Say and Hangup PerCL actions to achieve a graceful termination.

@RequestMapping(value = {
      "/RecordCallBack" }, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public String recordCallBack(@RequestBody String body) {
    // Create an empty PerCL script container
    PerCLScript script = new PerCLScript();
 
    RecordUtteranceActionCallback recordUtteranceActionCallBack;
    // Convert JSON into call status callback object
    try {
      recordUtteranceActionCallBack = RecordUtteranceActionCallback.createFromJson(body);
    } catch (FreeClimbException pe) {
      // Do something
      return script.toJson();
    }
    Say say;
    // Verify call is in the InProgress state
    if (recordUtteranceActionCallBack.getRecordingId() != null) {
      // Recording was successful as recording identifier present in response
 
      // Create PerCL say script with US English as the language
      // Set prompt to indicate message has been recorded
      say = new Say("Thanks. The message has been recorded.");
 
    } else {
      // Recording was failed as there is no recording identifier present in response
 
      // Create PerCL say script with US English as the language
      // Set prompt to indicate message recording failed
      say = new Say("Sorry we weren't able to record the message.");
    }
    say.setLanguage(Language.ENGLISH_US);
 
    // Add PerCL say script to PerCL container
    script.add(say);
 
    // Create PerCL pause script with a duration of 500 milliseconds
    Pause pause = new Pause(500);
 
    // Add PerCL pause script to PerCL container
    script.add(pause);
 
    // Create PerCL say script with US English as the language
    Say sayGoodbye = new Say("Goodbye");
    sayGoodbye.setLanguage(Language.ENGLISH_US);
 
    // Add PerCL say script to PerCL container
    script.add(sayGoodbye);
 
    // Create PerCL hangup script
    Hangup hangup = new Hangup();
 
    // Add PerCL hangup script to PerCL container
    script.add(hangup);
 
    return script.toJson();
  }

Upon termination of the call the statusCallbackUrl provided in the App Config receives a FreeClimb request. No response is required.


C#

To initiate any interaction with FreeClimb a FreeClimbClient object must be created. Using the CallsRequester created upon successful creation of the FreeClimbClient an asynchronous out dial request can be created.

At minimum a request to create an out dial request requires a To, From and applicationId. Successful invocation of the create method indicates the asynchronous out dial request has successfully been queued. All subsequent updates for the request will be directed to the application provided.

Example code:

try {
  // Create the FreeClimbClient
  FreeClimbClient client = new FreeClimbClient(accountId, apiKey);
  // Create a Call
  Call call = client.getCallsRequester.create(phoneNumber, // To
                                              freeClimbPhoneNumber, // From,
                                              applicationId); // Application to Handle the call
} catch(FreeClimbException ex) {
  System.Console.Write(ex.Message);
}

The callConnectUrl of the application provided in the original create request will be the recipient of FreeClimb requests for additional actions upon call answer. The additional PerCL actions are contained in the context of the response. In this sample both the Say and RecordUtterance PerCL actions are utilized. The RecordUtterancePerCL actionUrl provided will be invoked upon completion of the action.

Example code:

// POST /voice/
[HttpPost]
public ActionResult Post(CallStatusCallback callStatusCallback)
{
  PerCLScript script = new PerCLScript();
  // Verify call is in the InProgress state
  if (callStatusCallback.getDialCallStatus == ECallStatus.InProgress) {
    // Create PerCL say script with US English as the language
    Say say = new Say();
    say.setLanguage(ELanguage.EnglishUS);
    // Set prompt to record message
    say.setText("Hello. Please leave a message after the beep, then press one or hangup");
    // Add PerCL say script to PerCL container
    script.Add(say);
    // Create PerCL record utterance script
    string messageDoneUrl = AppUrl + "/voice/MakeRecordMessageDone";
    RecordUtterance recordUtterance = new RecordUtterance(messageDoneUrl);
    // Set indication that audible 'beep' should be used to signal start of recording
    recordUtterance.setPlayBeep(EBool.True);
    // Set indication that end of recording is touch tone key 0ne
    recordUtterance.setFinishOnKey(EFinishOnKey.One);

    // Add PerCL record utterance script to PerCL container
    script.Add(recordUtterance);
  }
  // Convert PerCL container to JSON and append to response
  return Content(script.toJson(), "application/json");
}

Successful completion of the RecordUtterance PerCL action will result in the receipt of the FreeClimb request at the Url defined in the action's original request. Upon receipt of the request additional PerCL actions are created to gracefully terminate the out dial call. The sample uses additional Say and Hangup PerCL actions to achieve a graceful termination.

Example code:

[HttpPost("MakeRecordMessageDone")]
public ActionResult MakeRecordMessageDone(RecordingUtteranceActionCallback recordingUtteranceStatusCallback) {
  // Create an empty PerCL script container
  PerCLScript script = new PerCLScript();

  if (Request != null) {
    // Check if recording was successful by checking if a recording identifier was provided
    if (recordingUtteranceStatusCallback.getRecordingId != null) {
      // Recording was successful as recording identifier present in response

      // Create PerCL say script with US English as the language
      Say say = new Say();
      say.setLanguage(ELanguage.EnglishUS);
      // Set prompt to indicate message has been recorded
      say.setText("Thanks. The message has been recorded.");

      // Add PerCL say script to PerCL container
      script.Add(say);
    }
    else {
      // Recording was failed as there is no recording identifier present in response

      // Create PerCL say script with US English as the language
      Say say = new Say();
      say.setLanguage(ELanguage.EnglishUS);
      // Set prompt to indicate message recording failed
      say.setText("Sorry we weren't able to record the message.");

      // Add PerCL say script to PerCL container
      script.Add(say);
    }

    // Create PerCL pause script with a duration of 100 milliseconds
    Pause pause = new Pause(100);

    // Add PerCL pause script to PerCL container
    script.Add(pause);

    // Create PerCL say script with US English as the language
    Say sayGoodbye = new Say();
    sayGoodbye.setLanguage(ELanguage.EnglishUS);
    // Set prompt sayGoodbye.setText("Goodbye");

    // Add PerCL say script to PerCL container
    script.Add(sayGoodbye);

    // Create PerCL hangup script
    Hangup hangup = new Hangup();

    // Add PerCL hangup script to PerCL container
    script.Add(new Hangup());
  }

  // Convert PerCL container to JSON and append to response
  return Content(script.toJson(), "application/json");
}

Upon termination of the call the statusCallbackUrl of the application provided in the initial asynchronous out dial receives a FreeClimb request and an empty response is provided.

Example code:

[HttpPost("/StatusCallback")
public ActionResult MakeRecordingCallStatus(CallStatusCallback callStatusCallback) {
  // Create an empty PerCL script container
  PerCLScript script = new PerCLScript();
 
  // Convert PerCL container to JSON and append to response
  return Content(script.toJson(), "application/json");
}