I have had a few people ask me lately how to send record attachments within ServiceNow to other third party services in an integration. My answer has always been descriptive, but I have never really provided any solid examples of performing this type of activity.

I have decided to take an example of InstanceA sending a new attachment on an incident record to a third party system via SOAP Web Services. In my example, we only send out the attachment if the incident record has an existing “Correlation ID” set on the record. We assume, for the purposes of the example, that the correlation ID corresponds to a unique record in a third party system.

General Architecture

In order to do this, I created a business rule on the “Sys_attachment” table. The business rule is set to trigger when a new attachment is created. I’ve set it to run asynchronously so that it doesn’t affect the performance of the attachment feature in the product (eg. you don’t have to wait for us to send the attachment to the third party system for the UI to process the newly attached record). For every attachment, we will check the parent record’s correlation ID. If it is not empty, then we attempt to send the attachment to the third party.

WARNING: this code example uses a potentially dangerous call that could create OutOfMemory issues with a ServiceNow instance. The ‘sa.getBytes’ call reads the entire content of the attachment into memory. Any time the attachment is large and the heap is low, the instance node could go down. I am hoping to get an alternative from the ServiceNow development team for a future release.

Business Rule Settings & Code

Name: Send Correlation Attachments SOAP
When: async
Insert: checked
Table: Attachment [sys_attachment]
Condition: gs.isInteractive()
Script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
gs.log("Entering Business Rule to Send Attachment via SOAP", "Test");

//Checking to get any correlation ID set on the record
var correlationId = getCorrelation(current.table_name, current.table_sys_id);

//We only send attachments if the record correlates to another system
if(correlationId != ""){
  //Load some common Packages from Java
  //typically we don't like to do this, but these are commonly used ones
  //so we should be safe
  var sa = new Packages.com.glide.ui.SysAttachment();
  var StringUtil = Packages.com.glide.util.StringUtil;

  //Get the base64 encoding of the attachment
  var binData =  sa.getBytes(current);
  var encData =  StringUtil.base64Encode(binData);
   
  //Send it via SOAP to the third party - using the third party's
  //format.  This example uses another SN instance, so the SOAP
  //body uses the format required by ServiceNow
  var s = new SOAPMessage('Demo10 ECC Queue', 'insert attachment');
  s.setParameter('filename', current.file_name);
  s.setParameter('mimetype', current.content_type);
  s.setParameter('destTable', current.table_name);
  s.setParameter('destSysId', correlationId);
  s.setParameter('payload', encData);
  s.post(true);
 
} else {
  gs.log("The record ("+current.table_name+":"+current.table_sys_id+") did not have necessary correlation...will not send attachment");
}

/*
 * Checks to see if the record has a correlation ID
 *
 * Params:
 * tablename - name of the table in the system where the record belongs
 * sysid - the sys_id of the record in the table
 *
 * Returns:
 * Either a correlation_id value or empty string
 */

function getCorrelation(tablename, sysid){
  var gr = new GlideRecord(tablename);
  gr.get(sysid);
  if( gr.correlation_id != ""){
    return gr.correlation_id;
  }
  return "";
};

A note about the SOAP Message

In this example, the code from the business rule builds out a SOAPMessage object that consumes another ServiceNow instance’s SOAP Attachment Web Service. Typically, you would not be integrating with another ServiceNow instance. You would create a SOAPMessage record that consumes the third party’s SOAP web service that supports attachments. You will use that SOAPMessage object to post the base64 encoded file and its meta data in the format required by the third party.

Other Documentation

AttachmentCreator SOAP Web Service – Official ServiceNow documentation on the inbound AttachmentCreator SOAP web service. It does not cover an outbound scenario that we demonstrate here. But it does show the format that ServiceNow uses to accept attachments via SOAP.