Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Send attachment in outbound REST integration

Saquib Mohammed
Mega Guru

I am trying to send an attachment via outbound REST integration. I have created a POST HTTP method with the following query parameters - 

{
"task_number":"${task_number}",
"task_cmdb_ci":"${task_cmdb_ci}",
"attachment_list": "${attachment_list}"

attachment_list is a list of object with attachment details.

In the business rule, i have the below script - 

var attachment_list = [];
if (attach.next()){
var gsa = GlideSysAttachmentInputStream(attach.sys_id.toString());
var baos = new Packages.java.io.ByteArrayOutputStream();
gsa.writeTo(baos, 0, 0);
baos.close();
var encData = GlideStringUtil.base64Encode(baos.toByteArray());
gs.log("This is encoded data of attachment " + encData);
var obj = {};
obj["encodedFile"] = encData;
obj["fileName"] = attach.file_name.toString();
obj["contentType"] = attach.content_type.toString();
attachment_list.push(obj);
}
gs.log("This is attachment_list outside if " + JSON.stringify(attachment_list));
gs.log("This is attachment_list outside if " + attachment_list);
r.setStringParameter('attachment_list', (attachment_list));
var requestBody = r.getRequestBody();
var response = r.execute();

 

The issue is that the attachment_list property is being sent as a string value while it needs to be sent as a list value. The payload that is being sent is in the below format:

{

    "attachment_list": "[{"encodedFile":"VGhpcyBpcyBhIHRlc3Q=","fileName":"Test1.txt","contentType":"text/plain"}]",

    "task_cmdb_ci": "UPS Hardware and Support",

    "task_number": "TASK000000042161"

}

While the attachment_list should be in the below formst - 

    "attachment_list": "[{"encodedFile":"VGhpcyBpcyBhIHRlc3Q=","fileName":"Test1.txt","contentType":"text/plain"}]",

 

1 ACCEPTED SOLUTION

Anish Reghu
Kilo Sage

Hi @Saquib Mohammed,

 

It appears that the issue is that the attachment_list property is being sent as a string value, when it should be sent as a list value. One way to fix this is to use JSON.stringify() to convert the attachment_list variable to a JSON string before passing it to r.setStringParameter('attachment_list',...).

Example:

 

 

r.setStringParameter('attachment_list', JSON.stringify(attachment_list));

 

 

Another way is to directly pass the attachment_list variable to r.setParameter() instead of r.setStringParameter()

 

Example:

 

 

r.setParameter('attachment_list', attachment_list);

 

This should be able to send the payload in the expected format as a list.

 

Kindly mark the response as Correct or Helpful.

Cheers,

Anish

View solution in original post

7 REPLIES 7

Here is the full script for your reference. I have highlighted in bold the pain points.

try {
var r = new sn_ws.RESTMessageV2('<API name>', '<Method name>');

r.setStringParameterNoEscape('task_number',current.number);
r.setStringParameterNoEscape('task_cmdb_ci',current.cmdb_ci.getDisplayValue());

//Send Attachment - Start
var attach = new GlideRecord('sys_attachment');
attach.addQuery('table_name', 'incident_task');
attach.addQuery('table_sys_id', current.sys_id);
attach.query();
gs.log("This is number of attachment " + attach.getRowCount());
var attachment_list = [];
if (attach.next()){
var gsa = GlideSysAttachmentInputStream(attach.sys_id.toString());
var baos = new Packages.java.io.ByteArrayOutputStream();
gsa.writeTo(baos, 0, 0);
baos.close();
var encData = GlideStringUtil.base64Encode(baos.toByteArray()); 
var obj = {};
obj["encodedFile"] = encData;
obj["fileName"] = attach.file_name.toString();
obj["contentType"] = attach.content_type.toString();
attachment_list.push(obj);
}
//r.setStringParameter('attachment_list', (attachment_list));
r.setParameter('attachment_list', (attachment_list)); // This is still throwing error from API
//Send Attachment- End

var requestBody = r.getRequestBody();
gs.log("This is Request body: " + requestBody); // This is not printing the actual request payload
var r_requestBody = r.getElements();
for (var i = 0; i < r_requestBody.length; i++) {
gs.log(r_requestBody[i].getName() + ": " + r_requestBody[i].getValue()); // This is not getting logged at all
}

}
catch(ex) {
 var message = ex.message;
}
})(current, previous);

r.getRequestBody() returns a string representation of the request body and it's not the same as the request payload. You can try to print the request payload by using the following line instead:

gs.log("This is Request Payload: " + JSON.stringify(r.getElements()));

 

 

Kindly mark the response as Correct or Helpful.

Cheers,

Anish

 

This is printing - 

This is Request Payload: undefined