Switching from Twilio
This tutorial shows you how to migrate an existing App from Twilio to 2600Hz. Because Pivot can render several common verbs from TwiML, it may be as simple as routing numbers in 2600Hz to your existing TwiML servers, though Twilio apps built with Twilio Studio cannot be migrated using Pivot.
This tutorial also expects you to have a 2600Hz account setup already. If you do not have a 2600Hz account, contact us! This guide additionally does not cover configuring carriers, migrating numbers between carriers, setting up storage plans for recording, and other 2600Hz configuration tasks.
Migrating from Twilio SDK
If you built your application with Twilio’s SDK or are otherwise hosting TwiML yourself, swapping 2600Hz for Twilio is simple thanks to Pivot’s TwiML support. Your numbers just need to be routed to use your servers, which can be done using the Pivot webapp, the Callflow webapp, or the Callfow API.
Please note that Pivot will skip unsupported TwiML terms. See our Pivot Documentation for supported terms. Some TwiML terms can be swapped for 2600Hz Callflow actions with similar behaviors, demonstrated in the IVR Tutorial.
Pivot App
Open your 2600Hz account and find the Pivot app.
Open the Pivot app, and navigate to ‘Number’s Routing’.
Click on ‘create new pivot action’, then configure these fields. Usually, method will be POST
depending on how your server is built.
Once saved, 2600Hz will route and process calls using your existing TwiML server.
Callflows App
Create a new Callflow and add the Pivot action, found in the ‘advanced’ dropdown. Put the url of your developer server in the Voice URL field.
Once your number is routed to this Callflow, if you’re using supported TwiML terms and the appropriate request format and method for your TwiML server, it will have the same call behavior as before.
Configure Routing with the Callflows API
See Callflows API documentation for how to a flow to route calls to your number, or ways to route multiple numbers at once. This is a brief guide on using that API. A new Callflow can be created with this Callflow API endpoint:
curl -v -X PUT \
-H "Content-Type:application/json" \
-H "X-Auth-Token: {AUTH_TOKEN}" \
-d '{"data": ... }' \
http://{SERVER}:8000/v2/accounts/{ACCOUNT_ID}/callflows
The body of the request is JSON containing a Pivot Callflow pointing to your TwiML server:
{
"data":
{
"name":"my pivot callflow",
"numbers":["555-113-0451"],
"flow": {
"module": "pivot",
"data": {
"method" : "get",
"req_format": "twiml",
"voice_url": "http://your_twiml_server.com/menu.xml"
}
}
}
}
Your number is now routed to contact your server and process the same TwiML XML as before.
Changeover from Twilio Studio
If you were using Twilio Studio before, you will need to create new 2600Hz Callflow, either by Callflow API or through the Callflow UI application drag-and drop editor. 2600Hz does not recommend using Pivot for migrating from a Twilio Studio application at this time.
IVR demo
This IVR, written with Flask and Twilio’s SDKs is fully supported by Pivot. A simple IVR such as this can be easily built using just the menu
Callflow module, either in the web editor or with 2600Hz JSON.
import flask
from twilio.twiml.voice_response import VoiceResponse
### helper functions for response headers
def pivot_twiml(body) :
res = flask.Response(str(body))
res.headers["Content-Type"] = "text/xml"
return res
### Pivot request endpoints
@app.route("/", "main_menu")
def main_menu() :
res = VoiceResponse()
with res.gather(
num_digits=1, action=flask.url_for("main_menu_action")
) as gather:
gather.say(
"""Welcome to 2600Hz. For sub-menu sandwiches, press 1.
To be connected to a fictitious operator, press 0."""
)
return pivot_twiml(res)
@app.route("/main_menu_action", methods=["POST"])
def main_menu_action() :
match flask.request.form["Digits"]:
case 0:
return pivot_twiml(VoiceResponse().dial("555-113-0451"))
case 1:
return pivot_twiml(sub_menu())
case _:
return pivot_twiml(VoiceResponse().redirect(flask.url_for("main_menu")))
@app.route("/sub_menu")
def sub_menu() :
res = VoiceResponse
with res.gather(
num_digits=1, action=flask.url_for("sub_menu_action")
) as gather:
gather.say(
"""For caprese, press 1.
For banh mi, press 2
to go back, press any other digit."""
)
return pivot_twiml(res)
@app.route("/sub_menu_action")
def sub_menu_action() :
match flask.request.form["Digits"]:
case 1:
return pivot_twiml(VoiceResponse().say("Good choice and good bye"))
case 2:
return pivot_twiml(VoiceResponse().say("Good choice and good bye"))
case _:
return pivot_twiml(VoiceResponse().redirect(flask.url_for("main_menu")))
Pivot can also dynamically switch between rendering TwiML and 2600Hz JSON with every request, so modifying this IVR to send an email notification whenever a user selects caprese requires little alteration:
### An additional helper function--Pivot expects application/json headers when
### a server responds with 2600Hz JSON.
def hz_json(body) :
res = flask.Response(str(body))
res.headers["Content-Type"] = "application/json"
return res
### Pivot request endpoints
@app.route("/sub_menu_action")
def sub_menu_action() :
match flask.request.form["Digits"]:
case 1:
return hz(caprese_callflow()) ### Changed!
case 2:
return pivot_twiml(VoiceResponse().say("Good choice and good bye"))
case _:
return pivot_twiml(VoiceResponse().redirect(flask.url_for("main_menu")))
### A simple function with a notification callflow
def caprese_callflow() :
return """
{
"flow": {
"data": {
"recipients":[
{
"type":"email",
"id":"jc@unatco.com"
}
]
},
"module": "notification",
}
"""
This notification
callflow could be extended with more callflow children, including another pivot
module if needed.