Skip to content

Simple Connect

A simple inbound or outbound application that connects an answered inbound or outbound call to a new outbound call.
Some audio (holdmusic.wav) is played to the original call until the new call is answered. When answered it is played a message and then connected to the original call.

This sample requires one Extra Channel. Please configure your service accordingly.
It also requires the wav file holdmusic.wav to be available in the cloud media store.

Uses actions:

Connect, Play

{
    "actions" :
    [
        {
            "connect":
            {
                "destinations" :
                [
                    "441908273800"
                ],
                "call_from" : "441908273801",
                "hold_media":
                {
                    "play" :
                    {
                        "play_list" :
                        [
                            {
                                "file_to_play" : "holdmusic.wav"
                            }
                        ]
                    }
                },
                "secondary_call" :
                {
                    "first_page" :
                    {
                        "url" : "ConnectFirst"
                    }
                },
                "next_page" :
                {
                    "url" : "ConnectNext"
                }
            }
        },
        {
            "play" :
            {
                "play_list" :
                [
                    {
                        "text_to_say" : "Sorry, I could not connect your call. Goodbye."
                    }
                ]
            }
        }
    ],
    "token" : "my connect instance id"
}
{
    "actions" :
    [
        {
            "play" :
            {
                "play_list" :
                [
                    {
                        "text_to_say" : "Connecting you now."
                    }
                ]
            }
        }
    ],
    "token" : "my connect instance id"
}
{
    "actions" :
    [
        {
            "play" :
            {
                "play_list" :
                [
                    {
                        "text_to_say" : "The outbound call has disconnected. Goodbye."
                    }
                ]
            }
        }
    ],
    "token" : "my connect instance id"
}
{
    [
    ],
    "token" : "Error for Action: xxxx  ActionIndex: xxxx  Result: xxxx"
}
{
}

Implemented as ASP.Net Web Forms:

using System;
using System.Collections.Generic;
using RestAPIWrapper;

public partial class SimpleConnect : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(Request);
        if (!ourRequest.IsValid)
        {
            return;
        }

        // Setup the actions
        List<TelephonyAction> actions = new List<TelephonyAction>();

        // Create the connect action
        Connect connectAction = new Connect("441908273800");
        connectAction.CallFrom = "441908273801";
        connectAction.HoldMedia = Play.PlayFile("holdmusic.wav");
        connectAction.SecondaryCall = new SecondaryCall(new WebPageRequest("ConnectFirst.aspx"));
        connectAction.NextPage = new WebPageRequest("ConnectNext.aspx");
        actions.Add(connectAction);

        // Add a message to play if the connect doesn't succeed
        Play notConnectedMsgAction = Play.SayText("Sorry, I could not connect your call. Goodbye.");
        actions.Add(notConnectedMsgAction);

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, "my connect instance id");
        ourResponse.ToHttpResponse(Response);
    }
}
using System;
using System.Collections.Generic;
using RestAPIWrapper;

public partial class ConnectFirst : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(Request);
        if (!ourRequest.IsValid)
        {
            return;
        }
        String token = ourRequest.InstanceInfo.Token;

        // Setup the actions
        List<TelephonyAction> actions = new List<TelephonyAction>();
        actions.Add(Play.SayText("Connecting you now."));

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
        ourResponse.ToHttpResponse(Response);
    }
}
using System;
using System.Collections.Generic;
using RestAPIWrapper;

public partial class ConnectNext : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(Request);
        if (!ourRequest.IsValid)
        {
            return;
        }
        String token = ourRequest.InstanceInfo.Token;

        // Get the result of the get_number action
        GetNumberResult result = (GetNumberResult)ourRequest.InstanceInfo.ActionResult;
        String enteredNumber = result.EnteredNumber;

        // Setup the actions
        List<TelephonyAction> actions = new List<TelephonyAction>();
        actions.Add(Play.SayText("The outbound call has disconnected. Goodbye."));

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
        ourResponse.ToHttpResponse(Response);
    }
}
using System;
using System.Collections.Generic;
using RestAPIWrapper;

public partial class ErrorPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(Request);
        if (!ourRequest.IsValid)
        {
            return;
        }
        ErrorResult result = ourRequest.InstanceInfo.ErrorResult;

        String token = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}",
            result.Action, result.ActionIndex, result.Result);

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(null, token);
        ourResponse.ToHttpResponse(Response);
    }
}
using System;
using System.Collections.Generic;
using RestAPIWrapper;

public partial class FinalPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(Request);
        if (!ourRequest.IsValid)
        {
            return;
        }
    }
}

