SlideShare a Scribd company logo
1 of 71
Download to read offline
Phone Calls and SMS
from PHP
PHP World 2016
David Stockton
November 16, 2016
Standard Interactions
Input
Web Pages / Forms
APIs
CLI
Output
HTML
Graphics
Documents
Reports
JSON
Console Output
Files
How else can we receive
input and produce
output?
Input:
Phone Call
Input:
SMS Message
Output:
Text Message
Output:
MMS Message
Output:
Phone Call
APIs for Phone
Interaction
Twilio SDK
composer require twilio/sdk
Let's Send an SMS
new TwilioRestClient($config['sid'], $config['token']);
Make a client
Let's Send an SMS
$client->messages->create(

$toNumber,

array(

'from' => '+1<purchased#>',

'body' => $fortune

)

);
All Together
$toNumber = $argv[1] ?? '<default #>';



$toNumber = PhpWorld
Utility::normalizeNumber($toNumber);



$fortune = $argv[2] ?? `fortune`;



$client->messages->create(

$toNumber,

array(

'from' => '+<purchased #>',

'body' => $fortune

)

);
How to Use?
$ php bin/fortune.php
$ php bin/fortune.php <destination #>
$ php bin/fortune.php <destination #> "Text
message from the command line"
php bin/fortune.php
php bin/fortune.php 7206757471
php bin/fortune.php 7206757471 "Your account has been created or something."
What can we do?
• Notifications
• Two-Factor Authentication (2FA)
• Responses to Queries
Make a Phone Call
• API Call to Twitter
• Twitter contacts URL for instructions
TwiML
• Twilio's Markup Language for controlling phone
calls
• XML
TwiML Commands
• Say - Read text to the caller
• Play - Play an audio file for the caller
• Dial - Add another party to the call
• Record - Record the caller's voice
• Gather - Collect digits the caller types on their keypad
• Sms - Send an SMS message during a phone call
More TwiML
• Hangup - Hang up the call
• Queue - Add the caller to a queue of callers.
• Redirect - Redirect call flow to a different TwiML
document.
• Pause - Wait before executing more instructions
• Reject - Decline an incoming call without being billed.
• Message - Send an MMS or SMS message reply
How Outgoing Calls Work
Your App TwilioAPI Call
TwiML
CalleeTwilio Plays Twiml
TwiML
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="woman">Your call is very

important to us, but not so

important we'll answer it with

a human. Please leave a message.

</Say>

<Record maxLength="20" playBeep="true"/>

</Response>
XML
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="woman">Your call is very

important to us, but not so

important we'll answer it with

a human. Please leave a message.

</Say>

<Record maxLength="20" playBeep="true"/>

</Response>
Root Element
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="woman">Your call is very

important to us, but not so

important we'll answer it with

a human. Please leave a message.

</Say>

<Record maxLength="20" playBeep="true"/>

</Response>
Commands - Say
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="woman">Your call is very

important to us, but not so

important we'll answer it with

a human. Please leave a message.

</Say>

<Record maxLength="20" playBeep="true"/>

</Response>
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="woman">Your call is very

important to us, but not so

important we'll answer it with

a human. Please leave a message.

</Say>

<Record maxLength="20" playBeep="true"/>

</Response>
Commands - Record
Configure Twilio
Let's Make a Call
<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="man">

Due to inclement weather, school

will be closed tomorrow. Please

stay home and stay safe.

</Say>

</Response>
The Full File
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say voice="man" loop="2">

Due to inclement weather, school

will be closed tomorrow. Please

stay home and stay safe.

</Say>

</Response>
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Tell Twilio Who To Call
<?php

require_once __DIR__ . '/../vendor/autoload.php';

/** @var TwilioRestClient $client */

$client = require_once __DIR__ . '/../src/PhpWorld/client.php';



$to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');

$from = '+<purchased #>';



$options = [

'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/
school_outage.php',

];



$client->calls->create($to, $from, $options);
Phone and SMS
Conversations
• Twilio is like a well-behaved HTTP client
• It uses sessions
• We can use session to remember things about the
caller or the conversation
Phone IVR
• Give callers a menu
• Look up information
• Connect to people
• Solve problems
• Give answers
First TwiML
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say>

Thanks for calling my demo IVR. Please

listen closely as this is the first time

you've heard this menu.

</Say>

<Gather numDigits="1" action="/twiml/process_ivr_menu.php">

<Say>

Press 1 to hear a random sound.

Press 2 to connect to a conference call.

Press 3 to hear some wisdom.

Press 4 to be connected to support.

</Say>

