PHLO

Overview

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.

PHLO terminology

Canvas

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.

Component

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.

Node

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

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.

Configuration and Information tabs

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

Triggers let you manage an ongoing call. There are four types of triggers:

  • Call
  • Hold
  • Transfer
  • Hangup

Creating PHLOs

You can create a PHLO either by using a blank canvas or by using a packaged templates.

Building a PHLO using a blank canvas

  1. In the Plivo console, click the PHLO icon. The PHLO page will appear and display your existing PHLOs. If you’re creating your first PHLO, the PHLO page will be empty.
  2. Click the Create New PHLO button to start building a new PHLO.
  3. In the Choose your use case window, click Build my own. The PHLO canvas will appear with the Start node. Note: The Start node is the starting point of any PHLO. It lets you trigger the start of a workflow with either an incoming SMS message or voice call or an API request.
  4. From the Components list at the left, drag and drop a component onto the canvas to create a new node. The Configurations tab will appear — see Configuring PHLO components.
  5. Click Validate to save the configurations for the node.
  6. Drag more components onto the canvas as appropriate. Connect nodes in a logical sequence. For more information, see Connecting PHLO components.
  7. Enter a unique name for the PHLO, then click Save.

You can then trigger the PHLO, as we talk about below.

Building a PHLO using a template

  1. In the Plivo console, click the PHLO icon. The PHLO page will appear and display your existing PHLOs. If you’re creating your first PHLO, the PHLO page will be empty.
  2. Click the CREATE NEW PHLO button to start building a new PHLO.
  3. In the Choose your use case window, select one of the available templates. The PHLO canvas will appear with all of the nodes that are part of the use case connected appropriately.
  4. If you need to add more steps to the workflow, then from the Components list at the left drag and drop a component onto the canvas to create a new node. Each time you add a node the Configurations tab will appear — see Configuring PHLO components.
  5. Connect nodes in a logical sequence. For more information, see Connecting PHLO components.
  6. Enter a unique name for the PHLO, then click Save.

You can then trigger the PHLO, as we talk about below.

Connecting PHLO components

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.

Example

In this example, the IVR Menu_1 node has four output states:

  • No Input
  • Wrong Input
  • 1
  • 2

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.

Configuring PHLO components

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.

Global variables

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.

Variables specific to components

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.

Triggering a PHLO

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.

Triggering a PHLO using a phone number

Once you’ve created and configured a PHLO, assign your PHLO to a number.

  1. Visit Phone Numbers on the console.
  2. On the Numbers page, under Your Numbers, click the phone number you want to use for the PHLO.
  3. In the Number Configuration section, select PHLO  from the application type drop-down list.
  4. From the PHLO Name drop-down list, select the PHLO you want to use with the phone number.
  5. Click on Update Number.

Make a call or send an SMS message to the phone number to test your PHLO.

Triggering a PHLO using an API request

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.

PHLO ListingIntegrate 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.

Code sample — without payload

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}

Code sample — with payload

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.

AuthID

You can install a server SDK to help you code, and set up a development environment.

Use case guides

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.