Collect Digits
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
An incoming call is initiated by FreeClimb POSTing to the resource specified in the voiceUrl
in App Config. The callConnectUrl
and the statusCallbackUrl
in your App Config specifies the callback for connected out dial calls and status updates respectively. In this tutorial the Say
and GetDigits
PerCL actions are used to greet the calling party and provide a short color selection menu. As part of the GetDigits
PerCL action the ColorSelectionDone
actionUrl
is provided to process the selection results.
Create your package.json file and save in the root directory of your project:
{
"name": "node-get-digits-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 { PerclScript, Say, Pause, GetDigits, Hangup } = require('@freeclimb/sdk')
const app = express()
app.use(bodyParser.json())
const port = process.env.PORT || 80
const host = process.env.HOST
app.post('/incomingCall', (req, res) => {
res.status(200).json(new PerclScript({
commands: [
new Say({ text: "Hello" }),
new Pause({ length: 100 }),
new GetDigits({
prompts: [
new Say({ text: "Please select a color. Enter one for green, two for red, and three for blue. " })
],
maxDigits: 1,
minDigits: 1,
flushBuffer: true,
actionUrl: `${host}/colorSelectionDone`
})
]
}).build())
})
Successful completion of the GetDigits
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 provide audio feedback on the color selected as well as gracefully terminating the call. The sample uses additional Say
and Hangup
PerCl actions to achieve this.
app.post('/colorSelectionDone', (req, res) => {
const colors = {
'1': 'green',
'2': 'red',
'3': 'blue'
}
if (req.body.digits && req.body.digits in colors) {
res.status(200).json(new PerclScript({
commands: [
new Say({ text: `You selected ${colors[req.body.digits]}` }),
new Hangup({})
]
}).build())
} else {
res.status(200).json(new PerclScript({
commands: [
new Say({ text: "You did not select a number between 1 and 3" }),
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(`Starting server on port ${port}`)
})
Java
Upon receipt of a FreeClimb incoming call POST at the InboundCall
controller any number of PerCL actions may be supplied in the JSON encoded response. In this tutorial the Say
and GetDigits
PerCL actions are used to greet the calling party and provide a short color selection menu. As part of the GetDigits
PerCL action the ColorSelectionDone
actionUrl
is provided to process the selection results.
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:
/*
* AFTER RUNNING PROJECT WITH COMMAND:
* `gradle build && java -Dserver.port=0080 -jar build/libs/gs-spring-boot-0.1.0.jar`
* CALL NUMBER ASSOCIATED WITH THIS FreeClimb App (CONFIGURED IN FreeClimb DASHBOARD)
* EXPECT A PROMPT TO ENTER A KEY ASSOCIATED WITH A COLOR,
* THEN EXPECT A MESSAGE WHICH REPEATS THE COLOR THAT WAS SELECTED.
*/
package main.java.collect_digits;
import org.springframework.web.bind.annotation.RestController;
import com.vailsys.freeclimb.api.FreeClimbException;
import com.vailsys.freeclimb.api.call.CallStatus;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.Pause;
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.GetDigits;
import com.vailsys.freeclimb.percl.GetDigitsNestable;
import com.vailsys.freeclimb.webhooks.application.ApplicationVoiceCallback;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.LinkedList;
import com.vailsys.freeclimb.webhooks.percl.GetDigitsActionCallback;
import com.vailsys.freeclimb.percl.Hangup;
Example code:
@RestController
public class CollectDigitsController {
// Get base URL from environment variables
private String baseUrl = System.getenv("HOST");
// 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 ResponseEntity<?> inboundCall(@RequestBody String str) {
ApplicationVoiceCallback applicationVoiceCallback;
// Convert JSON into application voice callback object
try {
applicationVoiceCallback = ApplicationVoiceCallback.createFromJson(str);
} catch (FreeClimbException pe) {
PerCLScript exceptionScript = new PerCLScript();
Say errorSay = new Say("There was an error handling the incoming call.");
exceptionScript.add(errorSay);
return new ResponseEntity<>(exceptionScript.toJson(), HttpStatus.OK);
}
// Create an empty PerCL script container
PerCLScript script = new PerCLScript();
// Verify call is in the Ringing state
if (applicationVoiceCallback.getCallStatus() == CallStatus.RINGING) {
// Create PerCL say script with US English as the language
Say sayGreeting = new Say("Hello");
sayGreeting.setLanguage(Language.ENGLISH_US);
// Add PerCL say script to PerCL container
script.add(sayGreeting);
// Create PerCL pause script
Pause pause = new Pause(100);
// Add PerCL pause script to PerCL container
script.add(pause);
// Create PerCL getdigits script
GetDigits getDigits = new GetDigits(baseUrl + "/ColorSelectionDone");
// Set maximum digits to 1
getDigits.setMaxDigits(1);
// Set minimum digits to 1
getDigits.setMinDigits(1);
// Set buffer flush to true
getDigits.setFlushBuffer(true);
// Create an empty GetDigitsNestable list
LinkedList<GetDigitsNestable> prompts = new LinkedList<>();
// Create PerCL say script with US English as the language
Say sayPrompt = new Say("Please select a color. Enter one for green, two for red, and three for blue.");
sayPrompt.setLanguage(Language.ENGLISH_US);
// Add PerCL say script to GetDigitsNestable list
prompts.add(sayPrompt);
// Add GetDigitsNestable list to PerCL getdigits script
getDigits.setPrompts(prompts);
// Add PerCL getdigits script to PerCL container
script.add(getDigits); // ISSUES ARISE
}
// Respond with the PerCL script
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
Successful completion of the GetDigits
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 provide audio feedback on the color selected as well as gracefully terminating the call. The sample uses additional Say
and Hangup
PerCl actions to achieve this.
@RequestMapping(value = {
"/ColorSelectionDone" }, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> ColorSelectionDone(@RequestBody String str) {
GetDigitsActionCallback getDigitsCallback;
// Convert JSON into getdigits action callback object
try {
getDigitsCallback = GetDigitsActionCallback.createFromJson(str);
} catch (FreeClimbException pe) {
PerCLScript errorScript = new PerCLScript();
Say sayError = new Say("There was an error processing the color selection.");
errorScript.add(sayError);
return new ResponseEntity<>(errorScript.toJson(), HttpStatus.OK);
}
// Create an empty PerCL script container
PerCLScript script = new PerCLScript();
// Verify one DTMF was received
if (getDigitsCallback.getDigits() != null && getDigitsCallback.getDigits().length() == 1) {
// Create PerCL say script based on the selected DTMF with US English as the
// language
Say say;
switch (getDigitsCallback.getDigits()) {
case "1":
say = new Say("You selected green. Goodbye.");
break;
case "2":
say = new Say("You selected red. Goodbye.");
break;
case "3":
say = new Say("You selected blue. Goodbye.");
break;
default:
say = new Say("Invalid selection. Goodbye.");
break;
}
say.setLanguage(Language.ENGLISH_US);
// Add PerCL say script to PerCL container
script.add(say);
// Create PerCL hangup script and add it to PerCL container
script.add(new Hangup());
}
// Respond with the PerCL script
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
}
C#
Upon receipt of a FreeClimb incoming call POST at the InboundCall
controller any number of PerCL actions may be supplied in the JSON encoded response. In this tutorial the Say
and GetDigits
PerCL actions are used to greet the calling party and provide a short color selection menu. As part of the GetDigits
PerCL action the ColorSelectionDone
actionUrl
is provided to process the selection results.
Example code:
HttpPost ("InboundCall")] // POST voice/InboundCall
public ActionResult InboundCall (CallStatusCallback freeClimbRequest) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
// Verify inbund call is in proper state
if (freeClimbRequest.getCallStatus == ECallStatus.Ringing) {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set greeting prompt
say.setText ("Hello");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL pause script with a 100 millisecond pause
Pause pause = new Pause (100);
// Add PerCL pause script to PerCL container
script.Add (pause);
// Create PerCL getdigits script
string getDigitsUrl = AppUrl + "/voice/ColorSelectionDone";
GetDigits getDigits = new GetDigits (getDigitsUrl);
// Set the max and min number of expected digits to 1
getDigits.setMaxDigits (1);
getDigits.setMinDigits (1);
// Set the DTMF buffer flush to false
getDigits.setFlushBuffer (EBool.False);
// Create PerCL say script with US English as the language
say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set color selection menu prompt
say.setText ("Please select a color. Enter one for green, two for red or three for yellow.");
// Add main selection menu prompt to the getdigits script
getDigits.setPrompts (say);
// Add PerCL getdigits script to PerCL container
script.Add (getDigits);
}
// Convert PerCL container to JSON and append to response
return Content (script.toJson (), "application/json");
}
Upon invocation of the ColorSelectionDone
controller additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and Hangup
actions are used to provide audio feedback on the color selected as well as gracefully terminate the call.
Example code:
[HttpPost("ColorSelectionDone")] // POST voice/ColorSelectionDone
public ActionResult ColorSelectionDone (GetDigitsActionCallback getDigitsStatusCallback) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
// Verify the getdigits contains a single digit response
if ((getDigitsStatusCallback.getDigits != null) && (getDigitsStatusCallback.getDigits.Length == 1)) {
// Verify digit one selected
if (string.Equals (getDigitsStatusCallback.getDigits, "1") == true) {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set color selected prompt
say.setText ("You selected green. Goodbye.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL hangup script and add to the container
script.Add (new Hangup ());
}
// Verify digit two selected
else if (string.Equals (getDigitsStatusCallback.getDigits, "2") == true) {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set color selected prompt
say.setText ("You selected red. Goodbye.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL hangup script and add to the container
script.Add (new Hangup ());
}
// Verify digit three selected
else if (string.Equals (getDigitsStatusCallback.getDigits, "3") == true) {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set color selected prompt
say.setText ("You selected yellow. Goodbye.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL hangup script and add to the container
script.Add (new Hangup ());
}
// Invalid selection
else {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set invalid selection prompt
say.setText ("Invalid selection. Goodbye.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL hangup script and add to the container
script.Add (new Hangup ());
}
}
// unexpected getdigit response
else {
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Set error selection prompt
say.setText ("There was an error retrieving your selection. Goodbye.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL hangup script and add to the container
script.Add (new Hangup ());
}
// Convert PerCL container to JSON and append to response
return Content (script.toJson (), "application/json");
}
Updated about 2 months ago