NewZendeskMemo.ps1

#region help
<#
.SYNOPSIS
Creates a new Zendesk memo file for note-taking.
 
.DESCRIPTION
Creates a new Zendesk memo file for note-taking, and opens it in the default text editor.
The file is saved into a predefined location.
The file is pre-populated with ticket number, ticket subject, ticket URL and a timestamp.
 
.PARAMETER number
Zendesk ticket number (6-digit code).
 
.PARAMETER username
Zendesk API username.
 
.PARAMETER token
Zendesk API token.
 
.PARAMETER store
Path of Zendesk memo store location.
 
.EXAMPLE
New-ZendeskMemo -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
 
.EXAMPLE
New-ZendeskMemo -number 123456
 
.EXAMPLE
New-ZendeskMemo 123456
 
.EXAMPLE
Help New-ZendeskMemo -Full
 
.INPUTS
System.String
 
InputObject parameters are strings.
 
.OUTPUTS
External text file, eg C:\Memos\#123456.txt
 
.NOTES
FunctionName : New-ZendeskMemo
Created by : Alex Zakharov
Date Coded : 3/12/2021
 
.LINK
https://www.powershellgallery.com/packages/ZendeskTools/
#>

#endregion

function New-ZendeskMemo {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false,
                   HelpMessage="Zendesk ticket number.",
                   Position=0,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true)]
        [ValidatePattern('^\d\d\d\d\d\d$')]
        [string]$number,
        
        [Parameter(Mandatory=$false, HelpMessage="Zendesk API username.")] 
        [string]$username,
        
        [Parameter(Mandatory=$false, HelpMessage="Zendesk API token.")] 
        [string]$token,
        
        [Parameter(Mandatory=$false, HelpMessage="Zendesk memo store location.")] 
        [string]$store
    )
    BEGIN {
        $regpath = 'HKCU:\SOFTWARE\ZendeskTools'
        $api = 'https://smokeball.zendesk.com/api/v2/tickets'
        $site = 'https://smokeball.zendesk.com/agent/tickets'
        $settingsChanged = $false

        if ($store) {
            SetSetting 'Store' $store
            $settingsChanged = $true
        }

        if ($username) {
            SetSetting 'Username' $username
            $settingsChanged = $true
        }

        if ($token) {
            SetSetting 'Token' $token $true
            $settingsChanged = $true
        }

        $username = GetSetting 'Username'
        $token = GetSetting 'Token' $true
        $store = GetSetting 'Store'
    }
    PROCESS {
        if ($settingsChanged) {
            DisplayMessage "Settings saved."
        }

        if ($number -and $username -and $token -and $store) {
            CreateOrOpenZendeskMemo $number
        }
        elseif ($number) {
            DisplayMessage "Some settings are missing. Use the following command to add:"
            DisplayMessage "New-ZendeskMemo -store ""<path>"" -username ""<username>"" -token ""<token>"""
        }
        elseif (-not $settingsChanged) {
            try {
                $number = Get-Clipboard -Format "Text"
            }
            catch {
                $number = Read-Host -Prompt "Number"
            }

            if ($number) {
                CreateOrOpenZendeskMemo $number
            }
        }
    }
    END {

    }
}

New-Alias -Name ticket -Value New-ZendeskMemo

#region Execution examples

#ticket -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#ticket -token '$ecret'
#ticket -number 123456 -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#ticket 123456 -store "C:\Memos" -username "someone@acme.com" -token "P@ssword"
#ticket 111111
#111111 | ticket
#111111,111112,111113 | ticket
#ticket
#ticket 1

#endregion


###############################################################################
# Helper functions
###############################################################################

function DisplayMessage($message) {
    Write-Output "$message"
}

function DownloadZendeskTicket($ticketURI) {
    $headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($username):$($token)")); }
    $ticket = Invoke-RestMethod -Uri $ticketURI -Method Get -Headers $headers -ContentType "application/json"
    $ticket.ticket
}

function CreateOrOpenZendeskMemo($number) {
    $file = "$store\#$number.txt"
    $uri = "$api/$number.json" 
    $url = "$site/$number"
    $timestamp = Get-Date -Format "dddd dd/MM/yyyy HH:mm"

    try {
        if (-not(Test-Path -Path $file -PathType Leaf)) {
            $subject = (DownloadZendeskTicket($uri)).subject
            $title = "#$number - $subject"
            $separator = "=" * ($title.Length + 10)

            $title | Out-File $file -Append
            $separator | Out-File $file -Append
            $url | Out-File $file -Append

            DisplayMessage "Zendesk memo file CREATED: $file"
        }
        else {
            DisplayMessage "Zendesk memo file OPENED: $file"
        }

        $separator = "`r`n" + "-" * $timestamp.Length

        $separator | Out-File $file -Append
        $timestamp | Out-File $file -Append

        Invoke-Item $file
    }
    catch {
        throw $_.Exception.Message
    }
}

function SetSetting($key, $value, $secure = $false)
{
    if (-not (Test-Path "$regpath")) {
        New-Item -Path $regpath  | Out-Null
    }

    if ($secure) {
        $value = $value | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
    }

    New-ItemProperty -Path $regpath -Name $key -PropertyType String -Value $value -Force | Out-Null
}

function GetSetting($key, $secure = $false)
{
    if (Test-Path "$regpath") {
        $value = (Get-ItemProperty $regpath).$key
        if ($secure) {
            $secureValue = $value | ConvertTo-SecureString
            $value = [System.Net.NetworkCredential]::new("", $secureValue).Password
        }
        $value
    }
}