Handle a Call Queue
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
In response to a POST request a number of PerCL actions may be supplied in the JSON encoded response. In this tutorial the Say
, Pause
and Enqueue
PerCL actions are used to greet and enqueue the calling party. As part of the Enqueue
PerCL action the InboundCallAction
actionUrl
is provided to process the selection results. In addition to the actionUrl
the optional waitUrl
InboundCallWait
is also in the Enqueue
PerCL action.
Create your package.json file and save in the root directory of your project:
{
"name": "node-inbound-call-queue-how-to-guide",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@freeclimb/sdk": "^1.0.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 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 || 3000
// your FreeClimb API credentials (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 freeclimb = freeclimbSDK(accountId, apiKey)
app.post('/incomingCall', (req, res) => {
const options = {
alias: 'Test',
maxSize: 25
}
//Invoke method to create a queue with the options provided
freeclimb.api.queues.create(options).then(queue => {
// use created queue
const enqueue = freeclimb.percl.enqueue(queue.queueId, `${host}/inboundCallAction`, `${host}/inboundCallWait`)
const percl = freeclimb.percl.build(enqueue)
res.status(200).json(percl)
}).catch(err => { /* Handle Errors */ })
})
Upon invocation the Enqueue
PerCL action the call will be enqueued and the InboundCallWait
Url invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and GetDigits
actions are used to provide instructions on how to exit the Queue. As part of the GetDigits
PerCL action the CallDequeueSelect
actionUrl
is provided to process the results.
app.post('/inboundCallWait', (req, res) => {
const queueId = req.params.queueId
const callId = req.body.callId
// Create PerCL say script
const say = freeclimb.percl.say('Press any key to exit queue.')
// Create options for getDigits script
const prompts = freeclimb.percl.build(say)
const options = {
prompts,
maxDigits: 1,
minDigits: 1,
flushBuffer: true
}
// Create PerCL for getDigits script
const getDigits = freeclimb.percl.getDigits(`${host}/callDequeue`, options)
// Build and respond with Percl script
const percl = freeclimb.percl.build(getDigits)
res.status(200).json(percl)
})
Upon invocation completion of the GetDigits
PerCL action, the CallDequeueSelect
Url is invoked. If a GetDigits
actions result is a digit, a PerCL Dequeue
action is returned in the response. Otherwise, the PerCL Say
, Play
and GetDigits
actions are used again to provide hold music as well as instruction on how to exit the Queue.
app.post('/callDequeue', (req, res) => {
const getDigitsResponse = req.body
const digits = getDigitsResponse.digits
if (digits && digits.length > 0) {
const dequeue = freeclimb.percl.dequeue()
const percl = freeclimb.percl.build(dequeue)
res.status(200).json(percl)
} else {
const redirect = freeclimb.percl.redirect(`${host}/inboundCallWait`)
const percl = freeclimb.percl.build(redirect)
res.status(200).json(percl)
}
})
Upon invocation completion of the Dequeue
PerCL action the CallDequeueSelect
Url is invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and Hangup
actions are used to indicate that the call was dequeued, as well as to disconnect the call.
app.post('/inboundCallAction', (req, res) => {
const say = freeclimb.percl.say('Call exited queue')
const percl = freeclimb.percl.build(say)
res.status(200).json(percl)
})
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('Listening on port ' + port)
})
Java
In response to a POST request a number of PerCL actions may be supplied in the JSON encoded response. In this tutorial the Say
, Pause
and Enqueue
PerCL actions are used to greet and enqueue the calling party. As part of the Enqueue
PerCL action the InboundCallAction
actionUrl
is provided to process the selection results. In addition to the actionUrl
the optional waitUrl
InboundCallWait
is also in the Enqueue
PerCL action.
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']
}
}
}
Build the file by running the following in your terminal/command line:
gradle build
Example code:
import com.vailsys.freeclimb.api.FreeClimbClient;
import com.vailsys.freeclimb.api.FreeClimbException;
import com.vailsys.freeclimb.api.call.CallStatus;
import com.vailsys.freeclimb.api.queue.Queue;
import com.vailsys.freeclimb.api.queue.QueueCreateOptions;
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.Pause;
import com.vailsys.freeclimb.percl.Enqueue;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Example code:
//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 request){
//Create an empty PerCL script container
PerCLScript script = new PerCLScript();
try {
//Create a FreeClimbClient object
//accountId & api key can be found under API credentials on the FreeClimb Dashboard
FreeClimbClient client = new FreeClimbClient(accountId, apiKey);
if(request != null){
//Convert the JSON into a request object
ApplicationVoiceCallback callback = ApplicationVoiceCallback.createFromJson(request);
//Verify inbound call is in the proper state
if(callback.getCallStatus() == CallStatus.RINGING){
//Create PerCL say script with US English as the language
Say say = new Say("Hello. Your call will be queued.");
say.setLanguage(Language.ENGLISH_US);
//Add PerCL say script to PerCL container
script.add(say);
//Create PerCL pause script with a 100 millisecond pause
script.add(new Pause(100));
//Create Queue options with an alias
QueueCreateOptions options = new QueueCreateOptions();
options.setAlias("InboundCallQueue");
//Create a queue with an alias
Queue queue = client.queues.create(options);
//Create PerCL say to enqueue the call into the newly created queue with an actionUrl
Enqueue enqueue = new Enqueue(queue.getQueueId(), {yourApplicationURL} + "/InboundCallAction");
//Add waitUrl
enqueue.setWaitUrl({yourApplicationURL} + "/InboundCallWait");
// Add PerCL enqueue script to PerCL container
script.add(enqueue);
}
}
}
catch(FreeClimbException pe) {
System.out.println(pe.getMessage());
}
//Convert PerCL container to JSON and append to response
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
Upon invocation of the Enqueue
PerCL action, the call will be enqueued and the InboundCallWait
Url invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and GetDigits
actions are used to provide instruction on how to exit the queue. As part of the GetDigits
PerCL action, the CallDequeueSelect
actionUrl
is provided to process the results.
Imports used:
import com.vailsys.freeclimb.api.FreeClimbException;
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.GetDigits;
import com.vailsys.freeclimb.percl.GetDigitsNestable;
import com.vailsys.freeclimb.webhooks.queue.QueueWaitCallback;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Example code:
@RequestMapping(value = {"/InboundCallWait"}, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> inboundCallWait(@RequestBody String request){
//Create an empty PerCL script container
PerCLScript script = new PerCLScript();
if (request != null) {
try {
// Convert the JSON into a request object
QueueWaitCallback callback = QueueWaitCallback.createFromJson(request);
//Create PerCL getdigits script
GetDigits digits = new GetDigits({yourApplicationURL} + "/CallDequeueSelect");
//Create a list of prompts to use with the getdigits command
LinkedList<GetDigitsNestable> prompts = new LinkedList<>();
//Create PerCL say script with US English as the language
Say say = new Say("Thank you for waiting. Press any key to exit queue.");
say.setLanguage(Language.ENGLISH_US);
//Add say script to the list of prompts
prompts.add(say);
//Set the list as the prompts to use with the getdigits command
digits.setPrompts(prompts);
// Add PerCL getdigits script to PerCL container
script.add(digits);
}
catch(FreeClimbException pe) {
System.out.println(pe.getMessage());
}
}
//Convert PerCL container to JSON and append to response
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
Upon invocation completion of the GetDigits
PerCL action the CallDequeueSelect
Url is invoked. If a GetDigits
action result is a digit, a PerCL Dequeue
action is returned in the response. Otherwise, the PerCL Say
and GetDigits
actions are used again to provide continuous instruction on how to exit the Queue.
Imports used:
import com.vailsys.freeclimby.api.FreeClimbyException;
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.GetDigits;
import com.vailsys.freeclimb.percl.GetDigitsNestable;
import com.vailsys.freeclimb.percl.Dequeue;
import com.vailsys.freeclimb.webhooks.percl.GetDigitsActionCallback;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Example code:
@RequestMapping(value = {"/CallDequeueSelect"}, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> callDequeue(@RequestBody String request){
//Create an empty PerCL script container
PerCLScript script = new PerCLScript();
if (request != null) {
try {
// Convert JSON into a request object
GetDigitsActionCallback callback = GetDigitsActionCallback.createFromJson(request);
// Check if a digit was pressed
if(callback.getDigits() != null && callback.getDigits().length() > 0) {
// Create PerCL dequeue script and add to PerCL container
script.add(new Dequeue());
} else {
//Create PerCl getdigits script
GetDigits digits = new GetDigits({yourApplicationURL} + "/CallDequeueSelect");
// Create a list of prompts to use with the getdigits command
LinkedList<GetDigitsNestable> prompts = new LinkedList<>();
// Create PerCL say script with US English as the language
Say say = new Say("Thank you for waiting. Press any key to exit queue.");
say.setLanguage(Language.ENGLISH_US);
// Add say script to prompts list
prompts.add(say);
//Add prompts list to the getdigits command
digits.setPrompts(prompts);
//Add PerCL getdigits script to PerCL container
script.add(digits);
}
}
catch(FreeClimbException pe) {
System.out.println(pe.getMessage());
}
}
//Convert PerCL container to JSON and append to response
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
Upon invocation completion of the Dequeue
PerCL action the InboundCallAction
Url is invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and Hangup
actions are used to indicate that the call was dequeued, as well as to disconnect the call.
Imports used:
import com.vailsys.freeclimb.api.FreeClimbException;
import com.vailsys.freeclimb.percl.PerCLScript;
import com.vailsys.freeclimb.percl.Say;
import com.vailsys.freeclimb.percl.Language;
import com.vailsys.freeclimb.percl.Hangup;
import com.vailsys.freeclimb.webhooks.queue.QueueActionCallback;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Example code:
@RequestMapping(value = {"/InboundCallAction"}, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<?> dequeueAction(@RequestBody String request){
//Create an empty PerCL script container
PerCLScript script = new PerCLScript();
if (request != null) {
//Convert JSON into a request object
try {
QueueActionCallback callback = QueueActionCallback.createFromJson(request);
//Create PerCL say script with US English as the language
Say say = new Say("Call exited queue.");
say.setLanguage(Language.ENGLISH_US);
// Add PerCL say script to PerCL container
script.add(say);
//Create and add PerCL hangup script to PerCL container
script.add(new Hangup());
}
catch(FreeClimbException pe) {
System.out.println(pe.getMessage());
}
}
//Convert PerCL container to JSON and append to response
return new ResponseEntity<>(script.toJson(), HttpStatus.OK);
}
C#
In response to a POST request a number of PerCL actions may be supplied in the JSON encoded response. In this tutorial the Say
, Pause
and Enqueue
PerCL actions are used to greet and enqueue the calling party. As part of the Enqueue
PerCL action the InboundCallAction
actionUrl
is provided to process the selection results. In addition to the actionUrl
the optional waitUrl
InboundCallWait
is also in the Enqueue
PerCL action.
Example code:
[HttpPost("InboundCall")]
public ActionResult InboundCall (CallStatusCallback freeClimbRequest) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
// Verify inbound 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. Your call will be queued.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create PerCL pause script with a 100 millisecond pause
script.Add (new Pause (100));
// Create queue options with an alias
QueueOptions options = new QueueOptions ();
options.setAlias ("InboundCallQueue");
// Create FreeClimbClient object
FreeClimbClient client = new FreeClimbClient (getFreeClimbAccountId (), getFreeClimbApiKey ());
// Create a queue with an alias
Queue queue = client.getQueuesRequester.create (options);
// Create PerCL say to enqueue the call into the newly created queue with an actionUrl
Enqueue enqueue = new Enqueue (queue.getQueueId, getAppUrl() + "/voice/InboundCallAction");
// Add waitUrl
enqueue.setWaitUrl (getAppUrl() + "/voice/InboundCallWait");
// Add PerCL enqueue script to PerCL container
script.Add (enqueue);
}
// Convert PerCL container to JSON and append to response
return Content (script.toJson (), "application/json");
}
Upon invocation of the Enqueue
PerCL command the call will be enqueued and the InboundCallWait
Url invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
, Play
and GetDigits
actions are used to provide hold music as well as instruction on how to exit the Queue. As part of the GetDigits
PerCL action the CallDequeueSelect
actionUrl
is provided to process the results.
Example code:
[HttpPost("InboundCallWait")]
public ActionResult InboundCallWait (QueueWaitCallback queueWaitStatusCallback) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
// Create PerCL getdigits script
string getDigitsUrl = Url.Action (getAppUrl() + "/voice/CallDequeueSelect");
GetDigits digits = new GetDigits (getDigitsUrl); // actionUrl
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Add prompt to for queue exit
say.setText ("Press any key to exit queue.");
// Add say script as a prompt to getdigits
digits.setPrompts (say);
// Add PerCL getdigits script to PerCL container
script.Add (digits);
// Convert PerCL container to JSON and append to response
return Content (script.toJson (), "application/json");
}
Upon invocation completion of the GetDigits
PerCL action the CallDequeueSelect
Url invoked. If a GetDigits
action result is a digit, a PerCL Dequeue
action is returned in the response. Otherwise, the PerCL Say
, Play
and GetDigits
actions are used again to provide hold music as well as instruction on how to exit the Queue.
Example code:
[HttpPost("CallDequeueSelect")]
public ActionResult CallDequeueSelect (GetDigitsActionCallback getDigitsStatusCallback) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
if ((getDigitsStatusCallback.getDigits != null) &&
(getDigitsStatusCallback.getDigits.Length > 0)) {
// Create PerCL dequeue script and add to PerCL container
script.Add (new Dequeue ());
} else {
// Create PerCL getdigits script
GetDigits digits = new GetDigits (getAppUrl() + "/voice/CallDequeueSelect");
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Add prompt to for queue exit
say.setText ("Press any key to exit queue.");
// Add say script as a prompt to getdigits
digits.setPrompts (say);
// Add PerCL getdigits script to PerCL container
script.Add (digits);
}
// Convert PerCL container to JSON and append to response
return Content (script.toJson (), "application/json");
}
Upon invocation completion of the Dequeue
PerCL action the CallDequeueSelect
Url is invoked; additional PerCL actions may accompany the response. In this tutorial the PerCL Say
and Hangup
actions are used to indicate the call was dequeued as well as to disconnect the call.
Example code:
[HttpPost("InboundCallAction")]
public ActionResult InboundCallAction (QueueActionCallback queueActionStatusCallback) {
// Create an empty PerCL script container
PerCLScript script = new PerCLScript ();
// Create PerCL say script with US English as the language
Say say = new Say ();
say.setLanguage (ELanguage.EnglishUS);
// Add prompt for queue exit
say.setText ("Call exited queue.");
// Add PerCL say script to PerCL container
script.Add (say);
// Create and 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");
}
Updated 3 months ago