Sipgate() Class
I wanted a PHP class that used the Sipgate API for sending SMS (text) messages, and to enable click-to-dial (click2dial) on my desk phone, which uses Sipgate as its VoIP provider. I couldn't find one online, so I wrote one.
If you specify a country It runs phone numbers through a filter to add the correct international dialing code
Source code
class Sipgate
{
var $username;
var $password;
var $sip_id;
// Init.
function Sipgate($username, $password, $sip_id = false)
{
$this->username = $username;
$this->password = $password;
$this->sip_id = $sip_id;
}
// System methods.
// Request a list of the RPC methods offered by the server with each entry being the name of a method stored as string value.
// Returns the response as an array.
function list_methods()
{
return $this->_request('system.listMethods');
}
// Request a human readable description of the given method containing information about purpose and usage.
// Returns the response as an array.
function method_help($method)
{
return $this->_request('system.methodHelp', array('MethodName' => $method));
}
// Request the signature of the given RPC method.
// The server will return a list of signatures valid for the specified method.
// The signature is defined as the promised return value?s type followed by the types of any arguments.
// A method MAY be called in more than one way, which is what the purpose of defining signatures is meant to distinguish.
// Returns the response as an array.
function method_signature($method)
{
return $this->_request('system.methodSignature', array('MethodName' => $method));
}
// The system.serverInfo method provides specific information on the server software.
// Returns the response as an array.
function server_info()
{
return $this->_request('system.serverInfo');
}
// Samurai functions.
// Request an account statement for a specified period.
// Returns the full response as an array.
function account_statement($time_from = 0, $time_to = false)
{
if (!$time_to) $time_to = time();
$args = array('PeriodStart' => date('c', $time_from), 'PeriodEnd' => date('c', $time_to));
return $this->_request('samurai.AccountStatementGet', $args);
}
// The client SHOULD identify itself to the server including version and vendor information to allow for better support in cases of problems.
// Returns true on success or false on failure.
function identify($client_vendor, $client_name, $client_version = '1.0')
{
$args = array('ClientName' => $client_name, 'ClientVersion' => $client_version, 'ClientVendor' => $client_vendor);
return $this->_request('samurai.ClientIdentify', $args);
}
// Request the list of SIP URIs belonging to the user's account.
// Returns array of SIP URIs on success, false on failure.
function uris()
{
if ($response = $this->_request('samurai.OwnUriListGet')) return $response['OwnUriList'];
else return false;
}
// Request the current balance of the users account in pence
// Returns balance on success or false on failure (remember to === false in case of zero balance).
function balance()
{
if ($response = $this->_request('samurai.BalanceGet')) return $response['CurrentBalance']['TotalIncludingVat']; // Round to pence.
else return false;
}
// Click-to-dial.
// $number must have no spaces and include an international calling code, but no IDD or NDD prefixes (0, 00, +, etc).
// Returns SessionID on success, false on failure.
function call($number, $time = false)
{
if (!$this->sip_id)
{
trigger_error('SIP-ID is required for click-to-dial.', E_USER_ERROR);
return false;
}
$args = array('LocalUri' => 'sip:' . $this->sip_id . '@sipgate.co.uk', 'RemoteUri' => 'sip:' . $number . '@sipgate.net', 'TOS' => 'voice', 'Content' => '');
if ($time) $args['Schedule'] = date('c', $time);
if ($response = $this->_request('samurai.SessionInitiate', $args)) return $response['SessionID'];
else return false;
}
// Hang up after a click-to-dial.
// $session_id must be an open session.
// Returns true on success, false on failure.
function call_end($session_id)
{
$args = array('SessionID' => $session_id);
if ($response = $this->_request('samurai.SessionClose', $args)) return true;
else return false;
}
// Get status of a session.
// $session_id must be a valid session.
// Returns human-readable status on success, false on failure (or session not found, ie call ended).
function call_status($session_id)
{
$args = array('SessionID' => $session_id);
if ($response = $this->_request('samurai.SessionClose', $args)) return $response['SessionStatus'];
else return false;
}
// Send a text message to a phone number.
// $country must be a two-letter ISO code.
// $number must have no spaces and include an international calling code, but no IDD or NDD prefixes (0, 00, +, etc).
// It can also be an array of numbers to send the text to multiple phones.
// Returns true on success, false on failure.
function text($number, $message, $time = false)
{
if (is_array($number))
{
$args = array('RemoteUri' => array(), 'TOS' => 'text', 'Content' => $message);
foreach ($number as $t_number) $args['RemoteUri'][] = 'sip:' . $t_number . '@sipgate.net';
if ($time) $args['Schedule'] = date('c', $time);
if ($response = $this->_request('samurai.SessionInitiateMulti', $args)) return true;
else return false;
}
else
{
$args = array('RemoteUri' => 'sip:' . $number . '@sipgate.net', 'TOS' => 'text', 'Content' => $message);
if ($time) $args['Schedule'] = date('c', $time);
if ($response = $this->_request('samurai.SessionInitiate', $args)) return true;
else return false;
}
}
// Private functions.
// Do a request and throw an error on failure.
// Returns true on success and false on failure.
private function _request($method, $args = array())
{
$url = 'https://' . $this->username . ':' . $this->password . '@samurai.sipgate.net/RPC2';
$request = xmlrpc_encode_request($method, $args);
$context = stream_context_create(array('http' => array(
'method' => 'POST',
'header' => 'Content-Type: text/xml',
'content' => $request
)));
$file = file_get_contents($url, false, $context);
$response = xmlrpc_decode($file);
if ($response['StatusCode'] == 200) return ($response);
else
{
if ($response['faultCode']) trigger_error($response['faultCode'] . ': ' . $response['faultString'], E_USER_ERROR);
elseif ($response['StatusCode']) trigger_error($response['faultString'], E_USER_ERROR);
else trigger_error('Sipgate error.', 'Unknown error in Sipgate response.', E_USER_ERROR);
return false;
}
}
}
Examples
Click-to-dial
Start a call on your desk phone.
$username = 'username'; // Your Sipgate username. $password = 'password'; // Your Sipgate password. $sip_id = '1234567'; // SIP-ID of your desk phone. $sg = new Sipgate($username, $password, $sip_id); $phone = '441234567890' // Phone number you want to dial formatted for Sipgate. $sg->call($phone); // Dial the number.
Sending an SMS
Send an SMS via Sipgate. A SIP-ID is not required for sending SMS messages.
$username = 'username'; // Your Sipgate username. $password = 'password'; // Your Sipgate password. $sg = new Sipgate($username, $password); $phone = '441234567890' // Phone number you want to dial formatted for Sipgate. $message = 'Hi, this is just a test message!'; $sg->text($phone, $message); // Send the text.
Format phone numbers
I like to run phone numbers through this function to remove the spaces and format them for Sipgate.
If you specify a country, the function uses my Countries dataset PHP array to strip national dialing prefixes (eg '0') and add the correct international dialing code (eg '44' or '48') to phone numbers.
// Format the phone number for Sipgate.
function sipgate_format_phone($number, $country = false)
{
$number = preg_replace('/[^0-9+]/', '', (substr($number, 0, 20))); // Remove everything except letters and plusses.
if (empty($number)) return false;
if (!$country) return $number; // No country - fingers crossed!
if (substr($number, 0, 1) == '+') return substr($number, 1); // Already an international number - just trim the plus and don't add any prefixes.
// Load international dialing rules.
if ($country == 'GB') $rules = array('dial' => '44', 'idd' => '00', 'ndd' => '0');
else
{
include('list_dialing.php');
if (!$rules = $GLOBALS['dialing'][$country]) return $number; // Invalid ISO code - we can't fix it :'(
}
if (strlen($rules['ndd']) > 0 && substr($number, 0, strlen($rules['ndd'])) == $rules['ndd']) return $rules['dial'] . substr($number, strlen($rules['ndd'])); // Trim off the national prefix if it's there.
else return $rules['dial'] . $number; // If it's not, return the international prefix.
}
Example
$phone = '01234 567 890'; $phone = sipgate_format_phone($phone, 'GB'); // UK number. echo $phone; // Outputs 441234567890 $phone = '01234 56 78 90'; $phone = sipgate_format_phone($phone, 'DE'); // German number. echo $phone; // Outputs 491234567890
