public/Invoke-XPostOAuth2.ps1

function Invoke-XPostOAuth2 {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)][string]$AccessToken,
        [Parameter(Mandatory=$true)][string]$Text,
        [string]$Endpoint = "https://api.twitter.com/2/tweets"
    )
    process {
        try {
            $headers = @{
                "Authorization" = "Bearer $AccessToken"
                "Content-Type"  = "application/json"
            }
            $body = @{ text = $Text } | ConvertTo-Json -Compress
            $response = Invoke-RestMethod -Uri $Endpoint -Method Post -Headers $headers -Body $body -ErrorAction Stop

            $rateLimit = $response.Headers["x-rate-limit-limit"]
            $rateRemaining = $response.Headers["x-rate-limit-remaining"]
            $rateReset = $response.Headers["x-rate-limit-reset"]
            $resetTime = if ($rateReset) { [timezone]::CurrentTimeZone.ToLocalTime([datetime]::UnixEpoch.AddSeconds($rateReset)) } else { "N/A" }

            Write-Output "Post successful! Status: 200"
            Write-Output "Response Body: $response"
            Write-Output "Rate Limits: Limit=$rateLimit, Remaining=$rateRemaining, Resets At=$resetTime (local time)"

            if ($rateRemaining -le 10) {
                $wait = ([datetime]::UnixEpoch.AddSeconds($rateReset) - (Get-Date)).TotalSeconds
                Start-Sleep -Seconds $wait
            }
        } catch [System.Net.WebException] {
            $resp = $_.Exception.Response
            $errStream = [System.IO.StreamReader]::new($resp.GetResponseStream()).ReadToEnd()
            Write-Output "Post failed! HTTP Status: $($resp.StatusCode)"
            Write-Output "Error Body: $errStream"
        } catch {
            Write-Output "Post failed! Unexpected error: $($_.Exception.Message)"
        }
    }
}