<?php
/*
The purpose of this program is to populate the following table in ServiceNow
with data from the IVR Call Log.
Table Name: Call Center Data (u_call_center_data)
u_call_center_uuid String (empty) 50
u_call_incident Reference Incident sys_id
u_call_language String 50
u_call_time Date/Time 40
u_caller_did String 25
u_did_country Reference Country sys_id
u_duration_in_seconds Integer 40
u_ivr_path String 25
u_source_number String 25
*/
/*
config.php contains the access information to the call center and servicenow
instance
CALL_CENTER = call center url
CALL_CENTER_KEY = call center key
SERVICE_NOW = servicenow url
SERVICE_NOW_USR = servicenow user
SERVICE_NOW_PWD = servicenow password
*/
$config= (include_once('config.php'));
$records= getCallCenter();
foreach($records['rows'] as $record){
$parsedRecord = recordParsing((array)($record));
$parsed_uuid = ($parsedRecord['u_call_center_uuid']);
/* Going out to Servicenow to verify that the record does not exist already.
The u_call_center_uuid should be the unique identifier
if it does not find any records, we will add it.
*/
$verify = verifyUniqueRecord($parsed_uuid);
var_dump($verify);
if ($verify == false){
/* Unique record was found so processing will continue by
obtaining the country that matches the DID number. The country and
DID are contained in the cmn_location table.
*/
$country = findCountryFromDid($parsedRecord['u_caller_did']);
if($country > ''){
$parsedRecord["u_did_country"]= $country;
}else{
/* DID Number without a country.
will add an email process to have it verified
as a valid DID in our list. Continue to add
the record without it though.
*/
postError("Country could not be located for DID. Data includes: \n".$parsedRecord['u_caller_did']);
}
// Matching call center record not found so one will be created
if($parsedRecord['u_duration_in_seconds'] > 120){
/*
If the call reached OpsGenie, it creates an incident.
We want to attempt to match the call with the incident.
*/
$incident = lookForIncident($parsedRecord['u_call_time']);
if($incident > ' '){
// if incident was found, attach the incident number to the record.
$parsedRecord["u_call_incident"] = $incident;
}
}
// post to our ServiceNow
$post = postToSNow($parsedRecord);
}
}
function getCallCenter(){
global $config;
// Basic curl call to the call center. Return's all records.
$curl = curl_init();
$url = $config['CALL_CENTER'].'apikey='.$config['CALL_CENTER_KEY'];
curl_setopt($curl, CURLOPT_HTTPGET, 1);
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_FRESH_CONNECT => TRUE,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"authorization: Basic ############################",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if (($err) or $response === '') {
echo "cURL Error #:" . $err;
postError("Error obtaining data from call center: \n".$err);
return 'Error';
} else {
$records = (array)json_decode($response);
return($records);
}
}
function recordParsing($record){
// parse the record from the IVR log to build the ServiceNow record.
$parsedRecord = array(
"u_call_center_uuid"=>$record['uniqueid'],
"u_call_language"=>$record["lang"],
"u_caller_did"=>$record["did"],
"u_duration_in_seconds"=>$record["duration"],
"u_ivr_path"=>$record["path"],
"u_call_time"=>$record['calldate'],
"u_source_number"=>$record["src"],
"u_domain"=>'############################'
// Getting the country based on the DID Number
);
return $parsedRecord;
}
function verifyUniqueRecord($parsed_uuid){
/* Verify that the record does not exist in ServiceNow
by looking for the record's unique id.
*/
$query = '?sysparm_limit=1&u_call_center_uuid='.$parsed_uuid;
$return = service_now_call('u_call_center_data','',$query,'GET');
if($return['Error'] > ''){
postError("Error verifying duplicates in ServiceNow. Data includes: \n".$parsed_uuid.'\n'.$return);
return false;
}
$record = (array)$return['result'][0];
// if there was a return, send in an 'a'
if($record["sys_id"]){
return true;
}
return false;
}
function findCountryFromDID($did){
/*
$did = string
We will send in the did number from the call log and find the
country it is assigned to in ServiceNow.
*/
$query = '?sysparm_limit=1&u_country.u_msa_country_did_number='.$did;
$return = service_now_call('cmn_location','',$query,'GET');
if($return['Error'] > ''){
postError("Error finding country in ServiceNow. Data includes: \n".$did.'\n'.$return);
return false;
}else {
$result = (array)$return['result'];
$records = (array)$result;
foreach($records as $location){
$tlocation = (array)$location;
$country = (array)$tlocation['u_country'];
return $country['value'];
}
}
return '';
}
function lookForIncident($calldate){
/* Attempt to match the call to an incident based on the date/time.
Can adjust the number of ours to go back based on when the update last
occured by modifying $time
*/
$time = '3600';
$query = "?sysparm_query=openedRELATIVEGE%40hour%40ago%40".$time."&company=MSA%20-%20FedEx";
$return = service_now_call('incident','',$query,'GET');
if($return['Error'] > ''){
postError("Error querying for duplicates. Data includes: \n".$calldate.'\n'.$return);
} else {
// We found at least one possible record
foreach($return['result'] as $record){
$record = (array)($record);
$record = (array)($record);
// calldate needs to be greater than the incident record
$dateTime = new DateTime($record["opened_at"]);
if($calldate < $dateTime){
$calldate2 = new DateTime($calldate);
$dteDiff = $calldate2->diff($dateTime);
$minutes = $dteDiff->days * 24 * 60;
$minutes += $dteDiff->h * 60;
$minutes += $dteDiff->i;
if($minutes <= 3){
/*
Set for 3 minutes because there is a delay from the
call's start time until it reaches opsgenie/servicenow.
We are estimating 3 minute delay to find possible records.
If found, return the incident sys_id to the record.
*/
return $record["sys_id"];
}
}
}
}
return '';
}
function postToSNow($data){
// Post the record ($data) to ServiceNow
$return = service_now_call('u_call_center_data',$data,'','POST');
if($return['Error'] > ''){
postError("Error posting call log item to ServiceNow. Data includes: \n".$data.'\n'.$return);
return 'Error';
} else {
return $return;
}
}
function postError($data){
// If any error is detected, we want to create an incident
// $data contains the description of the error
// Building the Incident Record
$incident = array(
"short_description"=>"Error from Call Record procedure",
"category"=>"ServiceNow",
"description"=>$data,
"company"=>"############################", // us
"customer"=>"############################", // them
"caller"=>"api.user",
"opened_by"=>"api.user"
);
$return = service_now_call('incident',$incident,'','POST');
if($return['Error'] > ''){
// if we had an error on the posting of the error, send email to servicenow
$to = "foobar@service-now.com";
$subject = "Error posting error in call log process";
$message = "Original error: \n";
$message = $return."\n";
$message .= $data;
$header = "From:foo@bar.com \r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-type: text/html\r\n";
$retval = mail($to,$subject,$message,$header);
if( $retval == true ) {
echo "Message sent successfully...";
}else {
echo "Message could not be sent...";
}
return 'Error';
} else {
return $return;
}
}
function service_now_call($table,$data,$query,$type){
global $config;
$url = $config['SERVICE_NOW'].$table.$query;
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $config['SERVICE_NOW_USR'].':'.$config['SERVICE_NOW_PWD']);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
if($type === 'POST'){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($curl);
$return = (array)json_decode($response);
if ($err) {
return array('Error' =>$err);
} else {
$return['Error']='';
// var_dump($return);
return $return;
}
}
?>