(v1) .Custom API Library v2021.3
For details on writing a Custom API Endpoint, please see our wiki article.
Process Incoming Slack API Calls
This Custom API script was written to process incoming API calls from Slack (a team chat program we use internally at PCR).
<?php /** * Type: Custom Logic * Identifier: helpdesk */ // The incoming payload from Slack is JSON encoded // so we need to decode it... $payload = json_decode($request["payload"], true); $user = $payload["user"]["name"]; $callbackId = explode("-",$payload["callback_id"]); $iconUrl = "https://www.iconexperience.com/_img/v_collection_png/24x24/plain/"; $icon = "error.png"; // find the Contact for this User - using the query function is best with // bound parameters instead of placing them directly into the query string. // This protects the database against injection threats $contacts = $this->query( "SELECT RECID FROM CONTACTS C LEFT JOIN V_UDF UDF ON UDF.VALUE_TABLE_NAME = 'CONTACTS' AND C.RECID = VALUE_TABLE_RECID WHERE UDF.VALUE = :slack_user", [":slack_user" => "@".$user] ); if(!empty($contacts)){ // the query function always returns an array // of rows so we need to look at the first index $contact = $contacts[0]; $incidents = $this->query( "SELECT SD.*, D.CODE, L.VALUE AS STATUS FROM SERVICE_DESK SD LEFT JOIN DEPT_HIERARCHY D ON SD.D_OWNER_DEPT_HIERARCHY_RECID = D.RECID LEFT JOIN LISTS L ON SD.SD_STATUS_LISTS_RECID = L.RECID WHERE SD_NUMBER = :incident", [":incident" => $callbackId[0]] ); if(!empty($incidents)){ $incident = $incidents[0]; $workflow = $this->query( "SELECT SDWF.*, CONCAT(C.LAST_NAME,', ',C.FIRST_NAME) AS WORKER, L.CODE AS STATUS FROM SERVICE_DESK_WORKFLOW SDWF LEFT JOIN CONTACTS C ON C.RECID = SDWF.WORKER_CONTACTS_RECID LEFT JOIN LISTS L ON SDWF.SD_WF_STATUS_LISTS_RECID = L.RECID WHERE SERVICE_DESK_RECID = :sd_recid AND SDWF.RECID = :recid", [ ":sd_recid" => $incident["RECID"], ":recid" => $callbackId[2] ] ); if(!empty($workflow)){ $wf = $workflow[0]; if(empty($wf["WORKER"])){ if($wf["STATUS"] == "PENDING"){ if(Core_Model_Api_Servicedesk::assignWorkflow( $wf["RECID"], $contact["RECID"] )){ $assigned = "Assigned to @{$user}"; $icon = "checkbox.png"; } else { $assigned = "Error: Failed to Assign Workflow..."; } } else { $assigned = "Error: WF is not Pending..."; } } else { $assigned = "WF Already Assigned to {$wf["WORKER"]}"; $icon = "information.png"; } } else { $assigned = "Error: Cannot find Workflow {$callbackId[1]} on {$callbackId[0]}..."; } } else { $assigned = "Error: Cannot find Incident [{$callbackId[0]}]..."; } } else { $assigned = "Error: Cannot find User [{$payload["user"]["name"]}]..."; } $orig = $payload["original_message"]; // the response array is the data that is returned to the original API request $response = [ "text" => $orig["text"], "attachments" => [[ "title" => $orig["attachments"][0]["title"], "title_link" => $orig["attachments"][0]["title_link"], "text" => $orig["attachments"][0]["text"], "footer" => $assigned, "footer_icon" => $iconUrl.$icon, "ts" => time(), ]] ];
Service Now Integration - Move Service
Service Now Integration is built upon PCR-360's (v1) Custom API Endpoints. Service Now will send its requests to the appropriate Endpoint and PCR-360 will process the details accordingly.
SNOW: Move Service
<?php // log the original request JSON in the SERVICENOW_DETAILS UDF table $details = ["data" => []]; $systemValues = [ "apikey" => "apikey", "typeformat" => "typeformat", "module" => "module", "controller" => "controller", "action" => "action", "request_method" => "request_method", "limit" => "limit", "page" => "page", "tenants_recid" => "tenants_recid", "ident" => "ident" ]; $data = array_diff_key($request, $systemValues); foreach ($data as $field => $value) { $details["data"][] = [ "LABEL" => $field, "VALUE" => $value ]; } // set the default save data to create an SO with the SNOW data in a UD table $payload = [ "type" => "SO", "csr" => "1", // User Demo "udf_SERVICENOW_NUMBER" => trim($request["servicenow_number"]), // SERVICENOW_NUMBER "udf_SERVICENOW_DETAILS" => json_encode($details), // SERVICENOW_DETAILS ]; // get the requestor based on the incoming requestor email address $requestorQuery = $this->query( "SELECT C.RECID FROM CONTACTS C JOIN CONTACTS_EMAILS CE ON C.RECID = CE.CONTACTS_RECID WHERE CE.EMAIL = :requestor", [":requestor" => trim($request["requestor"])] ); if (count($requestorQuery) && ($requestorRecid = $requestorQuery[0]["RECID"])) { // find the location RECID of the moveto_location $locationQuery = $this->query( "SELECT L.RECID FROM LOCATIONS L WHERE L.NAME = :location", [ ":location" => $request["moveto_location"] ]); if (count($locationQuery) && ($movetoLocationRecid = $locationQuery[0]["RECID"])) { // find the service RECID $service = $request["service"]; $serviceQuery = $this->query( "SELECT S.RECID FROM SERVICES S WHERE S.SERVICE_ID = :service OR S.SERVICE_ID_FMT = :service", [":service" => $service] ); if (count($serviceQuery) && ($serviceRecid = $serviceQuery[0]["RECID"])) { // set the SDA variables if the data is valid $payload["sd_action"] = "CHG_MOVE"; $payload["requestor"] = $requestorRecid; $payload["moveto_location"] = $movetoLocationRecid; $payload["service"] = $serviceRecid; } else { $response["error_message"] = "A valid SERVICE RECID could not be found based " . "on the incoming Service Number: " . $service; } } else { $response["error_message"] = "A valid LOCATION RECID could not be found in PCR360 based " . "on the incoming Location: " . $request["moveto_location"]; } } else { $response["error_message"] = "A valid CONTACT RECID could not be found in PCR360 based " . "on the incoming email address: " . $request["requestor"]; } if (isset($response["error_message"])) { // log the error as a remark on the SO $payload["remarks"] = "A Service Desk Action could not be created on this Service Order " . "due to the following error: " . $response["error_message"]; } $result = $this->call("saveServiceDesk", $payload); $response["servicedesk_number"] = $result["data"];
Service Now Integration - New Service
Service Now Integration is built upon PCR-360's (v1) Custom API Endpoints. Service Now will send its requests to the appropriate Endpoint and PCR-360 will process the details accordingly.
SNOW: New Service
<?php if (!empty($request["servicenow_number"])) { // log the original request JSON in the SERVICENOW_DETAILS UDF table $details = ["data" => []]; $systemValues = [ "apikey" => "apikey", "typeformat" => "typeformat", "module" => "module", "controller" => "controller", "action" => "action", "request_method" => "request_method", "limit" => "limit", "page" => "page", "tenants_recid" => "tenants_recid", "ident" => "ident" ]; $data = array_diff_key($request, $systemValues); foreach ($data as $field => $value) { $details["data"][] = [ "LABEL" => $field, "VALUE" => $value ]; } // set the default save data to create an SO with the SNOW data in a UD table $payload = [ "type" => "SO", "csr" => "1", // User Demo "udf_SERVICENOW_NUMBER" => trim($request["servicenow_number"]), // SERVICENOW_NUMBER "udf_SERVICENOW_DETAILS" => json_encode($details), // SERVICENOW_DETAILS "service_host" => "1" ]; // get the requestor based on the incoming requestor email address $requestorQuery = $this->query( "SELECT C.RECID FROM CONTACTS C JOIN CONTACTS_EMAILS CE ON C.RECID = CE.CONTACTS_RECID WHERE CE.EMAIL = :requestor", [":requestor" => trim($request["requestor"])] ); if (count($requestorQuery) && ($requestorRecid = $requestorQuery[0]["RECID"])) { // find the catalog RECID $catalogQuery = $this->query( "SELECT SC.RECID FROM SERV_CATALOG SC WHERE SC.SERVICE_NAME = :catalog", [":catalog" => $request["catalog"]] ); if (count($catalogQuery) && ($catalogRecid = $catalogQuery[0]["RECID"])) { // find the location RECID of the location $locationQuery = $this->query( "SELECT L.RECID FROM LOCATIONS L WHERE L.NAME = :location", [ ":location" => $request["new_location"] ]); if (count($locationQuery) && ($locationRecid = $locationQuery[0]["RECID"])) { // set the SDA variables if the data is valid $payload["sd_action"] = "ADD"; $payload["requestor"] = $requestorRecid; $payload["owner_contact"] = $requestorRecid; $payload["catalog"] = $catalogRecid; $payload["location"] = $locationRecid; } else { $response["error_message"] = "A valid LOCATION RECID could not be found in PCR360 based " . "on the incoming Location: " . $request["new_location"]; } } else { $response["error_message"] = "The Catalog '" . $catalog . "' could not be found in PCR360."; } } else { $response["error_message"] = "A valid CONTACT RECID could not be found in PCR360 based " . "on the incoming email address: " . $request["requestor"]; } if (isset($response["error_message"])) { // log the error as a remark on the SO $payload["remarks"] = "A Service Desk Action could not be created on this Service Order " . "due to the following error: " . $response["error_message"]; } $result = $this->call("saveServiceDesk", $payload); $response["servicedesk_number"] = $result["data"]; }
Help Desk Portal - Email: help@pcr.com - Phone: 616.259.9242