</Gather>

<Say>

I don't understand. Please try again later.

</Say>

<Hangup/>

</Response>
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say>

Thanks for calling my demo IVR. Please

listen closely as this is the first time

you've heard this menu.

</Say>

<Gather numDigits="1" action="/twiml/process_ivr_menu.php">

<Say>

Press 1 to hear a random sound.

Press 2 to connect to a conference call.

Press 3 to hear some wisdom.

Press 4 to be connected to support.

</Say>

</Gather>

<Say>

I don't understand. Please try again later.

</Say>

<Hangup/>

</Response>
Greeting
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say>

Thanks for calling my demo IVR. Please

listen closely as this is the first time

you've heard this menu.

</Say>

<Gather numDigits="1" action="/twiml/process_ivr_menu.php">

<Say>

Press 1 to hear a random sound.

Press 2 to connect to a conference call.

Press 3 to hear some wisdom.

Press 4 to be connected to support.

</Say>

</Gather>

<Say>

I don't understand. Please try again later.

</Say>

<Hangup/>

</Response>
Menu
Error Handling
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say>

Thanks for calling my demo IVR. Please

listen closely as this is the first time

you've heard this menu.

</Say>

<Gather numDigits="1" action="/twiml/process_ivr_menu.php">

<Say>

Press 1 to hear a random sound.

Press 2 to connect to a conference call.

Press 3 to hear some wisdom.

Press 4 to be connected to support.

</Say>

</Gather>

<Say>

I don't understand. Please try again later.

</Say>

<Hangup/>

</Response>
Goodbye.
<?php header('Content-Type: text/xml'); ?>

<?xml version="1.0" encoding="UTF-8"?>

<Response>

<Say>

Thanks for calling my demo IVR. Please

listen closely as this is the first time

you've heard this menu.

</Say>

<Gather numDigits="1" action="/twiml/process_ivr_menu.php">

<Say>

Press 1 to hear a random sound.

Press 2 to connect to a conference call.

Press 3 to hear some wisdom.

Press 4 to be connected to support.

</Say>

</Gather>

<Say>

I don't understand. Please try again later.

</Say>

<Hangup/>

</Response>
Now What?
• What if they press something that's not 1-4?
• What if they press 1-4?
• Need to figure out what to do next
Handle ! 1-4
<?php

require_once __DIR__ . '/../vendor/autoload.php';

session_start();

$digits = $_POST['Digits'] ?? 0;



switch ($digits) {

case 1: // Random sound

case 2: // Conference call

case 3: // Random Phrase

case 4: // Support queue

default:

if (countFailures() >= 3) {

echo bailOnCall();

return;

}

echo badInput();

return;

}
countFailures()
function countFailures($count = null)

{

$badInput = $count ?? $_SESSION[__FUNCTION__] ?? 0;

$badInput++;

$_SESSION[__FUNCTION__] = $badInput;

return $badInput;

}
badInput()
function badInput()

{

header('Content-type: text/xml');

$twiml = new TwilioTwiml();

$twiml->say('That was not a valid selection.');

$twiml->redirect('/twiml/ivr_menu.php');

return $twiml;

}
bailOnCall()
function bailOnCall()

