How to create a REST API to download attachment?

Subhashree3
Giga Contributor

Hi All,

We have one requirement where we need to create a Rest API which will be used by other external system in order to download the attachment.

I am confused between Scripted Rest API, Rest Message and Rest API explorer as I am new to this. Please let me know in this case which method will be considered and if you can provide any reference to create a REST API to download the attachment, that would be really helpful for me.

Thank You.

8 REPLIES 8

VigneshMC
Mega Sage

Hi Vignesh,

Yes I have looked at Attachment API  docs as well. So can it be done through Attachment API?

Thanks.

Service_RNow
Mega Sage

Hi shubhashree,

I think that would be easier than figuring out how to script it but if you have to script it you'll probably find the GlideSysAttachment API useful.

https://developer.servicenow.com/app.do#!/api_doc?v=london&id=r_SGSA-GlideSysAttachment

Attachment API

You can use the same process as mentioned in this link. With slight modifications, you can get to download all attachments.

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

Please note that the script might take time and if you want to limit to N number of records, you can do so in the below script. 

Few points to Note

1. The count variable is added to the file name to avoid duplicate file names. If there are duplicate file names, the zip process will break.

2. The script is modified to simply query sys_attachment and download them in the processor. It is not capturing any parameters from UI action as such. 

3. Create the UI action as a form button on any incident or any other table.

  var zipName = 'attachments.zip';
  var StringUtil = GlideStringUtil;
  var gr = new GlideRecord('sys_attachment');
  gr.query();
  if (gr.next()){
    g_response.setHeader('Pragma', 'public');
    g_response.addHeader('Cache-Control', 'max-age=0');
    g_response.setContentType('application/octet-stream');
    g_response.addHeader('Content-Disposition', 'attachment;filename=' + zipName);
    var out = new Packages.java.util.zip.ZipOutputStream(g_response.getOutputStream());
    var count=0;
    while (gr.next()){
        var sa = new GlideSysAttachment();
        var binData = sa.getBytes(gr); 
        //add counter so that the filename is NOT duplicate
        var file = gr.file_name+"-"+count; 
	gs.info("Entered into this loop"+file);
	addBytesToZip(out, zipName, file, binData);
        count ++;
    }
    // Complete the ZIP file
    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();
}

I ran this in my dev instance and it worked fine. The script takes time to download all the attachments. To test the script, i suggest you break the loop above at 5 or 10 records.

Mark the comment as correct and also helpful once worked.

Hi Ram,

Thanks for your suggestion. As per my requirement, an external system will download the attachment by accessing our API. 

Could you please let me know how this can be achieved? Will Attachment API be helpful in achieving this?

Thank You.