Implemented as ASP.Net Web Forms:

Imports System
Imports System.Collections.Generic
Imports RestAPIWrapper

Partial Class SimpleConnect
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

        ' Unpack the request
        Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
        If Not ourRequest.IsValid Then
            Return
        End If

        ' Setup the actions
        Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)

        ' Create the connect action
        Dim connectAction As Connect = New Connect("441908273800")
        connectAction.CallFrom = "441908273801"
        connectAction.HoldMedia = Play.PlayFile("holdmusic.wav")
        connectAction.SecondaryCall = New SecondaryCall(New WebPageRequest("ConnectFirst.aspx"))
        connectAction.NextPage = New WebPageRequest("ConnectNext.aspx")
        actions.Add(connectAction)

        ' Add a message to play if the connect doesn't succeed
        Dim notConnectedMsgAction As Play = Play.SayText("Sorry, I could not connect your call. Goodbye.")
        actions.Add(notConnectedMsgAction)

        ' Respond
        Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, "my connect instance id")
        ourResponse.ToHttpResponse(Response)
    End Sub
End Class
Imports System
Imports System.Collections.Generic
Imports RestAPIWrapper

Partial Class ConnectFirst
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

        ' Unpack the request
        Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
        If Not ourRequest.IsValid Then
            Return
        End If
        Dim token As String = ourRequest.InstanceInfo.Token

        ' Setup the actions
        Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
        actions.Add(Play.SayText("Connecting you now."))

        ' Respond
        Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
        ourResponse.ToHttpResponse(Response)
    End Sub
End Class
Imports System
Imports System.Collections.Generic
Imports RestAPIWrapper

Partial Class ConnectNext
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

        ' Unpack the request
        Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
        If Not ourRequest.IsValid Then
            Return
        End If
        Dim token As String = ourRequest.InstanceInfo.Token

        ' Setup the actions
        Dim actions As List(Of TelephonyAction) = New List(Of TelephonyAction)
        actions.Add(Play.SayText("The connected outbound call has disconnected. Goodbye."))

        ' Respond
        Dim ourResponse As TelephonyResponse = New TelephonyResponse(actions, token)
        ourResponse.ToHttpResponse(Response)
    End Sub
End Class
Imports System
Imports System.Collections.Generic
Imports RestAPIWrapper

Partial Class ErrorPage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

        ' Unpack the request
        Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
        If Not ourRequest.IsValid Then
            Return
        End If
        Dim result As ErrorResult = ourRequest.InstanceInfo.ErrorResult

        Dim token As String = String.Format("Action: {0}\nActionIndex: {1}\nResult: {2}", _
            result.Action, result.ActionIndex, result.Result)

        ' Respond
        Dim ourResponse As TelephonyResponse = New TelephonyResponse(token)
        ourResponse.ToHttpResponse(Response)
    End Sub
End Class
Imports System
Imports System.Collections.Generic
Imports RestAPIWrapper

Partial Class FinalPage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

        ' Unpack the request
        Dim ourRequest As TelephonyRequest = New TelephonyRequest(Request)
        If Not ourRequest.IsValid Then
            Return
        End If
    End Sub
End Class

Implemented as Java Servlets:

package com.aculab.telephonyrestapi.samples;

import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import com.aculab.telephonyrestapi.*;

public class SimpleConnect extends HttpServlet
{
    @Override
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) throws IOException
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(request);
        if (!ourRequest.isValid())
        {
            return;
        }

        // Set up the actions
        List<TelephonyAction> actions = new ArrayList<TelephonyAction>();

        // Create the connect action
        Connect connectAction = new Connect("441908273800");
        connectAction.setCallFrom("441908273801");
        connectAction.setHoldMedia(Play.playFile("holdmusic.wav"));
        connectAction.setSecondaryCall(new SecondaryCall(new WebPageRequest("ConnectFirst")));
        connectAction.setNextPage(new WebPageRequest("ConnectNext"));
        actions.add(connectAction);

        // Add a message to play if the connect doesn't succeed
        Play notConnectedMsgAction = Play.sayText("Sorry, I could not connect your call. Goodbye.");
        actions.add(notConnectedMsgAction);

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, "my connect instance id");
        ourResponse.setHttpServletResponse(response);
    }
}
package com.aculab.telephonyrestapi.samples;

import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import com.aculab.telephonyrestapi.*;

