Home » Php » php – Five9's API: How to pull reports using SOAP API and Basic Authentication

php – Five9's API: How to pull reports using SOAP API and Basic Authentication

Posted by: admin July 12, 2020 Leave a comment

Questions:

We are trying to access data from Five9’s server using there reporting API. We have written code below but are not getting any results. To me it looks like issue is with the Authentication to Five9’s server. Please check help us understand how we can pull data for a specific campaign on regular interval of time and store it in out Data Warehouse.

<?php
$soapUser = "USERNAME";  //  username
$soapPassword = "DEMOPASSWORD"; // password

$soap_options   = array( 'login' => $soapUser, 'password' => $soapPassword );
$auth_details   = base64_encode($soapUser.":".$soapPassword);

$client = new SoapClient("https://api.five9.com/wsadmin/v2/AdminWebService?wsdl",       $soap_options);
$header = new SoapHeader("https://api.five9.com/wsadmin/v2/AdminWebService/getCallLogReport", "authentication", "Basic $auth_details"); 
//echo "Response:\n" . $client->__getLastResponse() . "\n";
$client->__setSoapHeaders($header);

$xml_data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://service.admin.ws.five9.com/v2/AdminWebService/getCallLogReport">
<soapenv:Header/>
<soapenv:Body>
  <v2:getCallLogReport>
        <campaigns>Campaign1</campaigns>
  </v2:getCallLogReport>
</soapenv:Body>
</soapenv:Envelope>';

echo $result = $client->getCallLogReport($xml_data,   "https://api.five9.com/wsadmin/v2/AdminWebService?wsdl", "https://api.five9.com/wsadmin/v2/AdminWebService/getCallLogReport",0); 


?>  

Sample XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:v2="http://service.admin.ws.five9.com/v2/">
<soapenv:Header/>
<soapenv:Body>
  <v2:getCallLogReport>
     <!--Optional:-->
     <time>
        <!--Optional:-->
        <end>?</end>
        <!--Optional:-->
        <start>?</start>
     </time>
     <!--Optional:-->
     <criteria>
        <!--Optional:-->
        <ANI>?</ANI>
        <!--Zero or more repetitions:-->
        <agents>?</agents>
        <!--Zero or more repetitions:-->
        <callTypes>?</callTypes>
        <!--Zero or more repetitions:-->
        <campaigns>?</campaigns>
        <!--Optional:-->
        <DNIS>?</DNIS>
        <!--Zero or more repetitions:-->
        <dispositions>?</dispositions>
        <!--Zero or more repetitions:-->
        <lists>?</lists>
        <!--Zero or more repetitions:-->
        <skillGroups>?</skillGroups>
     </criteria>
  </v2:getCallLogReport>
  </soapenv:Body>
 </soapenv:Envelope>
How to&Answers:

It looks like your problem is that your sending your base64 encoded username/password in the soap header. It actually needs to be included in the http header. My solution is in ruby but hopefully it can help you out.

