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.

Processor script in Scripted rest api

Rj27
Mega Guru

Hi All,

I have a requirement where i need to download attachment from snow to local device using REST/SOAP.
I found following link for the same and it is working absolutely fine.

https://www.servicenowguru.com/scripting/download-attachments-zip-file/

But the issue is it is using processor. Since processors are deprecated and the alternative is scripted rest api. i am trying to use it there. but it;s not working. Seems i need to make few changes which are specific to processor.
Will the same code not work in scripted rest?

var gr = new GlideRecord('sc_req_item');
gr.addQuery('number', queryRITM);
gr.query();
 if (gr.next()) {
var zipName = 'attachments.zip';
var StringUtil = GlideStringUtil;
var fn;
 var ga = new GlideRecord('sys_attachment');
ga.addQuery('table_sys_id', gr.sys_id);
 ga.query();
while (ga.next()) {
 var obj = {};
var attachsysid = ga.sys_id;
 var filename = ga.file_name;
var contentType = ga.content_type;
 obj['Content-Type'] = "'" + ga.content_type + "'";

response.setStatus(200);
response.setHeaders(obj);
response.setContentType(obj['Content-Type']);
response.addHeader('Content-Disposition', 'attachment;filename=' + zipName);

var out = new Packages.java.util.zip.ZipOutputStream(response.getOutputStream());
var count = 0;
while (ga.next()) {
var sa = new GlideSysAttachment();
var binData = sa.getBytes(gr);
add counter so that the filename is NOT duplicate
var file = ga.file_name + "-" + count;
gs.info("Entered into this loop" + file);
addBytesToZip(out, zipName, file, binData);
count++;
}

 out.close();
}

// function addBytesToZip(out, dir, file, stream) {
// // Add ZIP entry to output stream.
// out.putNextEntry(new Packages.java.util.zip.ZipEntry(file));
// out.write(stream, 0, stream.length);
// out.closeEntry();
// }

2 REPLIES 2

Hitoshi Ozawa
Giga Sage
Giga Sage

Not a directly answer but following Scripted REST API will download a file. Unfortunately, it still doesn't zip the file so only 1 file can be downloaded at a time.

Syntax:

https://<servicenow instance>.service-now.com/api/<namespace>/getattachments/<incident number>?num=<attachment number to download>

 

Note: It's necessary to define a Query Parameter "num".

(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

    var tableName = 'incident';
    var number = request.pathParams.number;
    var row = request.queryParams.num;

    if (!row) {
        row = 1;
	}

    try {
        var grTable = new GlideRecord(tableName);
        if (grTable.get('number', number)) {
            var grAttach = new GlideRecord('sys_attachment');
            grAttach.addQuery('table_sys_id', grTable.sys_id);
            grAttach.chooseWindow(row - 1, row);
            grAttach.query();
            if (grAttach.next()) {
                var filename = grAttach.file_name;
                var content_type = grAttach.content_type;
                var created = grAttach.created;
                var created_by = grAttach.created_by;

                var hdrs = {},
                    attachment_sys_id = filename + ".jpg";

                hdrs['Content-Type'] = content_type;
                response.setStatus(200);
                response.setHeaders(hdrs);

                var writer = response.getStreamWriter();
                var attachmentStream = new GlideSysAttachmentInputStream(grAttach.sys_id);
                writer.writeStream(attachmentStream);
            }
        }
    } catch (e) {
        gs.error("ERROR=", e);
    }
})(request, response);

I was harding "jpg" as file extension. Change that part to below:

				var file_ext = content_type.substr(content_type.lastIndexOf('/') + 1);
                var hdrs = {},
                    attachment_sys_id = filename + file_ext;

                hdrs['Content-Type'] = content_type;