How to post a NSDocument Stream as multipart/form-data

lock
push_pin
done
Answered
3

Hi,

We have built interaction between SuperOffice and Trello. We create cards and get statuses and such.

Now I want to build a function that gets NSDocument from a Sale i SuperOffice and post it as an Attachment to a Trello Card.

I have made successful posts and puts with the HTTP CRMScript class, but I can't figure out how to post a NSDocument Stream according to the Trello Instructions.

https://developer.atlassian.com/cloud/trello/rest/api-group-cards/#api-cards-id-attachments-post

It needs to be posted as multipart/form-data with a parameter/name of "file".

 

I have tried this, with no luck:

HTTP h2;

Bool addeddoc = h2.addDocumentData(8859);
h2.addHeader("Content-Type","multipart/form-data");
Byte[] b2 = h2.post("https://api.trello.com/1/cards/" + trelloCardId + "/attachments?key=***************&token=*********************************7");
if (h2.hasError())
  print(h2.getErrorMessage());
else
{
  printLine(String(b2,"utf8").utf8Decode());

}

I get error "Error parsing body"

Any ideas? 

26 May 2023 | 06:46 PM

All Replies (3)

Hi John,

I had the same issue with adding attachment data as multipart/form-data, see this thread.

addDocumentData/addAttachmentData does not work since that is not added as multipart/form-data to the http body.

Sadly this is not solveable (currently) within CRMScript. I did register a wish for it.

30 May 2023 | 01:15 PM

Hi,

Unfortunately, creating support for multipart/form-data with the HTTP client library we are using in CRMScript requires a bit of coding, so we have not been able to prioritize this. However, I have earlier managed to make this work by creating the HTTP post myself. It will limit the size of the payload you can send (because CRMScripts are limited in memory size). But unless your attachments are very big, it should work. For reference, here is the code I was working on. It is not very polished, but perhaps it can help you get started. I used it to upload some stuff to a service that prints PDF documents.

NSStream stream = a.GetDocumentStream(documentId);

String head = '----------------------------782724701432735347421721\n' +
'Content-Disposition: form-data; name="JsonToServer"\n' +
'\n' +
'{\n' +
'"ApiKey":"xxx",\n' + 
'"UserEmail":"zzz",\n' +
'"UserPwd":"yyy",\n' +
'"NamePart1":"Sverre1"\n' +
'}\n' +
'----------------------------782724701432735347421721\n' +
'Content-Disposition: form-data; name="letter.pdf"; filename="letter.pdf"\n' +
'\n';

Byte[] bytes = stream.GetStream();
Byte[] footer = String(
'----------------------------782724701432735347421721\n' +
'Content-Disposition: form-data; name="letter.ini"; filename="letter.ini"\n' +
'\n' +
'[File]\n' +
'PagesInDocument=2\n' +
'LettersInDocument=1\n' +
'[PrinterBF]\n' +
'DeliverySpeed=A-Post\n' +
'EnvelopeType=To Vinduer\n' +
'[Advanced]\n' +
'DPperSheet=1\n' +
'----------------------------782724701432735347421721--\n').toByteArray();
Byte[] payload = head.toByteArray();
for (Integer i = 0; i < bytes.length(); i++)
  payload.pushBack(bytes[i]);
for (Integer i = 0; i < footer.length(); i++)
  payload.pushBack(footer[i]);

printLine("Length of payload: " + payload.length().toString());

HTTP http;
http.setDebugMode(true);
http.addBinaryData(payload);
http.addHeader("Content-Type", "multipart/form-data; boundary=--------------------------782724701432735347421721");
Byte[] response = http.post("http://zzz/UploadFileSet");
printLine("Response: " + String(response));
printLine("");
printLine(http.getDebug());

Sverre

5 Jun 2023 | 07:33 AM

Hi,

Thank you for the example!

I made it work by building a middleware. We are using the addDocumentAsData and posting it to an endpoint in our own API, and then our API posts it to Trello. 

 

 

5 Jun 2023 | 07:57 AM

Add reply