public class ConnectFirst extends HttpServlet
{
    @Override
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) throws IOException
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(request);
        if (!ourRequest.isValid())
        {
            return;
        }
        String token = ourRequest.getInstanceInfo().getToken();

        // Set up the actions
        List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
        actions.add(Play.sayText("Connecting you now."));

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
        ourResponse.setHttpServletResponse(response);
    }
}
package com.aculab.telephonyrestapi.samples;

import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import com.aculab.telephonyrestapi.*;

public class ConnectNext extends HttpServlet
{
    @Override
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) throws IOException
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(request);
        if (!ourRequest.isValid())
        {
            return;
        }
        String token = ourRequest.getInstanceInfo().getToken();

        // Set up the actions
        List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
        actions.add(Play.sayText("The outbound call has disconnected. Goodbye."));

        // Respond
        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
        ourResponse.setHttpServletResponse(response);
    }
}
package com.aculab.telephonyrestapi.samples;

import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.aculab.telephonyrestapi.*;

public class ErrorPage extends HttpServlet
{
    private static final long serialVersionUID = -4842873371047361437L;

    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request,
            HttpServletResponse response)
                    throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) throws IOException
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(request);
        if (!ourRequest.isValid())
        {
            return;
        }
        ErrorResult result = ourRequest.getInstanceInfo().getErrorResult();

        String token = String.format("Action: %s\nActionIndex: %d\nResult: %s", result.getAction(), result.getActionIndex(), result.getResult());

        // Respond
        List<TelephonyAction> actions = new ArrayList<TelephonyAction>();
        TelephonyResponse ourResponse = new TelephonyResponse(actions, token);
        ourResponse.setHttpServletResponse(response);
    }
}
package com.aculab.telephonyrestapi.samples;

import javax.servlet.http.*;
import javax.servlet.ServletException;
import java.io.IOException;
import com.aculab.telephonyrestapi.*;

public class FinalPage extends HttpServlet
{
    private static final long serialVersionUID = 5940620014313056844L;

    @Override
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request,
            HttpServletResponse response)
                    throws IOException, ServletException
    {
        handleRequest(request, response);
    }

    private void handleRequest(HttpServletRequest request,
                               HttpServletResponse response) throws IOException
    {
        // Unpack the request
        TelephonyRequest ourRequest = new TelephonyRequest(request);
        if (!ourRequest.isValid())
        {
            return;
        }
    }
}

Implemented using a wrapper for Python's wsgiref.simple_server.

For the purposes of this sample, the first page is first_page, the final page is final_page and the error page is error_page.

The application base class.

from aculab.telephony_rest_api import Play

class ApplicationBase:

    def __init__(self, exit=None):
        self.exit = exit or [self.exit]


    def exit(self):
        pass


    def error_page(self, my_actions, query_info):
        try:
            error_result = query_info.ErrorResult
            action = error_result.get('action', 'none')
            print("\nError {0} : {1}\n".format(action, error_result['result']))
            my_actions.add(Play(text_to_say='I encountered an error.'))

        except Exception as exc:
            print("Error page exception: {0}".format(exc))
        return True


    def final_page(self, my_actions, query_info):
        try:
            tcall = query_info.ThisCall
            if tcall:
                print("This call ID         : {0}".format(tcall.get('call_id')))
                print("This call duration   : {0}".format(tcall.get('seconds_call_duration')))
            self.exit[0]()
        except Exception as exc:
            print("Final page exception: {0}".format(exc))
        return True


    def unknown_page(self, my_actions, query_info):
        try:
            my_actions.add(Play(text_to_say='I find myself on an unknown page.'))
        except Exception as exc:
            print("Unknown page exception: {0}".format(exc))
        return True

The application code.

import sys, os
sys.path.append(os.path.abspath('../..'))

# import the wrappers for the REST API, these are used to create and send tasks
from aculab.telephony_rest_api import *
from aculab.simple_server import *
from aculab.base_application import ApplicationBase

