ZendeskWebhook.ps1 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. # original script by https://tietze.io/b/2015/09/08/integrating-zendesk-and-prtg/
  2. #
  3. # solves bug: https://kb.paessler.com/en/topic/75261-single-quote-in-sensor-message-breaks-notification-script
  4. #
  5. # angela 11/24/21:
  6. # - bugfix for multiple existing tickets; search by subject
  7. # - added option to update existing ticket, or leave it be
  8. #
  9. # angela 12/7/18: added:
  10. # - detailed messages & tags that don't break with single quotes
  11. # - local log generator for easy troubleshooting
  12. # - made the script a bit more newb friendly
  13. # - formatting cleanup
  14. #
  15. # This will create a new ticket in PRTG if no open PRTG ticket is found for this device; otherwise it will update the first found open PRTG ticket for this device.
  16. # initialize parameters that will be used later on in the script, more available at: https://kb.paessler.com/en/topic/373-what-placeholders-can-i-use-with-prtg
  17. Param(
  18. [string]$Device,
  19. [string]$Status,
  20. [string]$Down,
  21. [string]$Group,
  22. [string]$CommentsSensor,
  23. [string]$Message,
  24. [string]$CommentsProbe
  25. )
  26. ## CONFIG
  27. # zendesk credentials
  28. $User = "youremail@example.com/token" # user must be verified to use the zendesk api
  29. $Pass = "abcdefghijklmnopqrstuvwxyz0123456789"
  30. # Author ID (numeric) for updates to existing tickets, ie: https://[example].zendesk.com/agent/#/users/370381808374
  31. $AuthorId = "1234567989"
  32. $prtgName = "PRTG"
  33. $prtgEmail = "prtg@example.com"
  34. $BaseUri = "https://[yourzendeskurl].zendesk.com"
  35. $updateExisting = 0
  36. $debug = 0 # set to 1 if you want to save a log file to the location referenced in $logPath
  37. $logPath = "C:\Users\Administrator\Desktop\log.txt"
  38. ## END CONFIG
  39. ### NOTE TO SELF! ###
  40. # some of these messages, after find/replace have EXTRA spaces that get stripped from zendesk!
  41. # copying the message from zendesk into a replace string will not work; you need to activate debug
  42. # mode to see the true construct of the message that needs to be filtered
  43. # remove the numeric string prefix, referenced on line 34
  44. $Message = $Message.Trim() -replace "^[0-9]*:",""
  45. $Message = $Message -replace "Error by lookup value ",""
  46. # inject a newline when there's a dash in the comments, to keep it clean
  47. $Message = $Message -replace " — ","`n"
  48. # if you want to log something other than the $Message var, simply replace the references in the conditional code block
  49. if ($debug -eq 1 -AND (Test-Path $logPath)) {
  50. Write-Output $Message $CommentsSensor | Out-File $logPath -Append
  51. } elseif ($debug -eq 1 -AND !(Test-Path $logPath)) {
  52. New-Item $logPath -ItemType file
  53. # redundant, but add-content was goobering up with unnecessary spaces between letters
  54. Write-Output $Message $CommentsSensor | Out-File $logPath -Append
  55. }
  56. $AuthHeader = @{
  57. "Content-Type" = "application/json";
  58. "Authorization" = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($User):$($Pass)"))
  59. }
  60. # call the zendesk api
  61. function Call-ZenDesk($Api, $Method, $Body) {
  62. # by default, powershell seems to want to use insecure/deprecated tls, the following fixes that
  63. [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  64. Invoke-RestMethod -Method $Method -Uri "$($BaseUri)$($Api)" -Headers $AuthHeader -Body $Body
  65. }
  66. # queue monitoring scripts don't use plural subjects, so adjust if the group match is printers, to avoid duplicate tickets
  67. if ($($Group) -eq 'Printers') {
  68. $Group = 'Printer'
  69. }
  70. $CommentBody = "$($CommentSsensor) $($Message) $($CommentsProbe)"
  71. $TicketSubject = "$($Device) $($Group) Issue"
  72. # formatting used to search tags & add new; for updating existing tickets
  73. $deviceTag = $Device.Trim() -replace ' ','-'
  74. # find existing tickets, if any
  75. $Transaction = @{
  76. query = "subject:$($TicketSubject) status:new status:open";
  77. }
  78. $SearchResults = Call-ZenDesk '/api/v2/search.json' Get $Transaction
  79. $existingNewTickets = $($SearchResults.count)
  80. Write-Host "Search results count: $existingNewTickets"
  81. if ($debug -eq 1) {
  82. Write-Output "$existingNewTickets new/open existing tickets for: $($TicketSubject)" | Out-File $logPath -Append
  83. }
  84. # Update existing ticket or create new
  85. if ($existingNewTickets -gt 0 -and $updateExisting -eq 1) {
  86. # there is at least one open ticket for this device tagged with PRTG
  87. $Ticket = $SearchResults.results.Item(0)
  88. Write-Host "Found a ticket! Updating ticket #$($Ticket.id)"
  89. $Transaction = @{
  90. ticket = @{
  91. comment = @{
  92. public = $false;
  93. body = $CommentBody;
  94. author_id = $AuthorId;
  95. }
  96. }
  97. }
  98. $Body = ConvertTo-Json($Transaction)
  99. Call-ZenDesk "/api/v2/tickets/$($Ticket.id).json" Put $Body
  100. if ($debug -eq 1) {
  101. Write-Output "Updated existing ticket: $($Ticket.id)" | Out-File $logPath -Append
  102. }
  103. } elseif ($existingNewTickets -gt 0 -and $updateExisting -eq 0 -and $debug -eq 1) {
  104. $existingMessage = "Existing ticket found; not updating or creating a new one."
  105. if ($debug -eq 1) {
  106. Write-Output $existingMessage | Out-File $logPath -Append
  107. }
  108. } elseif ($existingNewTickets -eq 0) {
  109. # no ticket found, create one; to add additional tags, separate by a comma
  110. $Tags = "monitoring-alert,$($deviceTag)"
  111. $CommentBody = "$($CommentBody)"
  112. $Transaction = @{
  113. ticket = @{
  114. requester = @{
  115. name = "$prtgName";
  116. email = "$prtgEmail"
  117. };
  118. subject = "$TicketSubject";
  119. type = "Incident";
  120. priority = "Normal";
  121. comment = @{
  122. public = $false;
  123. body = "$CommentBody";
  124. };
  125. tags = "$Tags"
  126. }
  127. }
  128. $Body = ConvertTo-Json $Transaction
  129. Call-ZenDesk "/api/v2/tickets.json" Post $Body
  130. }