Powershell to update tags using API

MarkW2MarkW2 Posts: 3Expensify Customer

I'm using Invoke-Webrequest to emulate the curl command in the API for updating tags using a file. I've used community posts to resolve most of my issues. I can successfully connect with the API and post the JSON portion. However, I've not been able to upload the file that contains the tags. The curl example shows this as '[email protected]' after the JSON portion of the post. I've tried Invoke-RestMethod as well. No matter how I format it, I can't seem to emulate that portion of the curl and the response is always "Tag file is missing". Any help would be appreciated.

Answers

  • MarkW2MarkW2 Posts: 3Expensify Customer

    further examined the example by DMuncy and encoded the filename to get past the "Tag file is missing"

    Now I get "Could not split the file on multiple lines. The file probably does not have proper End Of Line characters"

    Confirmed csv has CR LF end of each line.

    Following is the current code


    $ptruserID = 

    $ptrusersec = 

    $PolicyID = 

    $dependency = $false

    $glCodes =$true

    $header = $true

    $setRequired=$false

    $json = [ordered]@{

        "type"="update";

        "credentials"[email protected]{

          "partnerUserID"=$ptruserID;

          "partnerUserSecret"=$ptrusersec

        };

        "inputSettings"[email protected]{

          "type"="policy";

          "policyIDList"[email protected]($PolicyID)

        };

        "tags"[email protected]{

          "action"="replace";

          "source"="file";

          "config"[email protected]{

              "dependency"=$dependency;

              "glCodes"=$glCodes;

              "header"=$header;

              "setRequired"=$setRequired;

              "fileType"="csv"

              };

        };

      } | ConvertTo-Json

    $url = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations"

    $request = "requestJobDescription="

    $file = Get-Item -Path C:\PM_to_Expensify.csv

    $encode = [System.Web.HttpUtility]::UrlEncode($file)

    $body = $request + $json + "'&file='$encode"


    Invoke-Webrequest -uri $url -body $body -Method Post

  • Francois LaithierFrancois Laithier Posts: 20Expensify Team Expensify Success Coach
    edited November 8
    Hi there,

    Any chance you can check the value of [System.Web.HttpUtility]::UrlEncode($file) and see if the line breaks are preserved? The result shouldn't be on one single line.

    If the line breaks are still present as expected, can you try to convert them to just LF (instead of CRLF)?

    Cheers
  • MarkW2MarkW2 Posts: 3Expensify Customer
    I assumed that the API is looking for two inputs ("requestjobdescription" and "file"), so I did a slight rewrite so make those elements of an array in the Powershell.  It didn't seem to make a difference.  No matter what I try, I get the same 666 response code (should I take that as a sign?).  The API seems to accept the "requestjobdescription" component, but I have no idea what the API is expecting for the "file" input.  I've tried:
    • full path to the file
    • relative path to the file
    • encoded paths (using [System.Web.HttpUtility]::UrlEncode)
    • content of the file using Get-Content
    • encoded content of the file
    For the file itself, I've tried:
    • File with header information
    • File with just a single line and no header (header set to $false)
    • CRLF for EOL
    • LF for EOL
  • Francois LaithierFrancois Laithier Posts: 20Expensify Team Expensify Success Coach
    The API does expect a second parameter called file if your requestJobDescription contains:
            "tags": {
                "action": "replace",
                "source":"file",
            "..."
    
    which is the case for you. The fact that you received a Could not split the file on multiple lines error means that the data in your CSV file was transmitted to our API, but the line breaks weren't correct, e.g. if your CSV file contained:
    a,b,c
    d,e,f
    
    then we received
    a,b,cd,e,f
    
    Since you only have one level of tags, you can also directly pass them as JSON objects in the requestJobDescription:
    {
        "type": "update",
        "credentials": {
            "...": "...",
        },
        "...": "...",
        "tags": {
            "data": [
                {
                    "name": "Tag Level 1",
                    "setRequired": true,
                    "tags": [
                        {
                            "name": "Tag 1",
                            "glCode": "Tag 1 GL Code"
                        },
                        {
                            "name": "Tag 2",
                            "glCode": "Tag 2 GL Code"
                        }
                    ]
                }
            ]
        }
    }
    
Sign In or Register to comment.