Public/Send-PushoverNotification.ps1

# .SYNOPSIS
# Sends a Pushover (https://pushover.net) notification
function Send-PushoverNotification
{
    [CmdletBinding(DefaultParameterSetName = 'Html')]
    param
    (
        # Unique token for your Pushover application, received when
        # you registered your application on https://pushover.net
        [Parameter(Mandatory)]
        [ValidatePattern('[A-Za-z0-9]{30}')]
        [string]$ApplicationToken,

        # The Pushover user/group key (not e-mail address) of the intended
        # recipient, as received when registering the user or group on
        # https://pushover.net
        [Parameter(Mandatory)]
        [ValidatePattern('[A-Za-z0-9]{30}')]
        [string]$Recipient,

        # The notification's title. If none is given, your app's name is used
        [ValidateLength(1, 250)]
        [string]$Title,

        # The actual notification message
        [Parameter(Mandatory)]
        [ValidateLength(1, 1024)]
        [string]$Message,

        # When set, some basic HTML formatting tags are supported in $Message
        [Parameter(ParameterSetName = 'Html')]
        [switch]$Html,

        # When set, $Message is rendered in a monospaced font
        [Parameter(ParameterSetName = 'Monospace')]
        [switch]$Monospace,

        # Additional url to be rendered as a clickable link on the receiving device
        [ValidateLength(1, 250)]
        [string]$SupplementaryUrl,

        # Human-friendly title for the additional url; defaults to the
        # supplementary url itself
        [ValidateLength(1, 100)]
        [string]$SupplementaryUrlTitle,

        # Image attachment to be sent to devices that support it. Also supports http:// and https:// urls.
        [string]$AttachmentFileName,

        # Device names to send the notification to; if not set, the notification
        # is sent to all active devices for the given $Recipient
        [ValidatePattern('[A-Za-z0-9_-]{1,25}')]
        [string[]]$Device,

        # The notification sound to play on the receiving device; if not set,
        # the default notification sound from the device's Pushover settings
        # will be played
        [ValidateSet('pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none')]
        [string]$Sound,

        # Priority for the notification
        # - Lowest: will not generate any notification. On iOS, the application badge number will be increased
        # - Low: will not generate any sound or vibration, but will still generate a popup/scrolling notification depending on the client operating system
        # - Normal: will trigger sound, vibration, and display an alert according to the user's device settings
        # - High: will always play a sound and vibrate (if the user's device is configured to) regardless of the delivery time
        [ValidateSet('Lowest', 'Low', 'Normal', 'High')]
        [string]$Priority = 'Normal',

        # If set, the cmdlet returns the response message received from the Pushover server
        [switch]$PassThru
    )

    $Uri = "https://api.pushover.net/1/messages.json"

    $Form = @{
        token   = $ApplicationToken
        user    = $Recipient
        message = $Message
    }

    if ($Title) { $Form.title = $Title }
    if ($Device) { $Form.device = $Device -join ',' }
    if ($Html) { $Form.html = 1 }
    if ($Monospace) { $Form.monospace = 1 }
    if ($Sound) { $Form.sound = $Sound }

    if ($SupplementaryUrl)
    {
        $Form.url = $SupplementaryUrl
        if ($SupplementaryUrlTitle)
        {
            $Form.url_title = $SupplementaryUrlTitle
        }
    }

    [string]$TempFileName

    if ($AttachmentFileName)
    {
        [uri]$AttachmentUri = $null;
        $IsUri = [uri]::TryCreate($AttachmentFileName, [System.UriKind]::Absolute, [ref]$AttachmentUri)
        $IsUri = $IsUri -and ($AttachmentUri.Scheme -in [uri]::UriSchemeHttp, [uri]::UriSchemeHttps)

        if ($IsUri)
        {
            $TempFileName = New-TemporaryFile
            trap { Remove-Item -Path $TempFileName -ErrorAction SilentlyContinue }
            Invoke-WebRequest -Uri $AttachmentUri -OutFile $TempFileName
            $Form.attachment = Get-Item -Path $TempFileName
        }
        else
        {
            $Form.attachment = Get-Item -Path $AttachmentFileName
        }
    }

    switch ($Priority)
    {
        'Lowest' { $Form.priority = -2 }
        'Low' { $Form.priority = -1 }
        'Normal' { $Form.priority = 0 }
        'High' { $Form.priority = 1 }
        default { throw "Unsupported priority '$Priority'" }
    }

    $Response = Invoke-RestMethod -Uri $Uri -Method Post -Form $Form

    if ($TempFileName)
    {
        Remove-Item -Path $TempFileName -ErrorAction SilentlyContinue
    }

    if ($PassThru)
    {
        $Response
    }
}