Getting raw attachment content

lock
push_pin
done
Answered
9

Hello,

I am trying to retrieve the raw content of a attachment so that I can include it as part of a multipart/form-data POST request.

When I retrieve the raw content of a .txt file it works fine, but if it is something like a .pdf or .docx file, I only get a tiny bit of the content.

Sample code:

Integer attachmentId = 55996;

Attachment attachment;
attachment.load(attachmentId);

String rawData = attachment.getRaw();

printLine("Raw data length: " + rawData.getLength().toString());
printLine("Actual data length: " + attachment.getValue("size"));

TXT file output:

Raw data length: 429102
Actual data length: 429102

PDF/DOCX file output:

Raw data length: 423
Actual data length: 1766746

 

Because of this I can't send these files using a multipart/form-data POST request to a external system. They aren't completely included in the data.

Is there another way to get the attachment raw content? or is this a bug?

Sample code for creating a multipart/form-data POST request:

Void addMultiPartFormData(HTTP http, Integer attachmentId)
{
   Attachment attachment;
  
    if (attachment.load(attachmentId) == false)
    {
      	throw "Unable to load attachment with id '" + attachmentId.toString() + "'";
    }

   String boundary = "fY47GRQfGNC7vJSNbqhp";
   String eol = "\r\n";
   String body = "--" + boundary;
  
   body.append(eol);
   body.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + attachment.getValue("name") + "\"");
   body.append(eol);
   body.append("Content-type: " + attachment.getValue("contentType"));
   body.append(eol);
   body.append(eol);
   body.append(attachment.getRaw());
   body.append(eol);  
   body.append("--" + boundary + "--");
   body.append(eol);
   	
   http.setOption("parameters", "?" + body);


   http.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
   http.addHeader("Content-Length", body.getLength().toString());
}

String url = "https://httpbin.org/post";
Integer attachmentId = 55996;
HTTP httpClass;

httpClass.setDebugMode(true);
httpClass.addHeader("Accept", "application/json");

addMultiPartFormData(httpClass, attachmentId);
NSStream responseStream = httpClass.postAsStream(url);

print(String(responseStream));
printLine("");
print(httpClass.getDebug());

2 Mar 2022 | 12:52 PM

All Replies (9)

Any idea/suggestion for this? I can't encode the data to base64, the external system does not accept that.

9 Mar 2022 | 01:15 PM

A file like PDF or DOCX most likely contain binary data. And you cannot read binary data into a String, because binary data will contain bytes with the value 0, and in a String that means that the end of the string is encountered. That is why you get the behaviour above.

There is a method on the Attachment class called getBase64. Then you will get a base64 encoded String of the attachment.

But if you are in Online, you might run into memory issues depending on how large the attachments are. 

To remedy on this situation there is a method on the HTTP class called "addAttachmentData", which takes an attachment id as parameter, and add the binary content of the attachment to the body. But it does not use a multi part form, so do not know if that helps you out.

9 Mar 2022 | 08:03 PM

Hi Stian,

The external system only accepts the file as a multi part form, so the add*Data functions on the HTTP class sadly won't help with this.

This is on Online so memory might indeed be an issue, would it be possible to add a function to the HTTP class to add the attachment as multi part form data?

10 Mar 2022 | 08:11 AM

Hi, we had the same issue in a case a couple of weeks back. I think we ended up with a workaround where we set up a C# webservice as a middleware, so CRMScript sent to the C#-webservice, and it passed the file on as MultiPartForm to the final webservice.

So we're also interrested in figuring out a plain CRMScript solution for this so we can remove the C# middleware.

10 Mar 2022 | 08:26 AM

Hi,

A middleware solution where we send the attachment to and convert it to a multi part form would also be our workaround, but we rather not do that since that create's an external dependency. The customer we are doing this for isn't very fond of that.

10 Mar 2022 | 08:39 AM

To get around with the memory problems (so you do not need to load the content into memory), I think that CRMScript would need to have support for creating multipart bodies, and in the same time able to add a part with the content of an attachment (or Sales document).

So the best way would be for you to suggest this as a wish and get it into the backlog for prioritization.

11 Mar 2022 | 07:56 AM

Wish registered: 25803

14 Mar 2022 | 09:02 AM

Ran into the same issue today.
Anyone managed to come up with a workaround that does not include a middleware?

29 Nov 2022 | 08:08 AM

Adding a +1 to this. I am also struggling with this. We will need to create a middleware until the request/wish is hopefully fullfilled.

31 May 2023 | 05:01 AM

Add reply