class Application(ApplicationBase):

    def __init__(self):
        ApplicationBase.__init__(self)

    def responder(self, query, start_response):

        query_info = RESTQuery(query)
        page = query_info.Page

        my_actions = Actions(token='connect call sample')

        # On your inbound service configuration page, set the first page entry to point to this page
        # e.g., http://<ip address>:<port>/first_page
        # To use a secondary call your inbound service will require one Extra Channel, configure
        # the service to have one Extra Channel.
        if 'first_page' == page:
            my_connect = Connect()
            # When phoning telephone numbers, this must be a full international phone number, without the +
            my_connect.append_call_destination('441908273800') 
            # When phoning telephone numbers, this must be a validated phone number. 
            # Please see the online documentation for details
            my_connect.set_call_origin('441908273801') 
            my_connect.set_hold_media(Play(file_to_play='holdmusic.wav'))
            my_connect.set_secondary_call(SecondaryCall(first_page=WebPage(url='secondary_first'),
                                                        final_page=WebPage(url='secondary_final'),
                                                        error_page=WebPage(url='error_page')))
            my_actions.add(my_connect)

        elif 'secondary_first' == page:
            my_actions.add(Play(text_to_say='Connecting you now.'))

        elif 'secondary_final' == page:
            print("Outbound call duration: {0}".format(query_info.ThisCall.get('seconds_call_duration')))

        elif 'final_page' == page:
            if self.final_page(my_actions, query_info) is False:
                return None

        elif 'error_page' == page:
            if self.error_page(my_actions, query_info) is False:
                return None

        else:
            if self.unknown_page(my_actions, query_info) is False:
                return None

        response_body = my_actions.get_json()
        response_headers = [('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', str(len(response_body)))]
        start_response('200 OK', response_headers)
        return [response_body]


if __name__ == "__main__":
    application = Application()
    # Set the host and port you want to use in the rest_simple_server.py file.
    # To use SSL also set the key and certificate file.
    ss = SimpleServer(application, simple_server_host, simple_server_port, simple_server_keyfile, simple_server_certfile)
    ss.start()
    print("Hit ctl-break to quit.")
declare(encoding='UTF-8');
spl_autoload_register();
header("Content-Type: application/json; charset=UTF-8");

use \Aculab\TelephonyRestAPI\Actions;
use \Aculab\TelephonyRestAPI\Play;
use \Aculab\TelephonyRestAPI\Connect;
use \Aculab\TelephonyRestAPI\SecondaryCallConfiguration;

$response = new Actions();
$response->setToken('my connect instance id');

// Create the connect action
$connect = new Connect();
$connect->addDestination('441908273800');
$connect->setCallFrom('441908273800');
$connect->setHoldMedia(Play::playFile('holdmusic.wav'));

$call_config = new SecondaryCallConfiguration();
$call_config->setFirstPage('ConnectFirst.php');
$connect->setSecondaryCallConfiguration($call_config);

$connect->setNextPage('ConnectNext.php');
$response->add($connect);

// Add a message to play if the connect doesn't succeed
$play = new Play();
$play->addText('Sorry, I could not connect your call. Goodbye.');
$response->add($play);

print $response;
declare(encoding='UTF-8');
spl_autoload_register();
header("Content-Type: application/json; charset=UTF-8");

use \Aculab\TelephonyRestAPI\InstanceInfo;
use \Aculab\TelephonyRestAPI\Actions;
use \Aculab\TelephonyRestAPI\Play;

$info = InstanceInfo::getInstanceInfo();

$response = new Actions();
$response->setToken($info->getToken());

$play = new Play();
$play->addText('Connecting you now.');
$response->add($play);

print $response;
declare(encoding='UTF-8');
spl_autoload_register();
header("Content-Type: application/json; charset=UTF-8");

use \Aculab\TelephonyRestAPI\InstanceInfo;
use \Aculab\TelephonyRestAPI\Actions;
use \Aculab\TelephonyRestAPI\Play;

$info = InstanceInfo::getInstanceInfo();

$response = new Actions();
$response->setToken($info->getToken());

$play = new Play();
$play->addText('The outbound call has disconnected. Goodbye.');
$response->add($play);

print $response;
declare(encoding='UTF-8');
spl_autoload_register();
header("Content-Type: application/json; charset=UTF-8");

$info = \Aculab\TelephonyRestAPI\InstanceInfo::getInstanceInfo();

$error = $info->getErrorResult();
$action = $error->getAction();
$desc = $error->getResult();
if (!is_null($action)) {
    error_log("Error from action \"$action\" with result:\n$desc\n");
} else {
    error_log("Error result:\n$desc\n");
}

$response = new \Aculab\TelephonyRestAPI\Actions();
$response->setToken('Error');

$play = new \Aculab\TelephonyRestAPI\Play();
$play->addText('An error has occurred.');
$response->add($play);

print $response;
declare(encoding='UTF-8');
spl_autoload_register();
header("Content-Type: application/json; charset=UTF-8");

$info = \Aculab\TelephonyRestAPI\InstanceInfo::getInstanceInfo();
$call = $info->getThisCallInfo();
$callid = $call->getCallId();
$duration = $call->getSecondsCallDuration();
error_log("This all id: $callid\nThis call duration: $duration\n");

print '';