Spillman XML API Powershell Script |
Top Previous Next |
# If powershell scripts aren't yet allowed to run on this computer then # run powershell as administrator and issue the following command: # set-executionpolicy remotesigned
# Need to create event logging source before first run, in powershell, as administrator # New-EventLog -LogName Application -Source "SpillmanXmlApiRequester"
# To run this script as a service see install-service.ps1 script
##### User Settable Values
# Folder that the script runs out of $WorkingDir = "THE PATH TO YOUR SCRIPT'S FOLDER"
# Delay between requests (seconds) $RequestDelay = 3
# PageGate Recipient $PGRecipient = "fromcad"
# PageGate Sender $PGSender = "CAD"
# Request URI $RequestUri = "THE IP OF YOUR SPILLMAN SERVER:4081/DataExchange/REST"
# API Username $APIUsername = "xmluser"
# API Password $APIPassword = "xmluser"
# Write debug info to console $Debug = $True
# Write debug info to a file # *** should not be left set on a production system # because file will grow indefinitely $LogToFile = $True
# Path to log file $LogFile = "THE PATH TO YOUR SCRIPT'S FOLDER\log.txt"
# API XML request $APIRequest = '<?xml version="1.0" encoding="UTF-8"?> <PublicSafetyEnvelope version="1.0"> <From/> <To/> <Creation/> <PublicSafety id=""> <Query> <CADActiveCallTable> <CADMasterCallCommentsTable childField="LongTermCallID" parentField="LongTermCallID" /> <RadioLogUnitStatusTable childField="LongTermCallID" parentField="LongTermCallID" /> </CADActiveCallTable> </Query> </PublicSafety> </PublicSafetyEnvelope>'
# End Of Line value - used in Build-Message-Text Set-Variable -Name Eol -Scope Global -Value "`r`n"
# This function is used to build the contents of the text message # use $CallXml.<XML-tag-name> to insert the contents of an XML tag in the call function Build-Message-Text($CallXml) { # This will return the call's full XML response as the message text #Return $PGRecipient + $Eol + #$PGSender + $Eol + #$CallXml.OuterXML
# This will return select XML fields as the message text Return $PGRecipient + $Eol + $PGSender + $Eol + '<LongTermCallID>' + $CallXml.LongTermCallID + '</LongTermCallID>' + $Eol + '<IncidentNature>' + $CallXml.IncidentNature + '</IncidentNature>' + $Eol + '<RespondToAddress>' + $CallXml.RespondToAddress + '</RespondToAddress>' + $Eol + '<CityCode>' + $CallXml.CityCode + '</CityCode>' + $Eol + '<AgencyCode>' + $CallXml.AgencyCode + '</AgencyCode>' + $Eol + '<WhenCallWasOpened>' + $CallXml.WhenCallWasOpened + '</WhenCallWasOpened>' + $Eol + '<YCoordinateGeobase>' + $CallXml.YCoordinateGeobase + '</YCoordinateGeobase>' + $Eol + '<XCoordinateGeobase>' + $CallXml.XCoordinateGeobase + '</XCoordinateGeobase>' + $Eol + '<CallTakerComments>' + $CallXml.CADMasterCallCommentsTable.CallTakerComments + '</CallTakerComments>' + $Eol }
##### End User Settable Values
# write startup notice to event log Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Information -EventId 1 -Message "Started" if ($Debug) { Write-Host ("Started") if ($LogToFile) { Add-Content $LogFile -value "Started" } }
try { while ($True) { if ($Debug) { Write-Host Write-Host ("Start message check") if ($LogToFile) { Add-Content $LogFile -value "" Add-Content $LogFile -value "Start message check" } }
# variable that stores call ids read from API request XML $XmlIds = New-Object System.Collections.Generic.List[string]
# get stored ids from disk try { # clear stored ids $StoredIds = $null # read ids file [System.Collections.Generic.List[String]]$StoredIds = get-content ($WorkingDir + "ids.txt") -ErrorAction Stop } catch { # can't access file Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Error -EventId 1 -Message "Unable to read stored Ids file" if ($Debug) { Write-Host ("Unable to read stored Ids file") if ($LogToFile) { Add-Content $LogFile -value "Unable to read stored Ids file" } } } # check if null if (!$StoredIds) { # null, so create empty object $StoredIds = New-Object System.Collections.Generic.List[string] }
if ($Debug) { Write-Host ("Stored Ids:") $StoredIds if ($LogToFile) { Add-Content $LogFile -value "Stored Ids:" Add-Content $LogFile -value $StoredIds } }
# generate credentials used to access API $TextCredentials = $APIUsername + ":" + $APIPassword $ByteCredentials = [System.Text.Encoding]::ASCII.GetBytes($TextCredentials) $Base64Credentials = [Convert]::ToBase64String($ByteCredentials)
$Headers = @{ Authorization = "Basic " + $Base64Credentials }
# API request in XML form $Body = $APIRequest
# make the actual request $Response = Invoke-WebRequest -URI $RequestUri -Method "Post" -Headers $Headers -Body $Body -UseBasicParsing
if ($Debug) { Write-Host ("HTTP response:") $Response if ($LogToFile) { Add-Content $LogFile -value "HTTP response:" Add-Content $LogFile -value $Response } }
# convert the received body text to an XML object (easier to work with) $ResponseXml = New-Object XML $ResponseXml.PreserveWhitespace = $True $ResponseXml.LoadXml($Response.Content)
# check if null if (!$ResponseXml) { # null, so create empty object $ResponseXml = New-Object XML }
#if ($Debug) #{ # Write-Host ("Response XML:") # $ResponseXml.OuterXml # if ($LogToFile) # { # Add-Content $LogFile -value "Response XML:" # Add-Content $LogFile -value $ResponseXml.OuterXml # } #}
# loop through the CADActiveCallTable blocks foreach ($Call in $ResponseXml.SelectNodes("//CADActiveCallTable")) { # only process Dispatched (DISP) or Onsite (ONS) calls if (($Call.StatusCodeOfCall -eq 'DISP') -or ($Call.StatusCodeOfCall -eq 'ONS')) { $CallId = $Call.LongTermCallID + "-" + $Call.CallTypeLawFireEMS + "-" + $Call.AgencyCode + "-" + $Call.IncidentNature $CallId = $CallId -replace " ", "-" $XmlIds.Add($CallId) $Match = $False
# look for a match in the stored ids foreach ($StoredId in $StoredIds) { if ($CallId -eq $StoredId) { # match found $Match = $True break } } if ($Match) { # existing id if ($Debug) { Write-Host ("Call Id already exists: " + $CallId) if ($LogToFile) { Add-Content $LogFile -value ("Call Id already exists: " + $CallId) } } } else { # new id found $StoredIds.Add($CallId) # write message file $MessageText = Build-Message-Text($Call) if ($Debug) { Write-Host ("Call Id is new: " + $CallId) Write-Host ("New message created:") $MessageText if ($LogToFile) { Add-Content $LogFile -value ("Call Id is new: " + $CallId) Add-Content $LogFile -value "New message created:" Add-Content $LogFile -value $MessageText } } $MessageFile = $WorkingDir + $CallId + ".asc" try { Set-Content -Path $MessageFile -Value $MessageText } catch { # unable to write message file Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Error -EventId 3 -Message "Unable to write message file" if ($Debug) { Write-Host ("Unable to write message file") if ($LogToFile) { Add-Content $LogFile -value "Unable to write message file" } } } } }
# do it all again for each <RadioLogUnitStatusTable> entry foreach ($AddCall in $Call.RadioLogUnitStatusTable) { # only process Dispatched (DISP) or Onsite (ONS) calls if (($AddCall.StatusDisplayCode -eq 'DISP') -or ($Call.StatusDisplayCode -eq 'ONS')) { # only process ones with AgencyCode set if ($AddCall.AgencyCode) { # replace the master call's AgencyCode with this one $Call.AgencyCode = $AddCall.AgencyCode
$CallId = $Call.LongTermCallID + "-" + $Call.CallTypeLawFireEMS + "-" + $Call.AgencyCode + "-" + $Call.IncidentNature $CallId = $CallId -replace " ", "-" $XmlIds.Add($CallId) $Match = $False
# look for a match in the stored ids foreach ($StoredId in $StoredIds) { if ($CallId -eq $StoredId) { # match found $Match = $True break } } if ($Match) { # existing id if ($Debug) { Write-Host ("Call Id already exists: " + $CallId) if ($LogToFile) { Add-Content $LogFile -value ("Call Id already exists: " + $CallId) } } } else { # new id found $StoredIds.Add($CallId) # write message file $MessageText = Build-Message-Text($Call) if ($Debug) { Write-Host ("Call Id is new: " + $CallId) Write-Host ("New message created:") $MessageText if ($LogToFile) { Add-Content $LogFile -value ("Call Id is new: " + $CallId) Add-Content $LogFile -value "New message created:" Add-Content $LogFile -value $MessageText } } $MessageFile = $WorkingDir + $CallId + ".asc" try { Set-Content -Path $MessageFile -Value $MessageText } catch { # unable to write message file Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Error -EventId 3 -Message "Unable to write message file" if ($Debug) { Write-Host ("Unable to write message file") if ($LogToFile) { Add-Content $LogFile -value "Unable to write message file" } } } } } } }
}
# write stored ids to disk try { Set-Content -Path ($WorkingDir + "ids.txt") -Value $XmlIds } catch { # unable to write stored ids Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Error -EventId 4 -Message "Unable to write stored Ids file" if ($Debug) { Write-Host ("Unable to write stored Ids file") if ($LogToFile) { Add-Content $LogFile -value "Unable to write stored Ids file" } } }
if ($Debug) { Write-Host ("Pausing for " + $RequestDelay + " seconds") if ($LogToFile) { Add-Content $LogFile -value ("Pausing for " + $RequestDelay + " seconds") } }
Start-Sleep -Seconds $RequestDelay } } finally { # write shutdown notice to event log Write-EventLog -LogName "Application" -Source "SpillmanXmlApiRequester" -EntryType Information -EventId 2 -Message "Stopped" if ($Debug) { Write-Host ("Stopped") if ($LogToFile) { Add-Content $LogFile -value "Stopped" } } }
|