Public/Get-ShellPhishMySongStats.ps1

function Get-ShellPhishMySongStats {
    <#
    .SYNOPSIS
        Counts how many times a user has seen each song performed live.
    .PARAMETER Username
        Phish.net username.
    .PARAMETER SortBy
        Sort by 'count' (most seen first) or 'song' (alphabetical). Default: count.
    .PARAMETER ExportPath
        Optional file path (.csv or .json) to export results.
    .PARAMETER DelayMs
        Delay in milliseconds between API calls. Default 500.
    .EXAMPLE
        PS C:\> Get-ShellPhishMySongStats -Username wilson
    .EXAMPLE
        PS C:\> Get-ShellPhishMySongStats -Username wilson -SortBy song
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [string]$Username,

        [Parameter()]
        [ValidateSet('count','song')]
        [string]$SortBy = 'count',

        [Parameter()]
        [string]$ExportPath,

        [Parameter()]
        [int]$DelayMs = 500
    )

    Write-Verbose "Fetching attendance for $Username..."
    $attendance = (Get-ShellPhishAttendance -Username $Username).data

    if (-not $attendance) {
        Write-Warning "No attendance records found for $Username"
        return
    }

    Write-Verbose "Found $($attendance.Count) show(s). Fetching setlists..."
    $allSongs = @()
    foreach ($record in $attendance) {
        Start-Sleep -Milliseconds $DelayMs
        $setlist = (Get-ShellPhishSetlists -ShowId $record.showid).data
        if ($setlist) {
            foreach ($entry in $setlist) {
                $allSongs += [PSCustomObject]@{
                    Song     = $entry.song
                    Slug     = $entry.slug
                    ShowDate = $record.showdate
                }
            }
        }
    }

    $grouped = $allSongs | Group-Object -Property Song | ForEach-Object {
        [PSCustomObject]@{
            Song      = $_.Name
            TimeSeen  = $_.Count
            FirstSeen = ($_.Group | Sort-Object ShowDate | Select-Object -First 1).ShowDate
            LastSeen  = ($_.Group | Sort-Object ShowDate | Select-Object -Last 1).ShowDate
        }
    }

    $sorted = switch ($SortBy) {
        'count' { $grouped | Sort-Object TimeSeen -Descending }
        'song'  { $grouped | Sort-Object Song }
    }

    Export-ShellPhishData -Data $sorted -ExportPath $ExportPath
}