Public/Send-Pushover.ps1
function Send-Pushover { <# .SYNOPSIS Sends a message to the Pushover API .EXAMPLE PS C:\> Send-PushoverMessage -Token $token -User $user -Title 'What time is it?' -Message 'It''s time for lunch' Sends a notification to the user or group specified in the $user string variable, from the application designed by the application API token value in $token .EXAMPLE PS C:\> Send-PushoverMessage -Token $token -User $user -Title 'What time is it?' -Message 'It''s time for lunch' -MessagePriority Emergency -RetryInterval (New-TimeSpan -Seconds 60) -ExpireAfter (New-TimeSpan -Hours 1) Sends the same notification as Example 1, except with emergency priority which results in the notification being repeated every 60 seconds, until an hour has passed or the message has been acknowledged. .OUTPUTS Returns a receipt string if the MessagePriority value was 'Emergency' (2) #> [CmdletBinding()] param ( # Specifies the application API token/key from which the Pushover notification should be sent. [Parameter()] [ValidateNotNullOrEmpty()] [securestring] $Token, # Specifies the User or Group identifier to which the Pushover message should be sent. [Parameter()] [ValidateNotNullOrEmpty()] [securestring] $User, # Optionally specifies one or more devices to which notifications should be sent. Useful for sending notifications to a targetted device instead of all of the user's devices. [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Device, # Specifies the title of the Pushover notification. The default will be the application name configured for the application API token supplied. [Parameter()] [string] $Title, # Specifies the message to be sent with the Pushover notification. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Message, # Optionally specifies an image in bytes to be attached to the message. [Parameter()] [byte[]] $Attachment, # Optionally specifies the file name to associate with the attachment. [Parameter()] [string] $FileName = 'attachment.jpg', # Optionally specifies a supplementary URL associated with the message. [Parameter()] [ValidateNotNullOrEmpty()] [uri] $Url, # Optionally specifies a title for the supplementary URL if specified. [Parameter()] [ValidateNotNullOrEmpty()] [string] $UrlTitle, # Parameter help description [Parameter()] [MessagePriority] $MessagePriority, # Specifies the interval between emergency Pushover notifications. Pushover will retry until the message is acknowledged, or expired. Valid only with MessagePriority of 'Emergency'. [Parameter()] [ValidateScript({ if ($_.TotalSeconds -lt 30) { throw 'RetryInterval must be at least 30 seconds' } if ($_.TotalSeconds -gt 10800) { throw 'RetryInterval cannot exceed maximum ExpireAfter value of 3 hours' } $true })] [timespan] $RetryInterval = (New-TimeSpan -Minutes 1), # Specifies the amount of time unacknowledged notifications will be retried before Pushover stops sending notifications. Valid only with MessagePriority of 'Emergency'. [Parameter()] [ValidateScript({ if ($_.TotalSeconds -le 30) { throw 'ExpireAfter must be greater than the minimum RetryInterval value of 30 seconds' } if ($_.TotalSeconds -gt 10800) { throw 'ExpireAfter cannot exceed 3 hours' } $true })] [timespan] $ExpireAfter = (New-TimeSpan -Minutes 10), # Optionally specifies the timestamp associated with the message. Default is DateTime.Now. [Parameter()] [datetime] $Timestamp = (Get-Date), # Optionally specifies one or more tags to associate with the Pushover notification. Tags can be used to cancel emergency notifications in bulk. [Parameter()] [string[]] $Tags ) begin { $uri = $script:PushoverApiUri + '/messages.json' $config = Get-PushoverConfig } process { if ($null -eq $Token -and $null -eq $config.Token) { $Token = $config.Token if ($null -eq $Token) { throw "Token not provided and no default application token has been set using Set-PushoverConfig." } } if ($null -eq $User -and $null -eq (Get-PushoverConfig).User) { $User = $config.User if ($null -eq $User) { throw "User not provided and no default user id has been set using Set-PushoverConfig." } } $deviceList = if ($null -ne $Device) { [string]::Join(',', $Device) } else { $null } $tagList = if ($null -ne $Tags) { [string]::Join(',', $Tags) } else { $null } $body = [ordered]@{ token = ([pscredential]::new('unused', $Token)).GetNetworkCredential().Password user = ([pscredential]::new('unused', $User)).GetNetworkCredential().Password device = $deviceList title = $Title message = $Message url = $Url url_title = $UrlTitle priority = [int]$MessagePriority retry = [int]$RetryInterval.TotalSeconds expire = [int]$ExpireAfter.TotalSeconds timestamp = [int]([datetimeoffset]::new($Timestamp).ToUnixTimeMilliseconds() / 1000) tags = $tagList } try { if ($Attachment.Length -eq 0) { $bodyJson = $body | ConvertTo-Json Write-Verbose "Message body:`r`n$bodyJson" $response = Invoke-RestMethod -Method Post -Uri $uri -Body $bodyJson -ContentType application/json -UseBasicParsing } else { $response = Send-MessageWithAttachment -Body $body -Attachment $Attachment -FileName $FileName } } catch { Write-Verbose 'Handling HTTP error in Invoke-RestMethod response' $statusCode = $_.Exception.Response.StatusCode.value__ Write-Verbose "HTTP status code $statusCode" if ($statusCode -lt 400 -or $statusCode -gt 499) { throw } try { Write-Verbose 'Parsing HTTP request error response' $stream = $_.Exception.Response.GetResponseStream() $reader = [io.streamreader]::new($stream) $response = $reader.ReadToEnd() | ConvertFrom-Json if ([string]::IsNullOrWhiteSpace($response)) { throw $_ } Write-Verbose "Response body:`r`n$response" } finally { $reader.Dispose() } } if ($response.status -ne 1) { if ($null -ne $response.error) { Write-Error $response.error } elseif ($null -ne $response.errors) { foreach ($problem in $response.errors) { Write-Error $problem } } else { $response } } if ($null -ne $response.receipt) { Write-Output $response.receipt } } } |