Morning everyone!
Been working on this for a few and just can't get this thing to work correctly. Hopefully this can be a learning experience along with a fix.
I am working on creating a flow between SP and Bill.com. When a file comes in to a specific email address, AP@weirdpeople.com, I wish for this file to be uploaded to Bill.com using their API. At the moment, I have had several responses of 200, but the "sessionId" would be incorrect, when it isn't, or the "session ended abruptly". I am not a big developer in this area, but assume the code coming from M365 isn't quite what Bill.com is looking for. Going to try and keep this short....
Very first step in this flow is the receipt of a file sent to a specific email. (Works Great)
Next step is to take this file and place it within a specific folder within Sharepoint (Works Great)
Now, POST to logon to Bill.com (provided example):
as per Sandbox sign in instructions
curl --request POST \
--url 'https://api-sandbox.bill.com/api/v2/Login.json' \
--header 'accept: application/json' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'userName= billservice.account ' \
--data 'password=01GET-ASDFG-ADSFG-ASDFG-ASDFG-ASDFG-ASDFG-CQk6f' ' \
--data 'orgId=12345ASDFGHJKLOI3axg' \
--data 'devKey=05QWEASDFGMHIJK2078'
My post to logon (Actual post request): (Works Great)
curl --request POST \
--url 'https://api-sandbox.bill.com/api/v2/Login.json' \
--header 'accept: application/json' \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'userName=billservice.account' \
--data 'password=01GET-ASDFG-ADSFG-ASDFG-ASDFG-ASDFG-ASDFG-CQk6f' \
--data 'orgId=12345ASDFGHJKLOI3axg' \
--data 'devKey=05QWEASDFGMHIJK2078'
--form 'data="{\"id\":\"{object_id}\", \"fileName\":\"{file_name}\"}"'
RAW OUTPUT:
{
"response_status": 0,
"response_message": "Success",
"response_data": {
"apiEndPoint": "https://api-sandbox.bill.com/api/v2",
"sessionId": "!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01",
"orgId": "12345ASDFGHJKLOI3axg",
"usersId": "syuQWEASDFGMHIJkl6g"
}
}
Upload Instructions as per Bill.com
Next - get things ready to upload the file into the bill.com site: (Works Great)
Now the flow does a Parse JSON of the header and another Parse JSON of the body to retrieve required information. If you need this information, I can post it seperately, but this just helps to provide the variables which will change each time you logon successfully.
Next - Apply to each (Upload file steps):
"COMPOSE" used to create the body of the HTTP POST
INPUTS
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="devKey"
"05QWEASDFGMHIJK2078"
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="sessionId"
!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="D:/PostManDeleteThis/download.pdf"
Content-Type: application/pdf
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
{"fileName":"download.pdf"}
------WebKitFormBoundary7MA4YWxkTrZu0gW--
RAW INPUT of COMPOSE:
"------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"devKey\"\n\"05QWEASDFGMHIJK2078\"\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"sessionId\"\n!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"file\"; filename=\"D:/PostManDeleteThis/download.pdf\"\nContent-Type: application/pdf\n(data)\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"data\"\n{\"fileName\":\"download.pdf\"}\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
"OUTPUTS" of COMPOSE
Content-Disposition: form-data; name="file"; filename="D:/PostManDeleteThis/download.pdf"
Content-Type: application/pdf
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
{"fileName":"download.pdf"}
------WebKitFormBoundary7MA4YWxkTrZu0gW--
"RAW OUTPUTS" of COMPOSE
"------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"devKey\"\n\"05QWEASDFGMHIJK2078\"\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"sessionId\"\n!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"file\"; filename=\"D:/PostManDeleteThis/download.pdf\"\nContent-Type: application/pdf\n(data)\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"data\"\n{\"fileName\":\"download.pdf\"}\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
HTTP POST REQUEST:
Method
POST
URI
https://api-sandbox.bill.com/api/v2/UploadAttachment.json
Body
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="devKey"
"05QWEASDFGMHIJK2078"
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="sessionId"
!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="D:/PostManDeleteThis/download.pdf"
Content-Type: application/pdf
(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
{"fileName":"download.pdf"}
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Headers
{
"Host": "api-sandbox.bill.com",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
RAW INPUTS:
{
"uri": "https://api-sandbox.bill.com/api/v2/UploadAttachment.json",
"method": "POST",
"headers": {
"Host": "api-sandbox.bill.com",
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
},
"body": "------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"devKey\"\n\"05QWEASDFGMHIJK2078\"\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"sessionId\"\n!bpIznBPupo3KcOwjoRjAL60aG9x3o2VooYmOm8ADWuXwhNhAByZSJQ5BsuYfTvfpc.01\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"file\"; filename=\"D:/PostManDeleteThis/download.pdf\"\nContent-Type: application/pdf\n(data)\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"data\"\n{\"fileName\":\"download.pdf\"}\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
}
OUTPUTS:
Status code
200
Headers
Date
Tue, 30 Apr 2024 16:10:47 GMT
Transfer-Encoding
chunked
Connection
keep-alive
Cache-Control
no-store, no-cache
Pragma
no-cache
Strict-Transport-Security
max-age=31536000; includeSubdomains; preload
X-Frame-Options
DENY
Content-Security-Policy
default-src 'none'
X-Content-Type-Options
nosniff
CF-Cache-Status
DYNAMIC
Set-Cookie
__cf_bm=xrLmio4HbP7CDyRZRrKip9KKi66BD_9vBDjsc32CVfk-1714493447-1.0.1.1-dytMI35iFJue0Z6E_xnv1iatV78YVwK3twpXJFvTS._uW64HNvQlFARKqsZOavnCbaDVSIj6_7eh1Nu6L33oww; path=/; expires=Tue, 30-Apr-24 16:40:47 GMT; domain=.bill.com; HttpOnly; Secure; SameSite=None
Server
cloudflare
CF-RAY
87c8cdcbcde26c51-DFW
Content-Type
application/json; charset=utf-8
Expires
Thu, 01 Jan 1970 00:00:00 GMT
Content-Length
167
Body
{
"response_status": 1,
"response_message": "Error",
"response_data": {
"error_code": "BDC_1002",
"error_message": "Stream ended unexpectedly"
}
}
RAW OUTPUTS
{
"statusCode": 200,
"headers": {
"Date": "Tue, 30 Apr 2024 16:10:47 GMT",
"Transfer-Encoding": "chunked",
"Connection": "keep-alive",
"Cache-Control": "no-store, no-cache",
"Pragma": "no-cache",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "DENY",
"Content-Security-Policy": "default-src 'none'",
"X-Content-Type-Options": "nosniff",
"CF-Cache-Status": "DYNAMIC",
"Set-Cookie": "__cf_bm=xrLmio4HbP7CDyRZRrKip9KKi66BD_9vBDjsc32CVfk-1714493447-1.0.1.1-dytMI35iFJue0Z6E_xnv1iatV78YVwK3twpXJFvTS._uW64HNvQlFARKqsZOavnCbaDVSIj6_7eh1Nu6L33oww; path=/; expires=Tue, 30-Apr-24 16:40:47 GMT; domain=.bill.com; HttpOnly; Secure; SameSite=None",
"Server": "cloudflare",
"CF-RAY": "87c8cdcbcde26c51-DFW",
"Content-Type": "application/json; charset=utf-8",
"Expires": "Thu, 01 Jan 1970 00:00:00 GMT",
"Content-Length": "167"
},
"body": {
"response_status": 1,
"response_message": "Error",
"response_data": {
"error_code": "BDC_1002",
"error_message": "Stream ended unexpectedly"
}
}
}
I am missing something somewhere, but just can't find it? Hopefully someone can help me to figure out what is missing to allow this upload to work on bill.com.
THANKS ahead of time. Sorry for the long read.