Attachments API - Converting Binary Files to Base64

Lucas Romani1
Tera Contributor

Hi,

I am using a REST API from servicenow (/api/now/attachment/{sys_id}/file) to get the binary file of an attachment (code below)

var rest = new sn_ws.RESTMessageV2();
rest.setEndpoint('https://xxxxxxxxxx.service-now.com/api/now/attachment/6f20c5fe1bbe6d10e641eb5be54212/file');
rest.setHttpMethod('get');
rest.setRequestHeader("Accept",'*/*');
rest.setBasicAuth("user","password");
var response = rest.execute();
var obj = response.getBody();
gs.info(obj); /* obj is the binary representation of the attachment */

Is there a way to convert the binary file (obj) to base64 ? I tried using GlideStringUtil.base64Encode(obj) but it seems not correct. Can you help me ?

1 ACCEPTED SOLUTION

Ratnakar7
Mega Sage
Mega Sage

Hi @Lucas Romani1 ,

 

You can use the GlideStringUtil.base64Encode() method to convert the binary file to Base64 in ServiceNow. Here's an updated version of the code using GlideStringUtil.base64Encode():

 

 

var rest = new sn_ws.RESTMessageV2();
rest.setEndpoint('https://xxxxxxxxxx.service-now.com/api/now/attachment/6f20c5fe1bbe6d10e641eb5be54212/file');
rest.setHttpMethod('get');
rest.setRequestHeader("Accept", '*/*');
rest.setBasicAuth("user", "password");
var response = rest.execute();
var obj = response.getBody(); // obj is the binary representation of the attachment

var base64String = GlideStringUtil.base64Encode(obj);

gs.info(base64String); // base64String is the Base64 representation of the binary file

 

 

 

For converting large files to base64encode string, you can refer below script:

 

 

var StringUtil = new GlideStringUtil();

var gsis = GlideSysAttachmentInputStream(gr.sys_id.toString());

var ba = new Packages.java.io.ByteArrayOutputStream();

gsis.writeTo(ba);

baos.close();

var base64EncodedData = StringUtil.base64Encode(ba.toByteArray());

 

 

 

If my response was helpful in resolving the issue, please consider accepting it as a solution by clicking on the Accept solution button and giving it a thumbs up 👍. This will benefit others who may have a similar question in the future.

 

Thank you!

Ratnakar

View solution in original post

6 REPLIES 6

Ratnakar7
Mega Sage
Mega Sage

Hi @Lucas Romani1 ,

 

You can use the GlideStringUtil.base64Encode() method to convert the binary file to Base64 in ServiceNow. Here's an updated version of the code using GlideStringUtil.base64Encode():

 

 

var rest = new sn_ws.RESTMessageV2();
rest.setEndpoint('https://xxxxxxxxxx.service-now.com/api/now/attachment/6f20c5fe1bbe6d10e641eb5be54212/file');
rest.setHttpMethod('get');
rest.setRequestHeader("Accept", '*/*');
rest.setBasicAuth("user", "password");
var response = rest.execute();
var obj = response.getBody(); // obj is the binary representation of the attachment

var base64String = GlideStringUtil.base64Encode(obj);

gs.info(base64String); // base64String is the Base64 representation of the binary file

 

 

 

For converting large files to base64encode string, you can refer below script:

 

 

var StringUtil = new GlideStringUtil();

var gsis = GlideSysAttachmentInputStream(gr.sys_id.toString());

var ba = new Packages.java.io.ByteArrayOutputStream();

gsis.writeTo(ba);

baos.close();

var base64EncodedData = StringUtil.base64Encode(ba.toByteArray());

 

 

 

If my response was helpful in resolving the issue, please consider accepting it as a solution by clicking on the Accept solution button and giving it a thumbs up 👍. This will benefit others who may have a similar question in the future.

 

Thank you!

Ratnakar

@Ratnakar7 

I executed the two code belows to get the base64 representation of the same attachment, but the outputs (base64) is different on both and I don't understand why this difference is occuring.

 

1st code:

var cgiAttch = new GlideRecord('sys_attachment');
cgiAttch.addQuery('sys_id','6f20c5fe1bbe6d10e641eb5be54b22');
cgiAttch.setLimit(1);
cgiAttch.query();
cgiAttch.next();
var sa = new GlideSysAttachment();
var binData = sa.getBytes(cgiAttch);
var encData = GlideStringUtil.base64Encode(binData);

gs.info(encData); /* returns the representation on base64 of the attachment queried on sys_attachment gliderecord */

 

2nd code (same code that you sent in your first suggestion on message)

var rest = new sn_ws.RESTMessageV2();
rest.setEndpoint('https://xxxxxxxxxx.service-now.com/api/now/attachment/6f20c5fe1bbe6d10e641eb5be54b22/file');
rest.setHttpMethod('get');
rest.setRequestHeader("Accept", '*/*');
rest.setBasicAuth("user", "password");
var response = rest.execute();
var obj = response.getBody(); // obj is the binary representation of the attachment

var base64String = GlideStringUtil.base64Encode(obj);

gs.info(base64String); // base64String is the Base64 representation of the binary file

 

gs.info(base64String) and gs.info(encData) are showing different values inspite of they are representing the same attachment file (on attachments of this comment I am sending the initial outputs of each gs.info). Can you help me ?

Hi @Lucas Romani1 ,

 

The difference in the base64 representation between the two codes could be due to the way the attachment data is obtained and encoded.

In the first code, you are directly retrieving the attachment data using GlideSysAttachment and then encoding it to base64. This approach retrieves the binary data of the attachment directly from the sys_attachment table.

In the second code, you are making a REST API call to retrieve the attachment file using the ServiceNow API. The response body (obj) contains the binary representation of the attachment file, which is then encoded to base64.

The difference in the base64 representation could be caused by variations in how the attachment data is obtained and processed in the two approaches. It's possible that the REST API call includes additional formatting or encoding that affects the resulting base64 representation.

To troubleshoot the issue, you can compare the binary data obtained from both approaches (binData from the first code and obj from the second code) to check if they are identical. You can compare the length of the binary data and examine a portion of the data to see if they match.

For example, you can log the lengths of binData and obj using gs.info(binData.length) and gs.info(obj.length), respectively. Additionally, you can log a portion of the binary data to compare, such as gs.info(binData.substring(0, 100)) and gs.info(obj.substring(0, 100)).

By comparing the binary data obtained from both methods, you can determine if there are any discrepancies in the retrieval of attachment data.

 

 

Thanks,

Ratnakar

Hi @Lucas Romani1 

 

Were you able to get a working solution based on 2nd code.

I have the requirement to make an API call to get the attachment but end up with binary file which I am unable to use to attach to my new record which is in another instance.

Please provide your insights if you find anything

 

My requirement is between two different Servicenow instances and pull the attachments from one instance to another. The attachments are on knowledge article record and each kb article has multiple attachments