1

I do understand that this question has been asked and answered many times, but I'm getting an error that I've not seen on the forums and I'm hoping someone might know what I'm doing wrong.

So, what am I doing? I am using the Expensify API to automate the provisioning of new hires. I already have a 2,000 line new hire script and I'm just trying to add more SaaS apps to it so I have to do... less.

The cURL request is supposed to look like this:

curl -X POST 'https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations' \
-H 'Expect:' \
-F 'requestJobDescription={
    "type": "update",
    "credentials": {
        "partnerUserID": "_REPLACE_",
        "partnerUserSecret": "_REPLACE_"
    },
    "inputSettings": {
        "type": "employees",
        "policyID":"0123456789ABCDEF",
        "fileType": "csv"
    }
}' \
-F 'data=@employeeData.csv'

And my script looks like this:

$expensify_csv = @(
    [pscustomobject]@{
    EmployeeEmail = $email
    ManagerEmail  = $mngr_email
    Admin  = $expensify_admin
    ForwardManagerEmail = $fwd_email
    }
) | Export-Csv -Path C:\expensify.csv -NoTypeInformation

$expensify_csv = [IO.File]::ReadAllText('C:\expensify.csv');

$json = [ordered]@{
    "requestJobDescription" = @{
        "type" = "update";
        "credentials" = @{
            "partnerUserID" = $expensify_id;
            "partnerUserSecret" = $expensify_secret;
        }
        "inputSettings" = @{
            "type" = "employees";
            "policyID" = "F9CC59BCD4521BB2";
            "fileType" = "csv";
        }
    };
    "data" = $expensify_csv
} | ConvertTo-Json -Depth 10

Write-Host $json

$check = Invoke-RestMethod `
    -Method Post `
    -Uri $expensify_url `
    -Body $json `
    -ContentType multipart/form-data `

Write-Host $check

exit

And the error that is being returned:

Invoke-RestMethod :

        Error

            body{
                font-family: Arial;
            }
            pre{
                padding: 5px;
                background-color: #ddd;
                border-top: 2px solid #999;
            }



        An error occurred
        Internal Server Error

It looks like the error has something to do with CSS? I have no idea though. Very strange. I've been battling this API for some time now and I'd appreciate any feedback!

1 Answers1

1

UPDATED

Now I see what the problem is, curl has that -F to add one more request inside the body and curl does some additional edits in the background, like adding a boundary. This is not native to Invoke-RestMethod so we need to write it.

$FilePath = 'C:\employeeData.csv';
$URL = 'https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations';

$importedCSV = Get-Content $filepath -Raw
$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "`r`n";

$bodyhash = [ordered]@{
    "type" = "update";
    "credentials" = @{
        "partnerUserID" = "_REPLACE_";
        "partnerUserSecret" = "_REPLACE_";
    }
    "inputSettings" = @{
        "type" = "employees";
        "policyID" = "F9CC59BCD4521BB2";
        "fileType" = "csv";
    }
} 

$bodyJSON = $bodyhash | ConvertTo-Json

$nestedBody = ( 
    "--$boundary",
    "Content-Disposition: form-data; name=`"requestJobDescription`"",
    "Content-Type: application/json$LF",
    "$($bodyJSON)",
    "--$boundary",
    "Content-Disposition: form-data; name=`"data`"; filename=`"employeeData.csv`"",
    "Content-Type: application/octet-stream$LF",
    $importedCSV,
    "--$boundary--$LF" 
) -join $LF

$sendRequest=@{
    Uri = $URL 
    Method = "Post"
    ContentType = "multipart/form-data; boundary=`"$boundary`""
    Body = $nestedBody
}

Invoke-RestMethod @sendRequest

This example, gives me Authentication Error as I would expect, unlike before with the internal server error .

2 of the answers (not the accepted one) from the following post lead me to that solution - powershell invoke-restmethod multipart/form-data

P.S. Working on this issue, lead to the resolution on my own issue on how to do nested HTTP request with powershell.

Vasil Nikolov
  • 667
  • 6
  • 16
  • So I made those changes, but I'm still seeing the same error... and my $body variable looks like this: `System.Collections.DictionaryEntry System.Collections.DictionaryEntry` – Derek Ritchison Oct 26 '19 at 16:10
  • @DerekRitchison I have updated my answer, try the new solution and let me know. – Vasil Nikolov Oct 26 '19 at 21:30
  • Holy crap. I just got a 200 response from Expensify. Dude, this is amazing and I'm not sure I ever would have figured that out on my own. I was about to give up on PowerShell and see if I could just do it easier in Ruby. You're awesome. Would upvote this 100 times if I could. – Derek Ritchison Oct 27 '19 at 19:24
  • Happy to hear that, if you think that is sufficient, you can mark my response as an answer and upvote it to help others and myself as well. – Vasil Nikolov Oct 27 '19 at 19:50
  • I did upvote but unfortunately my reputation is not high enough yet. I need to work on that. – Derek Ritchison Oct 27 '19 at 21:30