Manipulating File Attachments

I got a question from a colleague today–not an uncommon one–regarding the correct usage of the GlideSysAttachment API.

Throughout my examples, you I will generally assume that you’re using the Scripts – Background module to test your code prior to deployment. As such, there will generally be three parts to my “code snippet” posts:

  1. Code Setup
  2. Function declarations
  3. Example

Since the majority of the time we’re running background scripts, we will be likely be transferring to a Business Rule, a Workflow Script or a Scheduled Job, you’ll see the following a lot.

Setup
var current = new GlideRecord('incident');
current.get('number', "INC0000016");

I will follow this format for the setup of scripts, as I can test effectively against the “current” record.

Function declarations

The next step you want to take is to plan your common usage scenarios. When working with attachments, you will likely encounter the following:

  • Does the current record have attachments
  • How many attachments does it have
  • I want to copy the attachments to a different record
  • I want to delete one of the attachments
  • I want to delete all the attachments

For the first, we don’t need a function; there’s a method already available: current.hasAttachments()

How many attachments would need a simple function:

function getAttachmentCount (taskGR) {
   var gsa = new GlideSysAttachment();
   var attachGR = gsa.getAllAttachments(taskGR.getTableName(), taskGR.getUniqueValue());
   return attachGR.getRowCount();
}

If you want to copy all attachments to another record:

function copyAttachments(sourceGR, targetGR){
   var gsa = new GlideSysAttachment();
   gsa.copy(sourceGR.getTableName(), sourceGR.sys_id, targetGR.getTableName(), targetGR.sys_id);
}

If you want to delete a specific attachment:

function deleteSelectivly(taskGR, fileNameToDelete){
   var gsa = new GlideSysAttachment();
   var attachGR = gsa.getAllAttachments(taskGR.getTableName(), taskGR.sys_id);
   while (attachGR.next()){
      if (attachGR.file_name == fileNameToDelete){
         gsa.deleteAttachment(attachGR.sys_id);
      }
   }
}

And finally, delete all attachments:

function deleteAllAttachments (taskGR) {
   var gsa = new GlideSysAttachment();
   gsa.deleteAll(taskGR);
}
Example

Here’s what we get if we put it all together:

var current = new GlideRecord('incident');
current.get('number', "INC0000016");

if (current.hasAttachments()){
   if (current.problem_id != ''){
      copyAttachments(current, current.problem_id.getRefRecord());
   }
   manageAttachments();
}

function copyAttachments(sourceGR, targetGR){
   var gsa = new GlideSysAttachment();
   gsa.copy(sourceGR.getTableName(), sourceGR.sys_id, targetGR.getTableName(), targetGR.sys_id);
}

function manageAttachments(){
   var attachmentCount = getAttachmentCount(current);
   if (attachmentCount == 2){
      deleteSelectively(current, "file to delete.pdf");
   }
   else if (attachmentCount > 10){
      deleteAllAttachments(current);
   }
}

function deleteSelectively(taskGR, fileName){
   var gsa = new GlideSysAttachment();
   var attachGR = gsa.getAllAttachments(taskGR.getTableName(), taskGR.sys_id);
   while (attachGR.next()){
      // perform the check for file name (could also use something like size)
      if (attachGR.file_name == fileName){
         gsa.deleteAttachment(attachGR.sys_id);
      }
   }
}

function deleteAllAttachments (taskGR) {
   var gsa = new GlideSysAttachment();
   gsa.deleteAll(taskGR);
}

function getAttachmentCount (taskGR) {
   var gsa = new GlideSysAttachment();
   var attachGR = gsa.getAllAttachments(taskGR.getTableName(), taskGR.getUniqueValue());
   return attachGR.getRowCount();
}