The Phone client wraps the phone section of 46elks.se docs
- Dispatcher
- Receiver
- Phone actions (Incoming and outgoing)
- Phone router (Incoming and outgoing)
- History
The dispatcher service handles outgoing phone calls. This is how you access the phone dispatcher
use Tarre\Php46Elks\Client as Php46ElkClient;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$phone = $Php46ElksClient->phone()->dispatcher();To make an outgoing phonecall you need a valid number with VOICE support, you can get this number from 46elks control panel.
use Tarre\Php46Elks\Client as Php46ElkClient;
use Tarre\Php46Elks\Clients\PhoneCall\Resources\PhoneCallAction;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$phone = $Php46ElksClient->phone()->dispatcher();
$phone
// set outgoing number (Must be a valid VOICE enabled e164 number from 46elks dashboard)
->from('+467147147417')
// Set recipeient
->recipient('+4671928398')
// When the accepts the call, play a file and hang up
->voiceStart(function(PhoneCallAction $action){
return $action
->play('http://yourapp.com/wav/hello.wav')
->hangUp();
});You can use the setRecipients method to make multiple outgoing calls in one fell swoop, all calls will be async.
use Tarre\Php46Elks\Client as Php46ElkClient;
use Tarre\Php46Elks\Clients\PhoneCall\Resources\PhoneCallAction;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$phone = $Php46ElksClient->phone()->dispatcher();
$phone
// set outgoing number (Must be a valid VOICE enabled e164 number from 46elks dashboard)
->from('+467147147417')
// Set recipeient(s)
->setRecipients([
'+46719283981',
'+46719283982',
'+46719283983',
'+46719283984',
])
// When the accepts the call, play a file and hang up
->voiceStart(function(PhoneCallAction $action){
return $action
->play('http://yourapp.com/wav/hello.wav')
->hangUp();
});The receiver service handles incoming phone calls. This is how you access the phone receiver
// Via base client
use Tarre\Php46Elks\Client as Php46ElkClient;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$phone = $Php46ElksClient->phone()->receiver();
// without client
$phone = new PhoneCallReceiverService;NOTE: Receiving phone calls requires your PHP application to be exposed to 46elks.com`s webhooks.
Receiving phone calls is pretty straight forward, 46elks.com sends an POST request to the web hook to the url you provided in their control panel.
When your app receives the message, you can read certain data and peform some actions.
use Tarre\Php46Elks\Client;
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
$Php46ElksClient = (new Client('username', 'password'));
$receiver = $Php46ElksClient->phone()->receiver();
return $receiver->handleRequest(function(ReceivedPhoneCall $phoneCall){
// You wont be able to see this print_r result, so replace it with some log function of yours
print_r([
$phoneCall->callId(),
$phoneCall->created(),
$phoneCall->direction(),
$phoneCall->from(),
$phoneCall->to()
]);
// You wont be able to see this print_r result, so replace it with some log function of yours
print_r($phoneCall->toArray());
// handle the phone call by playing a soundfile, then hanging up
return $phoneCall
->action()
->play('http://yourapp.com/elks/soundfile.mp3') // play this file
->hangUp(); // hangup the call
});Whether you are making outgoing calls or receiving incoming calls, the PhoneCallAction class can be accessed to peform certains actions to the active call.
All examples will be presented as received calls without the base client
Connect the call to a given number, and in the case of an answer, let the two callers speak to each other.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action()
->connect('+46701464412');
});Play an audio file or predefined sound. Could be either a URL on your server or a sound resource provided by 46elks.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action()
->play('http://yourapp.com/welcome.mp3');
});The “ivr” action fills the purpose of playing a sound resource while also retrieving digits pressed by the caller (think customer support menus etc.).
Once a key is pressed the url in next will recieive a post request with an query param called result with the key pressed, so if the 3 key was pressed the url would end up like this http://yourapp.com/ivr-test.php?result=3
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action() // access phone call actions
->ivr('welcome.mp3')
->next('http://yourapp.com/ivr-test.php'); // go back to the same url. Effectively a loop
});You can also supply phone actions for the different alternatives directly.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action() // access phone call actions
->ivr([
'ivr' => 'welcome.mp3', //play this when call is connected
'1' => $phoneCall->action()->play('hours.mp3'), // if the caller presses 1, play opening hours
'2' => $phoneCall->action()->connect('+467014674527'), // if the caller presses 2, connect them to customer service
])
->next('http://yourapp.com/ivr-test.php'); // repeat
});This action records the voice of the caller.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action() // access phone call actions
->recordCall('https://yourapp.example/elks/recordings')
->connect('+46780121241')// Or any other action
->next('https://yourapp.example/elks/calls'); // optional
});This action records the entire call and sends out a webhook with a link to the recording when the call ends. This action cannot be used by itself, it triggers at the same time as another action.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action() // access phone call actions
->record('https://yourapp.example/elks/recordings')
->next('https://yourapp.example/elks/calls'); // optional
});End the call. If this is your first action, it is possible to control signalling, otherwise only "reject" is allowed.
use Tarre\Php46Elks\Clients\PhoneCall\Resources\ReceivedPhoneCall;
use Tarre\Php46Elks\Clients\PhoneCall\Services\PhoneCallReceiverService;
return (new PhoneCallReceiverService)->handleRequest(function(ReceivedPhoneCall $phoneCall){
return $phoneCall
->action() // access phone call actions
->play('https://yourapp.example/elks/recordings')
->hangUp('reject'); // optional
});To learn more about call actions, please consult this portion of the documentation. All call actions are reflected as functions via PhoneCallAction
The phone router handles incoming requests.
This is the scenario:
When you dial +46xxxxx You are presented with a soundfile telling you which buttons do what: Press 1 for hours Press 2 to talk with an employee Option 1 just plays a soundfile then hangs up Option 2 connets the caller to another number
Assuming this code exists in
http://yourapp.com/elks/callsandvoice_start@ 46elks.com points tohttp://yourapp.com/elks/calls
use Tarre\Php46Elks\Client;
use Tarre\Php46Elks\Clients\PhoneCall\Resources\PhoneCallAction;
/* Set the baseURL for all actions and webhooks (Optional) */
Client::setResourceBaseUrl('http://yourapp.com/elks/calls');
$Php46ElksClient = (new Client('username', 'password'));
$router = $Php46ElksClient->phone()->router();
$router->default(function(PhoneCallAction $action){
return $action
->ivr('choices.mp3')
->next('', ['action' => 'ivr']); // This will create a loopback to this action again
});
$router->register('ivr1', function(PhoneCallAction $action){
return $action
->play('hours.mp3') // opening hours will be presented
->next('', ['action' => 'ivr']); // This will redirect the call to "http://yourapp.com/elks/calls.php?action=ivr"
});
$router->register('ivr2', function(PhoneCallAction $action){
return $action
->connect('+467013212321');
});
// At first glance, this looks weird. But it makes sense.
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
$digits = isset($_REQUEST['digits']) ? $_REQUEST['digits'] : '';
// As you saw above this example, we assumed the calls initial endpoint is `.../calls`
// And according to https://46elks.se/docs/voice-ivr the IVR action will make a request with an added query param called `digits`
// That means that when the user inputs 1 on their phone, 46elks will make this request `calls.php?action=ivr&digits=1`
// Therefore we can match those
// Handle registered routes. This action will return a JSON that 46elks reads.
$actionName = $action . $digits;
return $router->handle($actionName);if you want to save different routes dynamically you can save and load routes with compile
use Tarre\Php46Elks\Client;
use Tarre\Php46Elks\Clients\PhoneCall\Resources\PhoneCallAction;
/* Set the baseURL for all actions and webhooks (Optional) */
Client::setResourceBaseUrl('http://yourapp.com/elks/calls');
$Php46ElksClient = (new Client('username', 'password'));
$router = $Php46ElksClient->phone()->router();
$router->default(function(PhoneCallAction $action){
return $action
->ivr('choices.mp3')
->next('', ['action' => 'ivr']); // This will create a loopback to this action again
});
// save
$router->compile();
$compiledRoutes = $router->toJson();
// load json
$router->compile(json_decode($compiledRoutes, true));This is how you fetch call history from 46elks.
Notes
- Log retention is set in your account settings
use Tarre\Php46Elks\Client as Php46ElkClient;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$history = $Php46ElksClient->phoneCall()->history();
$paginator = $history->get();
foreach($paginator->getData() as $PhoneCall){
print_r([
'direction' => $PhoneCall->direction(),
'id' => $PhoneCall->id(),
'from' => $PhoneCall->from(),
'to' => $PhoneCall->to(),
'created' => $PhoneCall->created(),
'cost' => $PhoneCall->cost()
]);
}There exists a couple of filter settings you can use to search and narrow your results
start($date)Retrieve PhoneCall before this date.end($date)Retrieve PhoneCall after this date.limit($number)Limit the number of results on each page.
These filters MUST to be used before get is invoked. After get has been invoked, you can use next() to get the next "page"
use Tarre\Php46Elks\Client as Php46ElkClient;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$history = $Php46ElksClient->phone()->history();
$paginator = $history
->start('2020-02-14T09:52:07.302000')
->end('2020-02-15T09:52:07.302000')
->get();
foreach($paginator->getData() as $PhoneCall){
print_r([
'direction' => $PhoneCall->direction(),
'id' => $PhoneCall->id(),
'from' => $PhoneCall->from(),
'to' => $PhoneCall->to(),
'created' => $PhoneCall->created(),
'cost' => $PhoneCall->cost()
]);
}To retrieve a single resource you can invoke the getById instead of get
use Tarre\Php46Elks\Client as Php46ElkClient;
// Initialize client
$Php46ElksClient = new Php46ElkClient('username', 'password');
$history = $Php46ElksClient->phone()->history();
$PhoneCall = $history->getById('enter phoneCall id here');
print_r([
'direction' => $PhoneCall->direction(),
'id' => $PhoneCall->id(),
'from' => $PhoneCall->from(),
'to' => $PhoneCall->to(),
'created' => $PhoneCall->created(),
'cost' => $PhoneCall->cost()
]);