BetBetter.psm1

# BetBetter - the free Bet Better sports model API from PowerShell. No API key.
# Model estimates, not advice. Data CC BY 4.0, credit Bet Better (https://betbetter.world). 18+.

$script:BaseUrl = 'https://betbetter.world'
$script:UserAgent = 'BetBetter-PSGallery/1.1.0 (+https://betbetter.world/api)'
$script:Leagues = @('afl','mlb','nba','nfl','nhl','ncaaf','nrl','ufc','wnba','cricket',
  'tennis/atp','tennis/wta','soccer/epl','soccer/la-liga','soccer/serie-a',
  'soccer/bundesliga','soccer/ligue-1','soccer/world-cup')

function Invoke-BetBetterJson([string]$Path) {
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    $raw = Invoke-WebRequest -Uri "$script:BaseUrl$Path`?format=json" -UserAgent $script:UserAgent -UseBasicParsing -TimeoutSec 30
    return ($raw.Content | ConvertFrom-Json)
}

function Invoke-BetBetterCsv([string]$Path) {
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    $raw = Invoke-WebRequest -Uri "$script:BaseUrl$Path`?format=csv" -UserAgent $script:UserAgent -UseBasicParsing -TimeoutSec 30
    $lines = $raw.Content -split "`r?`n" | Where-Object { $_ -and -not $_.StartsWith('#') }
    return ($lines | ConvertFrom-Csv)
}

function Resolve-BetBetterLeague([string]$League) {
    $l = $League.Trim().Trim('/').ToLower()
    if ($script:Leagues -notcontains $l) {
        throw "Unknown league '$League'. Valid options: $($script:Leagues -join ', ')"
    }
    return $l
}

function Get-BetBetterLeague {
    <#
    .SYNOPSIS
        Lists the league codes the free Bet Better API serves.
    #>

    [CmdletBinding()]
    param()
    $script:Leagues
}

function Get-BetBetterPicks {
    <#
    .SYNOPSIS
        Model selections for a league from the free Bet Better API (no key).
    .PARAMETER League
        A league code from Get-BetBetterLeague, e.g. nfl, nba, soccer/epl.
    .EXAMPLE
        Get-BetBetterPicks -League nfl | Format-Table
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)][string]$League)
    (Invoke-BetBetterJson "/$(Resolve-BetBetterLeague $League)/picks").picks
}

function Get-BetBetterProps {
    <#
    .SYNOPSIS
        Player-prop model selections for a league from the free Bet Better API.
    .PARAMETER League
        A league code from Get-BetBetterLeague.
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)][string]$League)
    (Invoke-BetBetterJson "/$(Resolve-BetBetterLeague $League)/prop-bets").picks
}

function Get-BetBetterScores {
    <#
    .SYNOPSIS
        Projected final score for every upcoming game in a sport.
    .PARAMETER Sport
        A sport code, e.g. nfl, nba, mlb.
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)][string]$Sport)
    (Invoke-BetBetterJson "/predicted-scores/$($Sport.Trim().Trim('/').ToLower())").games
}

function Get-BetBetterRankings {
    <#
    .SYNOPSIS
        Results-only power rankings for a sport.
    .PARAMETER Sport
        A sport code, e.g. nfl, nba.
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)][string]$Sport)
    Invoke-BetBetterCsv "/power-rankings/$($Sport.Trim().Trim('/').ToLower())"
}

Export-ModuleMember -Function Get-BetBetterLeague, Get-BetBetterPicks, Get-BetBetterProps, Get-BetBetterScores, Get-BetBetterRankings