Public/ps1/Html/Start-ApprxrJobHtml.ps1

<#
    .SYNOPSIS
    Executes an HTTP job for Apprxr, handling authentication, headers, and response parsing.
 
    .DESCRIPTION
    Sends an HTTP request (GET or POST) to a specified URL with provided headers, body, and authentication. Handles authentication via Set-ApprxrAuthenticationRoute, logs all request and response details, and returns a structured result. Handles errors and extracts detailed error information from the response.
 
    .PARAMETER taskInformation
    An object containing the job parameters, including url, httpMethod, headers, body, contentType, channelId, id, and type.
 
    .EXAMPLE
    Start-ApprxrJobHtml -taskInformation @{ url = 'https://example.com/api'; httpMethod = 'POST'; headers = @{ Authorization = 'Bearer ...' }; body = $jsonBody; contentType = 'application/json' }
 
    .NOTES
    Used for running HTTP-based jobs in Apprxr automation, including REST API calls with authentication and custom headers.
#>

function Start-ApprxrJobHtml {
    param (
        $taskInformation
    )

    if (-not $taskInformation.url) {
        return @{
            message= "No url found"
            sucess= $false
        }
    }

    # Populate authentication info using Set-ApprxrAuthenticationRoute
    $authInfo = Set-ApprxrAuthenticationRoute -hostURI $taskInformation.url -channelId $taskInformation.channelId -id $taskInformation.id -type $taskInformation.type
    if ($authInfo) {
        # Merge authentication info into $taskInformation
        $taskInformation | Add-Member -MemberType NoteProperty -Name 'Authentication' -Value $authInfo.Authentication -Force
        if ($authInfo.PSObject.Properties['username']) {
            $taskInformation | Add-Member -MemberType NoteProperty -Name 'username' -Value $authInfo.username -Force
        }
        if ($authInfo.PSObject.Properties['password']) {
            $taskInformation | Add-Member -MemberType NoteProperty -Name 'password' -Value $authInfo.password -Force
        }
    }

    $result = @{}
    $headers = @{}
    $taskInformation.headers.psobject.Properties | ForEach-Object {
        $headers[$_.Name] = $_.Value
    }

    Log ("Headers: $($headers | Out-String)")
    Log ("Body: $($taskInformation.body | Out-String)")
    Log ("Method: $($taskInformation.httpMethod | Out-String)")
    Log ("Url: $($taskInformation.url | Out-String)")
    Log ("ContentType: $($taskInformation.contentType | Out-String)")

    try {
        $invokeParams = @{
            Uri = $taskInformation.url
            Method = $taskInformation.httpMethod
            Headers = $headers
            ErrorAction = 'Stop'
        }
        if ($taskInformation.body) {
            $bodyToSend = $taskInformation.body
            if (-not $taskInformation.httpMethod) { $taskInformation.httpMethod = "POST" }
            if (-not $taskInformation.contentType) { $taskInformation.contentType = "application/json" }
            $invokeParams.ContentType = $taskInformation.contentType
            # If body is an object and content type is application/json, serialize to JSON
            if ($taskInformation.contentType -eq 'application/json' -and ($bodyToSend -is [PSCustomObject] -or $bodyToSend -is [hashtable])) {
                $bodyToSend = $bodyToSend | ConvertTo-Json -Depth 10
            }
            $invokeParams.Body = $bodyToSend
        } else {
            if (-not $taskInformation.httpMethod) { $taskInformation.httpMethod = "GET" }
            if ($taskInformation.body) {
                $bodyToSend = $taskInformation.body
                # If body is an object and content type is application/json, serialize to JSON
                if ($taskInformation.contentType -eq 'application/json' -and ($bodyToSend -is [PSCustomObject] -or $bodyToSend -is [hashtable])) {
                    $bodyToSend = $bodyToSend | ConvertTo-Json -Depth 10
                }
                $invokeParams.Body = $bodyToSend
                $invokeParams.ContentType = $taskInformation.contentType
            }
        }
        
     
        $response = Invoke-webrequest @invokeParams
        $cookiesObj = Get-CookiesObject $response.Cookies
        if ($null -eq $cookiesObj) { $cookiesObj = @() }
        $headersObj = @{}
        if ($response.PSObject.Properties['Headers']) {
            foreach ($key in $response.Headers.Keys) {
                $headersObj[$key] = $response.Headers[$key]
            }
        } elseif ($response.PSObject.Properties['BaseResponse'] -and $response.BaseResponse.Headers) {
            foreach ($key in $response.BaseResponse.Headers.Keys) {
                $headersObj[$key] = $response.BaseResponse.Headers[$key]
            }
        }
        $resultObj = @{}
        if ($response.PSObject.Properties["StatusCode"]) { $resultObj.StatusCode = $response.StatusCode }
        if ($response.PSObject.Properties["StatusDescription"]) { $resultObj.StatusDescription = $response.StatusDescription }
        $resultObj.Headers = $headersObj
        $resultObj.Cookies = $cookiesObj
        if ($response.PSObject.Properties["Content"]) { $resultObj.Content = $response.Content } else { $resultObj.Content = $response }
        if ($response.PSObject.Properties["RawContent"]) { $resultObj.RawContent = $response.RawContent }
        if ($response.PSObject.Properties["RawContentLength"]) { $resultObj.RawContentLength = $response.RawContentLength }
        if ($response.PSObject.Properties["BaseResponse"]) { $resultObj.BaseResponse = $response.BaseResponse }
        Log ("Response: $($resultObj | ConvertTo-Json -Depth 100)")
        return @{
            message = $resultObj | ConvertTo-Json -Depth 100
            sucess = $true
        }
    } catch {
        $headersObj = @{}
        $cookiesObj = @()
        $errorObj = @{}
        $errorContent = $null
        if ($_.Exception.Response) {
            $resp = $_.Exception.Response
            # Try to extract the raw response body (the red text)
            try {
                $reader = [System.IO.StreamReader]::new($resp.GetResponseStream())
                $errorContent = $reader.ReadToEnd()
                $reader.Close()
            } catch {}
            if ($resp.Headers) {
                foreach ($key in $resp.Headers.Keys) {
                    $headersObj[$key] = $resp.Headers[$key]
                }
            }
            $cookiesObj = Get-CookiesObject $resp.Cookies
            $errorObj.Headers = $headersObj
            $errorObj.Cookies = $cookiesObj
            if ($resp.StatusCode) { $errorObj.StatusCode = $resp.StatusCode }
            if ($resp.StatusDescription) { $errorObj.StatusDescription = $resp.StatusDescription }
            if ($resp.Content) { $errorObj.Content = $resp.Content }
            if ($resp.RawContent) { $errorObj.RawContent = $resp.RawContent }
            if ($resp.RawContentLength) { $errorObj.RawContentLength = $resp.RawContentLength }
            if ($resp.BaseResponse) { $errorObj.BaseResponse = $resp.BaseResponse }
            if ($_.Exception.Message) { $errorObj.Message = $_.Exception.Message }
            if ($errorContent) { $errorObj.ErrorContent = $errorContent }
        } else {
            if ($_.Exception.Message) { $errorObj.Message = $_.Exception.Message }
        }
        if ($null -eq $errorObj -or $errorObj.Count -eq 0) {
            Log ("Exception: $($_.Exception.Message)")
        } else {
            Log ("Error: $($errorObj | ConvertTo-Json -Depth 100)")
        }
        return @{
            message = if ($null -eq $errorObj -or $errorObj.Count -eq 0) { $_.Exception.Message } else { $errorObj | ConvertTo-Json -Depth 100 }
            messageCode = if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { $null }
            sucess = $false
        }
    }

}