{

header('Content-type: text/xml');

$twiml = new TwilioTwiml();

$twiml->say('Your rotary phone is not compatible
with this app.');

$twiml->say('Goodbye.');

$twiml->hangup();

return $twiml;

}
Call Handler
switch ($digits) {

case 1: // Random sound

echo randomSound();

break;

case 2: // Conference call

echo conferenceCall();

break;

case 3: // Random Phrase

echo fortune();

break;

case 4: // Support queue

echo supportQueue();

break;

default:

...
}
randomSound()
function randomSound()

{

header('Content-type: text/xml');

countFailures(-1);

$sounds = ['gull.mp3', 'lawnmower.mp3',

'monkey.mp3'];

$index = array_rand($sounds);

$twiml = new TwilioTwiml();

$twiml->play('/sounds/' . $sounds[$index]);

$twiml->redirect('/twiml/ivr_menu.php');

return $twiml;

}
Conference Call
function conferenceCall()

{

header('Content-type: text/xml');

$response = new TwilioTwiml();

$response->say('You have joined the conference.');

$dial = $response->dial();

$dial->conference('PHP World');

return $response;

}
fortune()
function fortune()

{

$fortune = `fortune -s`;

header('Content-type: text/xml');

$response = new TwilioTwiml();

$response->sms($fortune);

$response->say($fortune);

return $response;

}
supportQueue()
function supportQueue()

{

header('Content-type: text/xml');

$response = new TwilioTwiml();

if ($_POST['From'] == '<my number>') {

// Support agent

$dial = $response->dial();

$dial->queue('support', ['url' => '/twiml/about_to_connect.php']);

} else {

// Enqueue

$response->enqueue('support');

}



return $response;

}
supportQueue()
function supportQueue()

{

header('Content-type: text/xml');

$response = new TwilioTwiml();

if ($_POST['From'] == '<my number>') {

// Support agent

$dial = $response->dial();

$dial->queue('support', ['url' => '/twiml/about_to_connect.php']);

} else {

// Enqueue

$response->enqueue('support');

}



return $response;

}
Just Scratching the Surface
• Twilio can keep our application informed about
how calls are going
• We can interact with ongoing calls via the REST
API
Questions?
• Twitter: @dstockto
• Joind.in - https://joind.in/talk/e2e2b
20162016

More Related Content

What's hot

What's hot (20)

PHP an intro -1
PHP an intro -1PHP an intro -1
PHP an intro -1
 
Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?
 
Inside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in OmekaInside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in Omeka
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Php Security
Php SecurityPhp Security
Php Security
 
PHP Security
PHP SecurityPHP Security
PHP Security
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
P H P Part I I, By Kian
P H P  Part  I I,  By  KianP H P  Part  I I,  By  Kian
P H P Part I I, By Kian
 
New in php 7
New in php 7New in php 7
New in php 7
 
Top 10 php classic traps php serbia
Top 10 php classic traps php serbiaTop 10 php classic traps php serbia
Top 10 php classic traps php serbia
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
PHP Security
PHP SecurityPHP Security
PHP Security
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
PHP, RabbitMQ, and You
PHP, RabbitMQ, and YouPHP, RabbitMQ, and You
PHP, RabbitMQ, and You
 
Session1+2
Session1+2Session1+2
Session1+2
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire player
 

Viewers also liked

php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHPphp[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHPAdam Englander
 
IoT Lock Down - Battling the Bot Net Builders
IoT Lock Down - Battling the Bot Net BuildersIoT Lock Down - Battling the Bot Net Builders
IoT Lock Down - Battling the Bot Net BuildersAdam Englander
 
SunshinePHP 2017: Tales From The Crypt - A Cryptography Primer
SunshinePHP 2017: Tales From The Crypt - A Cryptography PrimerSunshinePHP 2017: Tales From The Crypt - A Cryptography Primer
SunshinePHP 2017: Tales From The Crypt - A Cryptography PrimerAdam Englander
 
PHP UK 2017 - Don't Lose Sleep - Secure Your REST
PHP UK 2017 - Don't Lose Sleep - Secure Your RESTPHP UK 2017 - Don't Lose Sleep - Secure Your REST
PHP UK 2017 - Don't Lose Sleep - Secure Your RESTAdam Englander
 
Node.js interactive NA 2016: Tales From the Crypt
Node.js interactive NA 2016: Tales From the CryptNode.js interactive NA 2016: Tales From the Crypt
Node.js interactive NA 2016: Tales From the CryptAdam Englander
 
Zend con 2016 - Asynchronous Prorgamming in PHP
Zend con 2016 - Asynchronous Prorgamming in PHPZend con 2016 - Asynchronous Prorgamming in PHP
Zend con 2016 - Asynchronous Prorgamming in PHPAdam Englander
 
php[world] 2016 - Tales From the Crypto: A Cryptography Primer
php[world] 2016 - Tales From the Crypto: A Cryptography Primerphp[world] 2016 - Tales From the Crypto: A Cryptography Primer
php[world] 2016 - Tales From the Crypto: A Cryptography PrimerAdam Englander
 
Py Vegas - Tales from the crypt
Py Vegas - Tales from the cryptPy Vegas - Tales from the crypt
Py Vegas - Tales from the cryptAdam Englander
 
All the Laravel Things – Up & Running to Making $$
All the Laravel Things – Up & Running to Making $$All the Laravel Things – Up & Running to Making $$
All the Laravel Things – Up & Running to Making $$Joe Ferguson
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingSteve Rhoades
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...James Titcumb
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground UpJoe Ferguson
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework FoundationsChuck Reeves
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pagesRobert McFrazier
 

Viewers also liked (20)

php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHPphp[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
 
IoT Lock Down - Battling the Bot Net Builders
IoT Lock Down - Battling the Bot Net BuildersIoT Lock Down - Battling the Bot Net Builders
IoT Lock Down - Battling the Bot Net Builders
 
SunshinePHP 2017: Tales From The Crypt - A Cryptography Primer
SunshinePHP 2017: Tales From The Crypt - A Cryptography PrimerSunshinePHP 2017: Tales From The Crypt - A Cryptography Primer
SunshinePHP 2017: Tales From The Crypt - A Cryptography Primer
 
PHP UK 2017 - Don't Lose Sleep - Secure Your REST
PHP UK 2017 - Don't Lose Sleep - Secure Your RESTPHP UK 2017 - Don't Lose Sleep - Secure Your REST
PHP UK 2017 - Don't Lose Sleep - Secure Your REST
 
Node.js interactive NA 2016: Tales From the Crypt
Node.js interactive NA 2016: Tales From the CryptNode.js interactive NA 2016: Tales From the Crypt
Node.js interactive NA 2016: Tales From the Crypt
 
Zend con 2016 - Asynchronous Prorgamming in PHP
Zend con 2016 - Asynchronous Prorgamming in PHPZend con 2016 - Asynchronous Prorgamming in PHP
Zend con 2016 - Asynchronous Prorgamming in PHP
 
php[world] 2016 - Tales From the Crypto: A Cryptography Primer
php[world] 2016 - Tales From the Crypto: A Cryptography Primerphp[world] 2016 - Tales From the Crypto: A Cryptography Primer
php[world] 2016 - Tales From the Crypto: A Cryptography Primer
 
Python Bluetooth
Python BluetoothPython Bluetooth
Python Bluetooth
 
IoT Lockdown
IoT LockdownIoT Lockdown
IoT Lockdown
 
Py Vegas - Tales from the crypt
Py Vegas - Tales from the cryptPy Vegas - Tales from the crypt
Py Vegas - Tales from the crypt
 
Travis CI - PHP
Travis CI - PHPTravis CI - PHP
Travis CI - PHP
 
All the Laravel Things – Up & Running to Making $$
All the Laravel Things – Up & Running to Making $$All the Laravel Things – Up & Running to Making $$
All the Laravel Things – Up & Running to Making $$
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
 
Engineer - Mastering the Art of Software
Engineer - Mastering the Art of SoftwareEngineer - Mastering the Art of Software
Engineer - Mastering the Art of Software
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Up
 
Hack the Future
Hack the FutureHack the Future
Hack the Future
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework Foundations
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pages
 

Similar to Phone calls and sms from php

Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-KjaerCOMMON Europe
 
Programming For Designers V3
Programming For Designers V3Programming For Designers V3
Programming For Designers V3sqoo
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con RailsSvet Ivantchev
 
East Bay Ruby Tropo presentation
East Bay Ruby Tropo presentationEast Bay Ruby Tropo presentation
East Bay Ruby Tropo presentationAdam Kalsey
 
HackU PHP and Node.js
HackU PHP and Node.jsHackU PHP and Node.js
HackU PHP and Node.jssouridatta
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | BasicsShubham Kumar Singh
 
Learning of Php and My SQL Tutorial | For Beginners
Learning of Php and My SQL Tutorial | For BeginnersLearning of Php and My SQL Tutorial | For Beginners
Learning of Php and My SQL Tutorial | For BeginnersRatnesh Pandey
 
2015 ZendCon - Do you queue
2015 ZendCon - Do you queue2015 ZendCon - Do you queue
2015 ZendCon - Do you queueMike Willbanks
 
Esplorando Google Assistant e Dialogflow
Esplorando Google Assistant e DialogflowEsplorando Google Assistant e Dialogflow
Esplorando Google Assistant e DialogflowPaolo Montrasio
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GooglePeter Friese
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 

Similar to Phone calls and sms from php (20)

Look Who's Talking
Look Who's TalkingLook Who's Talking
Look Who's Talking
 
Ruby on the Phone
Ruby on the PhoneRuby on the Phone
Ruby on the Phone
 
Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-Kjaer
 
Programming For Designers V3
Programming For Designers V3Programming For Designers V3
Programming For Designers V3
 
Interface de Voz con Rails
Interface de Voz con RailsInterface de Voz con Rails
Interface de Voz con Rails
 
East Bay Ruby Tropo presentation
East Bay Ruby Tropo presentationEast Bay Ruby Tropo presentation
East Bay Ruby Tropo presentation
 
HackU PHP and Node.js
HackU PHP and Node.jsHackU PHP and Node.js
HackU PHP and Node.js
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Php101
Php101Php101
Php101
 
Php mysql
Php mysqlPhp mysql
Php mysql
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | Basics
 
Php My SQL Tutorial | beginning
Php My SQL Tutorial | beginningPhp My SQL Tutorial | beginning
Php My SQL Tutorial | beginning
 
Learning of Php and My SQL Tutorial | For Beginners
Learning of Php and My SQL Tutorial | For BeginnersLearning of Php and My SQL Tutorial | For Beginners
Learning of Php and My SQL Tutorial | For Beginners
 
CakePHP workshop
CakePHP workshopCakePHP workshop
CakePHP workshop
 
2015 ZendCon - Do you queue
2015 ZendCon - Do you queue2015 ZendCon - Do you queue
2015 ZendCon - Do you queue
 
Esplorando Google Assistant e Dialogflow
Esplorando Google Assistant e DialogflowEsplorando Google Assistant e Dialogflow
Esplorando Google Assistant e Dialogflow
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 

More from David Stockton

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of TransductionDavid Stockton
 
Using queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your applicationUsing queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your applicationDavid Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid Stockton
 
Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2David Stockton
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHPDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid Stockton
 
Common design patterns in php
Common design patterns in phpCommon design patterns in php
Common design patterns in phpDavid Stockton
 
Intermediate oop in php
Intermediate oop in phpIntermediate oop in php
Intermediate oop in phpDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid Stockton
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profitDavid Stockton
 
Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)David Stockton
 
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSHTame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSHDavid Stockton
 
Mercurial Distributed Version Control
Mercurial Distributed Version ControlMercurial Distributed Version Control
Mercurial Distributed Version ControlDavid Stockton
 
Regular expressions and php
Regular expressions and phpRegular expressions and php
Regular expressions and phpDavid Stockton
 

More from David Stockton (19)

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of Transduction
 
Using queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your applicationUsing queues and offline processing to help speed up your application
Using queues and offline processing to help speed up your application
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2Building APIs with Apigilty and Zend Framework 2
Building APIs with Apigilty and Zend Framework 2
 
API All the Things!
API All the Things!API All the Things!
API All the Things!
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Beginning OOP in PHP
Beginning OOP in PHPBeginning OOP in PHP
Beginning OOP in PHP
 
Common design patterns in php
Common design patterns in phpCommon design patterns in php
Common design patterns in php
 
Intermediate oop in php
Intermediate oop in phpIntermediate oop in php
Intermediate oop in php
 
Grokking regex
Grokking regexGrokking regex
Grokking regex
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Hacking sites for fun and profit
Hacking sites for fun and profitHacking sites for fun and profit
Hacking sites for fun and profit
 
Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)Increasing code quality with code reviews (poetry version)
Increasing code quality with code reviews (poetry version)
 
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSHTame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH
 
Mercurial Distributed Version Control
Mercurial Distributed Version ControlMercurial Distributed Version Control
Mercurial Distributed Version Control
 
Regular expressions and php
Regular expressions and phpRegular expressions and php
Regular expressions and php
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic Methods
 
FireBug And FirePHP
FireBug And FirePHPFireBug And FirePHP
FireBug And FirePHP
 

Recently uploaded

ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxiammrhaywood
 
Meghan Sutherland In Media Res Media Component
Meghan Sutherland In Media Res Media ComponentMeghan Sutherland In Media Res Media Component
Meghan Sutherland In Media Res Media ComponentInMediaRes1
 
How to Configure Email Server in Odoo 17
How to Configure Email Server in Odoo 17How to Configure Email Server in Odoo 17
How to Configure Email Server in Odoo 17Celine George
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for BeginnersSabitha Banu
 
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxRaymartEstabillo3
 
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfEnzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfSumit Tiwari
 
Biting mechanism of poisonous snakes.pdf
Biting mechanism of poisonous snakes.pdfBiting mechanism of poisonous snakes.pdf
Biting mechanism of poisonous snakes.pdfadityarao40181
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxthorishapillay1
 
भारत-रोम व्यापार.pptx, Indo-Roman Trade,
भारत-रोम व्यापार.pptx, Indo-Roman Trade,भारत-रोम व्यापार.pptx, Indo-Roman Trade,
भारत-रोम व्यापार.pptx, Indo-Roman Trade,Virag Sontakke
 
DATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersDATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersSabitha Banu
 
Hierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementHierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementmkooblal
 
Crayon Activity Handout For the Crayon A
Crayon Activity Handout For the Crayon ACrayon Activity Handout For the Crayon A
Crayon Activity Handout For the Crayon AUnboundStockton
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationnomboosow
 
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17Incoming and Outgoing Shipments in 1 STEP Using Odoo 17
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17Celine George
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatYousafMalik24
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceSamikshaHamane
 

Recently uploaded (20)

Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
 
Meghan Sutherland In Media Res Media Component
Meghan Sutherland In Media Res Media ComponentMeghan Sutherland In Media Res Media Component
Meghan Sutherland In Media Res Media Component
 
How to Configure Email Server in Odoo 17
How to Configure Email Server in Odoo 17How to Configure Email Server in Odoo 17
How to Configure Email Server in Odoo 17
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for Beginners
 
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptxEPANDING THE CONTENT OF AN OUTLINE using notes.pptx
EPANDING THE CONTENT OF AN OUTLINE using notes.pptx
 
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdfEnzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
Enzyme, Pharmaceutical Aids, Miscellaneous Last Part of Chapter no 5th.pdf
 
Biting mechanism of poisonous snakes.pdf
Biting mechanism of poisonous snakes.pdfBiting mechanism of poisonous snakes.pdf
Biting mechanism of poisonous snakes.pdf
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptx
 
ESSENTIAL of (CS/IT/IS) class 06 (database)
ESSENTIAL of (CS/IT/IS) class 06 (database)ESSENTIAL of (CS/IT/IS) class 06 (database)
ESSENTIAL of (CS/IT/IS) class 06 (database)
 
भारत-रोम व्यापार.pptx, Indo-Roman Trade,
भारत-रोम व्यापार.pptx, Indo-Roman Trade,भारत-रोम व्यापार.pptx, Indo-Roman Trade,
भारत-रोम व्यापार.pptx, Indo-Roman Trade,
 
DATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginnersDATA STRUCTURE AND ALGORITHM for beginners
DATA STRUCTURE AND ALGORITHM for beginners
 
Hierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of managementHierarchy of management that covers different levels of management
Hierarchy of management that covers different levels of management
 
9953330565 Low Rate Call Girls In Rohini Delhi NCR
9953330565 Low Rate Call Girls In Rohini  Delhi NCR9953330565 Low Rate Call Girls In Rohini  Delhi NCR
9953330565 Low Rate Call Girls In Rohini Delhi NCR
 
OS-operating systems- ch04 (Threads) ...
OS-operating systems- ch04 (Threads) ...OS-operating systems- ch04 (Threads) ...
OS-operating systems- ch04 (Threads) ...
 
Crayon Activity Handout For the Crayon A
Crayon Activity Handout For the Crayon ACrayon Activity Handout For the Crayon A
Crayon Activity Handout For the Crayon A
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communication
 
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17Incoming and Outgoing Shipments in 1 STEP Using Odoo 17
Incoming and Outgoing Shipments in 1 STEP Using Odoo 17
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice great
 
Roles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in PharmacovigilanceRoles & Responsibilities in Pharmacovigilance
Roles & Responsibilities in Pharmacovigilance
 

Phone calls and sms from php

  • 1. Phone Calls and SMS from PHP PHP World 2016 David Stockton November 16, 2016
  • 4. Web Pages / Forms
  • 6. CLI
  • 12. JSON
  • 14. Files
  • 15. How else can we receive input and produce output?
  • 22.
  • 24. Let's Send an SMS new TwilioRestClient($config['sid'], $config['token']); Make a client
  • 25. Let's Send an SMS $client->messages->create(
 $toNumber,
 array(
 'from' => '+1<purchased#>',
 'body' => $fortune
 )
 );
  • 26. All Together $toNumber = $argv[1] ?? '<default #>';
 
 $toNumber = PhpWorld Utility::normalizeNumber($toNumber);
 
 $fortune = $argv[2] ?? `fortune`;
 
 $client->messages->create(
 $toNumber,
 array(
 'from' => '+<purchased #>',
 'body' => $fortune
 )
 );
  • 27. How to Use? $ php bin/fortune.php $ php bin/fortune.php <destination #> $ php bin/fortune.php <destination #> "Text message from the command line"
  • 30. php bin/fortune.php 7206757471 "Your account has been created or something."
  • 31. What can we do? • Notifications • Two-Factor Authentication (2FA) • Responses to Queries
  • 32. Make a Phone Call • API Call to Twitter • Twitter contacts URL for instructions
  • 33. TwiML • Twilio's Markup Language for controlling phone calls • XML
  • 34. TwiML Commands • Say - Read text to the caller • Play - Play an audio file for the caller • Dial - Add another party to the call • Record - Record the caller's voice • Gather - Collect digits the caller types on their keypad • Sms - Send an SMS message during a phone call
  • 35. More TwiML • Hangup - Hang up the call • Queue - Add the caller to a queue of callers. • Redirect - Redirect call flow to a different TwiML document. • Pause - Wait before executing more instructions • Reject - Decline an incoming call without being billed. • Message - Send an MMS or SMS message reply
  • 36. How Outgoing Calls Work Your App TwilioAPI Call TwiML CalleeTwilio Plays Twiml
  • 37. TwiML <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="woman">Your call is very
 important to us, but not so
 important we'll answer it with
 a human. Please leave a message.
 </Say>
 <Record maxLength="20" playBeep="true"/>
 </Response>
  • 38. XML <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="woman">Your call is very
 important to us, but not so
 important we'll answer it with
 a human. Please leave a message.
 </Say>
 <Record maxLength="20" playBeep="true"/>
 </Response>
  • 39. Root Element <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="woman">Your call is very
 important to us, but not so
 important we'll answer it with
 a human. Please leave a message.
 </Say>
 <Record maxLength="20" playBeep="true"/>
 </Response>
  • 40. Commands - Say <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="woman">Your call is very
 important to us, but not so
 important we'll answer it with
 a human. Please leave a message.
 </Say>
 <Record maxLength="20" playBeep="true"/>
 </Response>
  • 41. <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="woman">Your call is very
 important to us, but not so
 important we'll answer it with
 a human. Please leave a message.
 </Say>
 <Record maxLength="20" playBeep="true"/>
 </Response> Commands - Record
  • 43. Let's Make a Call <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="man">
 Due to inclement weather, school
 will be closed tomorrow. Please
 stay home and stay safe.
 </Say>
 </Response>
  • 44. The Full File <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say voice="man" loop="2">
 Due to inclement weather, school
 will be closed tomorrow. Please
 stay home and stay safe.
 </Say>
 </Response>
  • 45. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 46. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 47. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 48. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 49. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 50. Tell Twilio Who To Call <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 /** @var TwilioRestClient $client */
 $client = require_once __DIR__ . '/../src/PhpWorld/client.php';
 
 $to = PhpWorldUtility::normalizeNumber($argv[1] ?? '+<default #>');
 $from = '+<purchased #>';
 
 $options = [
 'url' => 'http://' . $_SERVER['HTTP_HOST'] . '/twiml/ school_outage.php',
 ];
 
 $client->calls->create($to, $from, $options);
  • 51. Phone and SMS Conversations • Twilio is like a well-behaved HTTP client • It uses sessions • We can use session to remember things about the caller or the conversation
  • 52. Phone IVR • Give callers a menu • Look up information • Connect to people • Solve problems • Give answers
  • 53. First TwiML <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say>
 Thanks for calling my demo IVR. Please
 listen closely as this is the first time
 you've heard this menu.
 </Say>
 <Gather numDigits="1" action="/twiml/process_ivr_menu.php">
 <Say>
 Press 1 to hear a random sound.
 Press 2 to connect to a conference call.
 Press 3 to hear some wisdom.
 Press 4 to be connected to support.
 </Say>
 </Gather>
 <Say>
 I don't understand. Please try again later.
 </Say>
 <Hangup/>
 </Response>
  • 54. <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say>
 Thanks for calling my demo IVR. Please
 listen closely as this is the first time
 you've heard this menu.
 </Say>
 <Gather numDigits="1" action="/twiml/process_ivr_menu.php">
 <Say>
 Press 1 to hear a random sound.
 Press 2 to connect to a conference call.
 Press 3 to hear some wisdom.
 Press 4 to be connected to support.
 </Say>
 </Gather>
 <Say>
 I don't understand. Please try again later.
 </Say>
 <Hangup/>
 </Response> Greeting
  • 55. <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say>
 Thanks for calling my demo IVR. Please
 listen closely as this is the first time
 you've heard this menu.
 </Say>
 <Gather numDigits="1" action="/twiml/process_ivr_menu.php">
 <Say>
 Press 1 to hear a random sound.
 Press 2 to connect to a conference call.
 Press 3 to hear some wisdom.
 Press 4 to be connected to support.
 </Say>
 </Gather>
 <Say>
 I don't understand. Please try again later.
 </Say>
 <Hangup/>
 </Response> Menu
  • 56. Error Handling <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say>
 Thanks for calling my demo IVR. Please
 listen closely as this is the first time
 you've heard this menu.
 </Say>
 <Gather numDigits="1" action="/twiml/process_ivr_menu.php">
 <Say>
 Press 1 to hear a random sound.
 Press 2 to connect to a conference call.
 Press 3 to hear some wisdom.
 Press 4 to be connected to support.
 </Say>
 </Gather>
 <Say>
 I don't understand. Please try again later.
 </Say>
 <Hangup/>
 </Response>
  • 57. Goodbye. <?php header('Content-Type: text/xml'); ?>
 <?xml version="1.0" encoding="UTF-8"?>
 <Response>
 <Say>
 Thanks for calling my demo IVR. Please
 listen closely as this is the first time
 you've heard this menu.
 </Say>
 <Gather numDigits="1" action="/twiml/process_ivr_menu.php">
 <Say>
 Press 1 to hear a random sound.
 Press 2 to connect to a conference call.
 Press 3 to hear some wisdom.
 Press 4 to be connected to support.
 </Say>
 </Gather>
 <Say>
 I don't understand. Please try again later.
 </Say>
 <Hangup/>
 </Response>
  • 58. Now What? • What if they press something that's not 1-4? • What if they press 1-4? • Need to figure out what to do next
  • 59. Handle ! 1-4 <?php
 require_once __DIR__ . '/../vendor/autoload.php';
 session_start();
 $digits = $_POST['Digits'] ?? 0;
 
 switch ($digits) {
 case 1: // Random sound
 case 2: // Conference call
 case 3: // Random Phrase
 case 4: // Support queue
 default:
 if (countFailures() >= 3) {
 echo bailOnCall();
 return;
 }
 echo badInput();
 return;
 }
  • 60. countFailures() function countFailures($count = null)
 {
 $badInput = $count ?? $_SESSION[__FUNCTION__] ?? 0;
 $badInput++;
 $_SESSION[__FUNCTION__] = $badInput;
 return $badInput;
 }
  • 61. badInput() function badInput()
 {
 header('Content-type: text/xml');
 $twiml = new TwilioTwiml();
 $twiml->say('That was not a valid selection.');
 $twiml->redirect('/twiml/ivr_menu.php');
 return $twiml;
 }
  • 62. bailOnCall() function bailOnCall()
 {
 header('Content-type: text/xml');
 $twiml = new TwilioTwiml();
 $twiml->say('Your rotary phone is not compatible with this app.');
 $twiml->say('Goodbye.');
 $twiml->hangup();
 return $twiml;
 }
  • 63. Call Handler switch ($digits) {
 case 1: // Random sound
 echo randomSound();
 break;
 case 2: // Conference call
 echo conferenceCall();
 break;
 case 3: // Random Phrase
 echo fortune();
 break;
 case 4: // Support queue
 echo supportQueue();
 break;
 default:
 ... }
  • 64. randomSound() function randomSound()
 {
 header('Content-type: text/xml');
 countFailures(-1);
 $sounds = ['gull.mp3', 'lawnmower.mp3',
 'monkey.mp3'];
 $index = array_rand($sounds);
 $twiml = new TwilioTwiml();
 $twiml->play('/sounds/' . $sounds[$index]);
 $twiml->redirect('/twiml/ivr_menu.php');
 return $twiml;
 }
  • 65. Conference Call function conferenceCall()
 {
 header('Content-type: text/xml');
 $response = new TwilioTwiml();
 $response->say('You have joined the conference.');
 $dial = $response->dial();
 $dial->conference('PHP World');
 return $response;
 }
  • 66. fortune() function fortune()
 {
 $fortune = `fortune -s`;
 header('Content-type: text/xml');
 $response = new TwilioTwiml();
 $response->sms($fortune);
 $response->say($fortune);
 return $response;
 }
  • 67. supportQueue() function supportQueue()
 {
 header('Content-type: text/xml');
 $response = new TwilioTwiml();
 if ($_POST['From'] == '<my number>') {
 // Support agent
 $dial = $response->dial();
 $dial->queue('support', ['url' => '/twiml/about_to_connect.php']);
 } else {
 // Enqueue
 $response->enqueue('support');
 }
 
 return $response;
 }
  • 68. supportQueue() function supportQueue()
 {
 header('Content-type: text/xml');
 $response = new TwilioTwiml();
 if ($_POST['From'] == '<my number>') {
 // Support agent
 $dial = $response->dial();
 $dial->queue('support', ['url' => '/twiml/about_to_connect.php']);
 } else {
 // Enqueue
 $response->enqueue('support');
 }
 
 return $response;
 }
  • 69. Just Scratching the Surface • Twilio can keep our application informed about how calls are going • We can interact with ongoing calls via the REST API
  • 70. Questions? • Twitter: @dstockto • Joind.in - https://joind.in/talk/e2e2b