Plivo High Level Objects (PHLO, pronounced “flow”) is a visual workflow design studio. It provides building blocks that let you create custom voice and SMS applications without writing program code. Instead, you drag and drop components onto a canvas and connect them to create custom workflows. That lets you build applications quickly, and you can speed development time further by using PHLO templates — prebuilt workflows for common use cases.
The canvas is the space where you place and connect components to create a PHLO. If a PHLO grows to cover the visible canvas, you can scroll the canvas in any direction to declutter the display.
Components are PHLO’s building blocks. You drag and drop components to the canvas to create nodes, then connect the nodes to create workflows. You can view a list of all components on the Components Library page.
A node is an instance of a component that has been placed on the canvas. Each node must have a unique name within the PHLO.
States are properties that a component is set to or based on for each action. Each component has one input state and at least one output state.
Every node has a set of default configuration values associated with it. When you click on a node you can view its configuration in the Configuration tab on a panel on the right of the canvas. To view the list of configuration options available for the node, click the Information tab at the top of that panel. The Information tab displays information about the node, its default variables, and node-specific options and states.
You can change a node’s configuration by entering values in the Configuration tab. After you make changes, you must validate the node by clicking on Validate at the bottom of the panel. The side panel will display validation errors, if any, or slide off the canvas if the node is validated. You must correct all validation errors before you save the PHLO.
Triggers let you manage an ongoing call. There are four types of triggers:
You can create a PHLO either by using a blank canvas or by using a packaged templates.
You can then trigger the PHLO, as we talk about below.
You can then trigger the PHLO, as we talk about below.
After you’ve added components to the PHLO canvas, you must create connections between the nodes to complete the workflow. Defining a command to a response is as simple as connecting the output state of one node to the input state of another. The output state is the command and the input state is the response.
Each node has a predefined set of output states. To connect PHLO components, on the PHLO Canvas, click and drag the output state of a node to the input state of another node. For example, here’s an IVR menu that shows the connection between output and input states.
In this example, the IVR Menu_1 node has four output states:
The IVR Menu_1 node’s No Input output state connects to the Play Audio_1 input state at the top of the node. Every node has a input state except the Start node.
Once you’ve connected all the nodes on your PHLO canvas, make sure you’ve configured the components, as we talk about in the next section.
You must configure every node to make sure the workflow works as intended. You can access a node’s Configurations tab by clicking on it on the canvas. The adjacent Information tab in the right panel explains the configuration and variables available for the node.
PHLO supports two types of variables: global variables and variables specific to components.
You configure global variables by defining key-value pairs in the Start node of the PHLO. Connect the Start node to the component in which you want to use the global variables, then use two curly brackets to view all available variables. Scroll through the list and select the variable you want to use.
Each component has a list of predefined variables that you can use. For more information on the components and their default variables and configurations, see the PHLO components library page.
After you change a node’s configuration, click Validate to make sure there are no errors in the configuration. PHLO will display a message if it finds an error.
You can trigger a PHLO with an incoming call or SMS message or with an outgoing API call. If you plan to trigger a PHLO for an incoming call or message, you must add the PHLO to a Plivo number.
If you need to buy a phone number, visit Phone Numbers on the console and click Buy Number. On this page you can search for available phone numbers based on country, type (local, national, mobile, or toll-free), and capability (voice, SMS, or MMS), then click Buy Number for the number that you want to purchase.
Once you’ve created and configured a PHLO, assign your PHLO to a number.
Make a call or send an SMS message to the phone number to test your PHLO.
Once you’ve created and configured your PHLO, copy the PHLO URL either by clicking on the button in the upper right corner above the PHLO canvas or from the list on the PHLO page of the console.
Integrate the PHLO into your application workflow by making an API request to the PHLO URL. You can trigger an API request with or without a payload depending on how the PHLO is set up. You can configure static payload values (from, to, etc.) on the PHLO console. Alternately, you can define the payload keys as Liquid templates on the PHLO console and pass the values dynamically at runtime for execution.
1
2
3
4
5
6
7
8
9
import plivo
auth_id = '<auth_id>'
auth_token = '<auth_token>'
phlo_id = '<phlo_id>'
phlo_client = plivo.phlo.RestClient(auth_id=auth_id, auth_token=auth_token)
phlo = phlo_client.phlo.get(phlo_id)
response = phlo.run()
print str(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
require 'rubygems'
require 'plivo'
include Plivo
AUTH_ID = 'AUTH_ID'
AUTH_TOKEN = 'AUTH_TOKEN'
client = Phlo.new(AUTH_ID, AUTH_TOKEN)
# if credentials are stored in the PLIVO_AUTH_ID and the PLIVO_AUTH_TOKEN environment variables
# then initialize client as:
# client = Phlo.new
begin
phlo = client.phlo.get('phlo_id')
response = phlo.run()
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var plivo = require('plivo');
var PhloClient = plivo.PhloClient;
var authId = 'auth-id';
var authToken = 'auth-token';
var phloId = 'PHLO_ID';
var phloClient = phlo = null;
phloClient = new PhloClient(authId, authToken);
phloClient.phlo(phloId).run().then(function (result) {
console.log('Phlo run result', result);
}).catch(function (err) {
console.error('Phlo run failed', err);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
/**
* Example for API request
*/
require 'vendor/autoload.php';
use Plivo\Resources\PHLO\PhloRestClient;
use Plivo\Exceptions\PlivoRestException;
$client = new PhloRestClient("<auth_id>", "<auth_token>");
$phlo = $client->phlo->get("<phlo_id>");
try {
$response = $phlo->run();
print_r($response);
} catch (PlivoRestException $ex) {
print_r($ex);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import com.plivo.api.Plivo;
import com.plivo.api.PlivoClient;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.phlo.Phlo;
import java.io.IOException;
public class Example
{
private static final String authId = "<auth_id>";
private static final String authToken = "<auth_id>";
private static PlivoClient client = new PlivoClient(authId, authToken);
public static void main(String[] args) throws IOException, PlivoRestException
{
String phloId = "<phlo_id>";
Plivo.init(authId, authToken);
Phlo phlo = Phlo.getter(phloId).client(client).get();
PhloUpdateResponse response = Phlo.updater(phloId).payload().run();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main
import (
"fmt"
"plivo-go"
)
const authId = "<auth_id>"
const authToken = "<auth_token>"
const phloId = "phlo_id"
func main() {
testPhloRunWithoutParams()
}
func testPhloRunWithoutParams() {
phloClient, err := plivo.NewPhloClient(authId, authToken, &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
phloGet, err := phloClient.Phlos.Get(phloId)
if err != nil {
fmt.Print("Error", err.Error())
return
}
response, err := phloGet.Run(nil)
if err != nil {
fmt.Print("Error", err.Error())
return
}
fmt.Printf("Response: %#v\n", response)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System;
using Plivo;
namespace test_PHLO_dotnet
{
class Program
{
public static void Main(string[] args)
{
var phloClient = new PhloApi("<auth_id>", "<auth_token>");
var phloID = "phlo_id";
var phlo = phloClient.Phlo.Get(phloID);
Console.WriteLine(phlo.Run());
}
}
}
1
2
curl -i --user AUTH_ID:AUTH_TOKEN \
https://phlorunner.plivo.com/v1/account/{auth_id}/phlo/{phlo_id}
1
2
3
4
5
6
7
8
9
10
import plivo
auth_id = '<auth_id>'
auth_token = '<auth_token>'
phlo_id = '<phlo_id>'
payload = {"from" : "+12025550000","to" : "+12025551111"}
phlo_client = plivo.phlo.RestClient(auth_id=auth_id, auth_token=auth_token)
phlo = phlo_client.phlo.get(phlo_id)
response = phlo.run(**payload)
print str(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require 'rubygems'
require 'plivo'
include Plivo
AUTH_ID = 'AUTH_ID'
AUTH_TOKEN = 'AUTH_TOKEN'
client = Phlo.new(AUTH_ID, AUTH_TOKEN)
begin
phlo = client.phlo.get('phlo_id')
#parameters set in PHLO - params
params = {
from: '9999999999',
to: '0000000000'
}
response = phlo.run(params)
puts response
rescue PlivoRESTError => e
puts 'Exception: ' + e.message
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var plivo = require('plivo');
var PhloClient = plivo.PhloClient;
var authId = 'auth-id';
var authToken = 'auth-token';
var phloId = 'PHLO_ID';
var phloClient = phlo = null;
var payload = {
from: '19999999999',
to: '18888888888'
}
phloClient = new PhloClient(authId, authToken);
phloClient.phlo(phloId).run(payload).then(function (result) {
console.log('Phlo run result', result);
}).catch(function (err) {
console.error('Phlo run failed', err);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
/**
* Example for API request
*/
require 'vendor/autoload.php';
use Plivo\Resources\PHLO\PhloRestClient;
use Plivo\Exceptions\PlivoRestException;
$client = new PhloRestClient("<auth_id>", "<auth_token>");
$phlo = $client->phlo->get("<phlo_id>");
try {
$response = $phlo->run(["field1" => "value1", "field2" => "value2"]); // These are the fields entered in the PHLO console
print_r($response);
} catch (PlivoRestException $ex) {
print_r($ex);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.plivo.api.Plivo;
import com.plivo.api.PlivoClient;
import com.plivo.api.exceptions.PlivoRestException;
import com.plivo.api.models.phlo.Phlo;
import java.io.IOException;
public class Example
{
private static final String authId = "<auth_id>";
private static final String authToken = "<auth_token>";
private static PlivoClient client = new PlivoClient(authId, authToken);
public static void main(String[] args) throws IOException, PlivoRestException
{
String phloId = "<phlo_id>";
Plivo.init(authId, authToken);
Phlo phlo = Phlo.getter(phloId).client(client).get();
Map<String, Object> payload = new HashMap<>();
payload.put("phone", "+12025550000");
payload.put("to", "+12025551111");
PhloUpdateResponse response = Phlo.updater(phloId).payload(payload).run();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main
import (
"fmt"
"plivo-go"
)
const authId = "<auth_id>"
const authToken = "<auth_token>"
const phloId = "phlo_id"
func main() {
testPhloRunWithParams()
}
func testPhloRunWithParams() {
phloClient, err := plivo.NewPhloClient(authId, authToken, &plivo.ClientOptions{})
if err != nil {
fmt.Print("Error", err.Error())
return
}
phloGet, err := phloClient.Phlos.Get(phloId)
if err != nil {
fmt.Print("Error", err.Error())
return
}
//pass corresponding from and to values
type params map[string]interface{}
response, err := phloGet.Run(params{
"from": "12025550000",
"to": "12025551111",
})
if err != nil {
println(err)
}
fmt.Printf("Response: %#v\n", response)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using Plivo;
namespace test_PHLO_dotnet
{
class Program
{
public static void Main(string[] args)
{
var phloClient = new PhloApi("<auth_id>", "<auth_token>");
var phloID = "phlo_id";
var phlo = phloClient.Phlo.Get(phloID);
var data = new Dictionary<string, object>
{
{ "from", "19999999999" },
{ "to", "18888888888" }
};
Console.WriteLine(phlo.Run(data));
}
}
}
1
2
3
4
5
curl --request POST \
--user AUTH_ID:AUTH_TOKEN \
--url 'https://phlorunner.plivo.com/v1/account/{auth_id}/phlo/{phlo_id}' \
--header 'Content-Type: application/json' \
--data '{"from": "12025550000","to": "12025551111"}'
You can get the Auth ID and Auth Token you need for this code from the overview page of the console.
You can install a server SDK to help you code, and set up a development environment.
We’ve put together some use cases guides to help you get started with some common tasks:
All of these use cases are also available as PHLO templates — predefined workflows that help you build your applications faster.