Posting Asterisk/FreePBX calls to Toggl

Toggl is a hosted time tracking system, used to keep track of time spent of different projects.

If you use Asterisk/FreePBX and spend time on the phone to clients that should be assigned to a project you can automatically create time entries in Toggl using their API. To do this we can make a curl call from Asterisk when a call ends.

To be able to do this you’ll need to ensure you have curl compiled in to Asterisk. You can check this with “core show function CURL”.

I tested this on Asterisk 11 and FreePBX v2.11, but it should work the same on other versions.

First we need to add a little dial plan code to Asterisk to tell it to run our script when a call ends. We going to do this by adding the following lines to – /etc/asterisk/extensions_custom.conf

[macro-dialout-trunk-predial-hook]    ; check to ensure this context doesn't already exist before adding
exten => s,1,Set(CHANNEL(hangup_handler_push)=hangup-handler,s,1)

[hangup-handler]
exten => s,1,Noop( capsule crm intergration ${CALLERID(all)})
exten => s,n,Set(foo=${CURL(http://127.0.0.1/toggl.php?strSrc="${CDR(src)}"&strDst=${CDR(dst)}&strDuration="${CDR(duration)}")})
exten => s,n,Noop(${foo})
exten => s,n,Return()

After changing the dial plan we will either need to restart Asterisk or run “dialplan reload”.

That will call a web page on the local server called toggl.php, now we need to create that file. On my server it will look here for the file – /var/www/html/toggl.php

<?php

// You will need to change this setting
$api_token = 'XXXXXXXXXXXXXXXXXXXXXXX';

$toggl_api = "https://www.toggl.com/api/v8/time_entries";

$src = $_GET['strSrc'];
$dst = $_GET['strDst'];
$duration = $_GET['strDuration'];
$current_date = new DateTime();

class TimeEntry {
    public $description= "";
    public $tags  = "";
    public $start = "";
    public $pid = "";
    public $created_with = "";
}

$time_entry = new TimeEntry();
$time_entry->description = "Telehone call from $src to $dst";
$time_entry->tags  = "billed";
$time_entry->duration  = "$duration";
$time_entry->created_with  = "curl";

json_encode($time_entry);
$time_entry->start = $current_date->format('c');
$time_entries = json_encode(array("time_entry" => $time_entry));

// Initialise the session and return a cURL handle to pass to other cURL functions.
$ch = curl_init($toggl_api);
$options = array(CURLOPT_USERPWD => "$api_token:api_token",
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $time_entries
);
curl_setopt_array($ch, $options);

// Do the POST and collect the response for future printing etc then close the session
$response = curl_exec($ch);
$responseInfo = curl_getinfo($ch);
curl_close($ch);
echo $responseInfo;
echo $response;
?>

You will need to change the setting at the top to match your toggl API token.

Now when a call ends Asterisk calls the toggl.php web page, passing it the source, destination and length of the call. This is then formatted in the way that the toggl API expects and posted to toggl.

When a call ends you should immediately see a new time entry created in Toggl –

toggl time entries

If your time entry doesn’t get created in toggl then check in the Asterisk logs to ensure the Curl request is being made, and check in the web server logs to ensure there are no errors when the script runs.