soap_client = Savon.client(
  endpoint: "https://api.five9.com/wsadmin/AdminWebService/", 
  namespace: "http://service.admin.ws.five9.com/", 
  headers: { "Authorization" => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" }, 
  env_namespace: :soapenv, 
  namespace_identifier: :ser, 
  ssl_verify_mode: :none
)

message = { 
  "lookupCriteria" => {
"criteria" => {
      "field" => "email_address",
      "value" => "[email protected]"
    }
  }
}

response = soap_client.call(:getContactRecords, message: message)
p response.body

So your XML ends up looking like this.

SOAP request: https://api.five9.com/wsadmin/AdminWebService/
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==, SOAPAction: "getContactRecords",
Content-Type: text/xml;charset=UTF-8, Content-Length: 471

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ser="http://service.admin.ws.five9.com/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <ser:getContactRecords>
      <lookupCriteria>
        <criteria>
          <field>email_address</field>
          <value>[email protected]</value>
        </criteria>
      </lookupCriteria>
    </ser:getContactRecords>
  </soapenv:Body>
</soapenv:Envelope>

HTTPI POST request to api.five9.com (httpclient)
SOAP response (status 200)

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
  <env:Header></env:Header>
  <env:Body>
    <ns2:getContactRecordsResponse xmlns:ns2="http://service.admin.ws.five9.com/" xmlns:ns3="http://service.admin.ws.five9.com/v1/">
      <return>
        <fields>number1</fields>
        <fields>email_address</fields>
        <records>
          <values>
            <data>5555555555</data>
            <data>[email protected]</data>
          </values>
        </records>
      </return>
    </ns2:getContactRecordsResponse>
  </env:Body>
</env:Envelope>

Answer:

I know this is an old question, but we recently switched to using Five9 and I couldn’t find any PHP examples to work with. The following illustrates how to connect using standard credentials, and execute the call list. I’ve included the entire selection criteria structure (commented out) for your reference. If you include a selection property, you must specify the corresponding criteria.

$soap = null;
$wsdl = "https://api.five9.com/wsadmin/v2/AdminWebService?wsdl";

$user = "yourloginid";
$pass = "yourpassword";

$soap_options = array("login" => $user, "password" => $pass);

$soap = new SoapClient($wsdl, $soap_options);

/* create the callLogReportCriteria data selection structure */
$arryParams['time']  = array("start" => "2013-05-05T00:00:01",
                             "end" => "2013-05-05T09:00:00");
$arryParams['criteria'] = array("callTypes" =>  array("INBOUND","OUTBOUND"));

/************ Entire Structure for selection criteria *************/
/*$arryParams['criteria'] = array("ANI" =>  "6178752803",
                                "Agents" => "",
                                "callTypes" =>  array("INBOUND","OUTBOUND"),
                                "campaigns" =>  "",
                                "dispositions" => "",
                                "Lists" =>  "",
                                "skillGroups" => ""
                               );*/

$result = $soap->getCallLogReport($arryParams);

if(isset($result->return->records)) {
    /* you have records returned */
    $objRecords = $result->return->records;

    for($i=0 ; $i < sizeof($objRecords) ; $i++) {
        /* do your processing */
        printf("ANI: %s<br />", $objRecords[$i]->values->data[3]); //4th element has ANI
    }

}

Certain lines of code could be combined, but for the sake of understandability I broke them out. You will also want to utilize a try/catch around the actual SOAP call for error handling.

Hopefully this will help shorten someone’s learning curve. I know I would have loved to have had this a month ago!!

Answer:

@JesseQ great example! Helped me a ton. Here’s how I set it up to run any Five9 report in their arsenal including ones you create yourself. For custom reports, you’ll need to create a new folder/report and place it in the “Custom Reports” section on the Five9 web portal. Hope this helps.

MySQL Database Connection (dbConnect.php)

<?php
    $mysqli = new mysqli("your db's IP address", "your db user", "your db password", "your db");
    if ($mysqli->connect_error) {
        die('Connect Error: (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
    }
?>

Five9/MySQL Database Import

<?php
    require_once("../include/dbConnect.php");
    $startDate = new DateTime();
    $endDate = new DateTime();
    $startDate->setDate(2015, 07, 22);
    $endDate->setDate(2015, 07, 22);
    $five9 = "https://api.five9.com/wsadmin/v2/AdminWebService?wsdl";
    $five9Credentials = array("login" => "your Five9 username", "password" => "your Five9 password");
    $soap = new SoapClient($five9, $five9Credentials);
    $runReportParam["criteria"]["time"] = array("start" => $startDate->format("Y-m-d\T00:00:00"), "end" => $endDate->format("Y-m-d\T23:59:59"));
    $runReportParam["folderName"] = "My Custom Reports";
    $runReportParam["reportName"] = "My First Report";
    $runReportResult = $soap->runReport($runReportParam);
    if(isset($runReportResult->return)){
        $runReportData = $runReportResult->return;
        $isReportRunningParam["identifier"] = $runReportData;
        $isReportRunningParam["timeout"] = 10;
        $isReportRunningResult = $soap->isReportRunning($isReportRunningParam);
        if(empty($isReportRunningResult->return)){
            $getReportResultParam["identifier"] = $runReportData;
            $getReportResult = $soap->getReportResult($getReportResultParam);
            if(isset($getReportResult->return->records)){                
                $getReportResultData = $getReportResult->return->records;
                echo "[" . date("Y-m-d h:i:s") . "] " . $runReportData . "\n";
                for($x = 0; $x < $xx = count($getReportResultData); $x++){
                    $query = "REPLACE INTO MyTable(
                        CallDate, CallTime, DNIS, Disposition, Zip, AreaCode, ANI)
                        VALUES (?,?,?,?,?,?,?)";
                    $result = $mysqli->prepare($query);
                    $result->bind_param("sssssss", 
                        $getReportResultData[$x]->values->data[0],
                        $getReportResultData[$x]->values->data[1],
                        $getReportResultData[$x]->values->data[2],
                        $getReportResultData[$x]->values->data[3],
                        $getReportResultData[$x]->values->data[4],
                        $getReportResultData[$x]->values->data[5],
                        $getReportResultData[$x]->values->data[6]
                    );
                    $result->execute();
                    $result->store_result();
                    if ($result->error){
                        die('Connect Error: (' . $result->errno . ') ' . $result->error);
                    }
                    echo "[" . date("Y-m-d h:i:s") . "] " . $x . "\n";
                }
            } else {
                echo "Error: " . $runReportData . " returned no data";
            }
        } else {
            echo "Error: " . $runReportData . " exceeded the report runtime limit";
        }
    } else {
        echo "Error: " . $runReportParam["reportName"] . " wasn't found";
    }
    $mysqli->close();
?>