You are currently viewing All Attachment Questions In ServiceNow

All Attachment Questions In ServiceNow

In this article, I am providing day-to-day questions asked by developers regarding attachments anywhere on the internet across various forums. My object is to provide all such daily activities in one place with easy and sharp answers.

Most of these codes are provided by experts and can be used with so changes as per your requirements. However, I have tried to optimize it to the most but can’t guarantee it is working 100%.

[youtube-feed feed=1][youtube-feed feed=3][youtube-feed feed=4]
My ServiceNow YouTube Channels

Which tables deal with attachments in ServiceNow?

  • Attachments (sys_attachment)
  • Attachment Documents (sys_attachment_doc).

When you upload an attachment file to ServiceNow, a record is created in the Attachments table with some metadata, including the file name, content type, and size of the attached file.

Name important Classes / APIs used for attachments in ServiceNow.

  • GlideExcelParser(): You can parse. xlsx-formatted Excel files. The GlideExcelParser methods can be used in global and scoped scripts. The API namespace identifier “sn_impex” must be used when creating a GlideExcelParser object.
  • getColumnHeaders(): Returns a list of column headers from the parsed document.
  • getContent(GlideRecord sysAttachment): Returns the attachment content as a string.
  • getContentStream(String sysID): Returns a GlideScriptableInputStream object given the sysID of an attachment
  • getRow(): Get the current row values and headers.

How do I fetch data from an attachment attached to a record?

var parser = new sn_impex.GlideExcelParser();
var attachment = new GlideSysAttachment();
// use attachment sys id of an excel file attachment
var attachmentStream = attachment.getContentStream('f18e8e0a1b2f3300364d32a3cc4bcb99');
parser.parse(attachmentStream);
//retrieve the column headers
var headers = parser.getColumnHeaders();
var key = headers[0];
var value = headers[1];
//var obj = {};
while(parser.next()) {
                        var row = parser.getRow();
                        //print row value for both columns
                        gs.log(row[key] + ': ' + row[value]) ;
               //         obj[row[key]] = row[value];
}

How do I fetch data from an attached CSV to a record?

  • getBytes() : This returns the raw bytes of the file — that means binary data.
  • java. lang.String(): we convert that data into a string using.
 var   gr = new GlideRecord('sys_attachment');
       gr.addQuery('sys_id', '24021a4e1b2f3300364d32a3cc4bcb69'); // sys_id of attachment record
      gr.query();
      if(gr.next()){
                        var gsa = new GlideSysAttachment();
                        var bytesInFile = gsa.getBytes('incident', 'b98d17f11ba73300364d32a3cc4bcb29');
                        var originalContentsInFile = Packages.java.lang.String(bytesInFile); // originalContentsInFile
                        originalContentsInFile = String(originalContentsInFile);
                        gs.print("Contents of Attached CSV File:  "+originalContentsInFile);
       }

How to fetch Contents from TEXT File Attached to your record?

var tableName = 'incident';
var sysIdOfRecord = 'b98d17f11ba73300364d32a3cc4bcb29';
var fileNameWithoutExtension = 'Demo'; //Full file name: example text doc.txt
var grWithAttachment = new GlideRecord(tableName);
grWithAttachment.get(sysIdOfRecord);
var gsa = new GlideSysAttachment();
//ONLY works in global
var dataInTextFile = gsa.get(grWithAttachment, fileNameWithoutExtension);
gs.print("Information Available in Text File: "+dataInTextFile);

How to copy an Attachment from One Table/Record to another Table/Record?

Copying all of the attachments associated with a given record is fairly straightforward. You simply call the copy method of the GlideSysAttachment class, and pass in four parameters:

  • The table you want to copy the attachment from (incident, change_request, etc.).
  • The sys_ID of the record you want to copy the attachment from.
  • The table that you want to copy the attachment to.
  • The sys_ID of the record you want to copy the attachment to.
This might look something like this: 
var donorTable = sc_req_ite’;//
var donorID = '2b6644b15f1021001c9b2572f2b47763';
var recipientTable = sc_task; //
var recipientID = '78e47fe94f31d200bf004a318110c7d4';
GlideSysAttachment.copy(donorTable, donorID, recipientTable, recipientID);

List few important attachment related properties?

The following are list of attachment-related properties that you can access and modify in ServiceNow. You can either modify the value of a property in that list, or if you don’t see a given property in the list, create it and set the value specified below. 

PropertyValuesDescription
glide.ui.attachment_drag_and_droptrue/false
Enable/disable drag-and-drop to attach a file
com.glide.attachment.max_sizeInteger (MB)The maximum size (in megabytes) for individual file attachments. Leaving this field blanks allows attachments up to 1GB.
glide.attachment.roleComma-separated listEnter a comma-separated list of the roles that can attach files. Enter names, not sys_ids. Entering “Public”, or leaving this blank means that anyone can attach files.
glide.attachment.extensionsComma-separated listEnter a comma-separated list of attachment file extensions (not including the ‘dot’) which should be allowed. To allow all, leave this property value blank. Note that unless this is blank, any attachments not listed here will be blocked.
glide.ui.disable_attachment_view & glide.ui.attachment_popup
true/false
To hide the “[View]” link next to an attachment, set the disable_attachment_view property to true and the attachment_popup property to false. Users can still view attachments by clicking the attachment file name.
glide.ui.attachment.
force_download_all_mime_types
true/falseThis property, when true, makes it so that all attachment file types will be downloaded rather than viewed in the browser, when clicked. This is especially helpful for filetypes like text or HTML files, where the browser may attempt to render them rather than download them.

Catalog item Realtime requirement

Question:-

While raising a new request from a particular catalog item, we want to add an attachment everytime when the new record is created attachment being the same throughout. I am trying through BR after insert, selecting the item in the filter and using the glidesysattachement gliderecord.

Its not working, any guide would be helpful.

Solution:-

Attach the required attachment in catalog item(sc_cat_item) and write an after insert BR with cat item name in the filter conditions. Please use the below code in the BR.

GlideSysAttachment.copy('sc_cat_item', current.cat_item.sys_id, 'sc_req_item', current.sys_id);

What is the relation between sys_attachment & sys_attachment_docs table?

  • “sys_attachment” table has got one-to-many relationship with “sys_attachment_docs” table.
  • Field “sys_attachment” on Table “sys_attachment_docs” holds sys_id of parent mapping record of table “sys_attachment”
  • There can be more than one records in “sys_attachment_docs” table which are basically 4K chunks of the gzip archive of actual attachment

How attachments stored in servicenow?

  • Attachments are stored in sys_attachment_doc table in 4k chunks,
  • Attachment information is stored in sys_attachment table.
  • Sys_attachment table stores file’s meta information including, file name, size & type.
  • Sys_attachment_doc table stores files in the following way.
  • ServiceNow receives an attachment
  • We gzip it => split the gzip into 4k chunks => Execute a base64 encoding of the 4k chunks.

How to retrieve attachment from servicenow ?

To retrieve an attachment is as simple as finding the 4k chunks, base64 decoding, constructing the gzip archive and then extracting the file from the archive.

  • The first step will be to locate the parent reference: the single record in sys_attachment
  • Lookup sys_attachment table for

Table sys id = <Your Transactions Record sys ID>

  • This will return the attachments in this transactional record. We can refine above query to get the single record we are after.
  • Get sys ID of this record.
  • Search sys_attachment_docs table with

Sys_attachment = <Sys ID of parent record in sys_attachment table, copied above>

  • This will return all the records for this attachment.
  • Each of these records contains a field “position”. Position defines ordering, and simply is 0,1,2,3,.. for reconstructing.
  • So during your query in sys_attachment_doc table you can add

“order_by” = “position” to retrieve the records in order.

  • Once we have the chunks,
    • base64_decode each chunk
    • It will build a gzip archive
    • gunzip this archive
  • congrats you have your attachment.

How to download excel template attached to catalog item via UI macro?

Requirement-

I have a catalog item form, which has a UI macro which lets user to Download a excel template. Where the excel template will be stored or attached, so when ever user clicks, it downloads a template?

Solution:-

Create a UI macro with below script by adjusting instance name and attachment sys_id. Once done you can refer the same created macro on catalog item.

<?xml version="1.0" encoding="utf-8" ?>   

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">   

<p> <b><font color="red">Please download Form and Attach Updated Form, </font> <a href="https://YOURINSTANCENAME.service-now.com/sys_attachment.do?sys_id=18465214998902006604821bbb93ed1f" target ="_blank"><font color="blue">Click Here</font></a><font color="red"> to download form.</font> </b></p>   

</j:jelly>

Script to send attachment to third party from servicenow instance?

Here we have to write business rule:-

(function executeRule(current, previous /*null when async*/ ) {
      var attachment = new GlideRecord('sys_attachment');
      attachment.addQuery('table_sys_id', current.sys_id);
      attachment.addQuery('table_name', current.getTableName());
      attachment.query();
      while (attachment.next()) {
              sendAttachment(attachment);
      }
      function sendAttachment(att) {
              try {
                      var StringUtil = new GlideStringUtil();
                      var file_name = att.file_name.toString();
                      var gsa = GlideSysAttachmentInputStream(att.sys_id.toString());
                      var baos = new Packages.java.io.ByteArrayOutputStream();
                      gsa.writeTo(baos);
                      baos.close();
                      var base64EncodedData = StringUtil.base64Encode(baos.toByteArray());
                      sendRequest(base64EncodedData, file_name);
                 

              } catch (Exception) {
                      gs.log('Failed sending Attachment to due to Exception: ' + Exception);
              }
     }
      function sendRequest(encData, file_name) {
              //Set up variables
              s.setStringParameter('attachment.filename', file_name);
              s.setStringParameter('attachment.type', encData);
      }
})(current, previous);

How to include all attachments from record in email?

  • If you have attachemnts attached to records and want to send all notifications then it is just a matter of making a check box true.
  • Go to your desired notification and make the “Include attachments” check box as true.
  • If your record has an attachment it will be sent over email as a physical attachment.

How to attach specific attachment to email sent from servicenow?

There might be a scenario where the attachment is not attached to the record but you have to send some attachments in the notification. This can be done in 2 ways.

  • Send physical attachment
  • Send attachment download link in the mail.

Send physical attachment

To send a physical attachment we have to create a Business rule to add attachment as physically in the notification. Create Business Rule on Email table with the following details:

  • Table: Email [sys_email]
  • When: Before
  • Insert: True
  • Condition- Mailbox is Outlook AND any other condition to match your requirement
  • Script – below
var grAttachment = new GlideRecord('sys_attachment');
grAttachment.get('<your_attachment_sys_id>'); 
//replace <your_attachment_sys_id> your attachment sys_id
var attContent = new GlideSysAttachment().getContentStream(grAttachment.sys_id);
new GlideSysAttachment().writeContentStream(current, grAttachment.getValue('file_name'), grAttachment.getValue('content_type'), attContent);

Send attachment download link in the mail

  • This will add a link in your notification to download the attachment.
  • When a user clicks on that link they will be asked to login to the ServiceNow instance if they are not logged in. Once logged in attachment will be downloaded.
  • To have a link in the notification we have to create an email script as follow and use it in the notification
  • Create email script- add_attachment_link
var attachmentSysId = 'a7cb84bf2f1630107f282aa62799b6ae'; // get sys_id your attachment from sys_attachment table
var nameOfAttachment = 'Click here to download'; //Name on link
var link = "<a href = /sys_attachment.do?sys_id=" + attachmentSysId + ">" + nameOfAttachment + "</a>" ;
template.print(link);
  • Once an email script is created open your notification and call mail script into it
  • Open the notification and write the below code at bottom of notification “Message HTML”
${mail_script:add_attachment_link}

This will add a link to your notification to download the attachment.

I want to add attachment box in service catalog item?

  • Starting from Paris release we have an “attachment” variable type and it is easily used in record producer or catalog item to add attachment.
  • The variable lets you upload an attachment for a question of the item. After you upload the attachment, you can also download, update, and delete it. 

Is it possible to track in the activity log when an attachment is attached or removed?

Yes, you can also track removal of an attachment with a business rule on the sys_attachment table when=after and checkmarks for insert, update, delete.

	if (current.table_name == 'u_ridac' || current.table_name == 'rm_story')
{
  AttachmentAudit();
}

function AttachmentAudit() {
  var attachmentMsg = '';
  var gr = new GlideRecord(current.table_name);
  if (gr.get(current.table_sys_id))
  {
  if (current.operation() == 'delete') {
  attachmentMsg = 'Attachment deleted: '+current.file_name+' by ' +current.sys_created_by+' on '+gs.nowDateTime();
  }
  else {
  attachmentMsg = 'Attachment added: '+current.file_name+' by ' +current.sys_created_by;
  }
  gr.work_notes = attachmentMsg;
  gr.update();
  }
}

How do Attachments Work in ServiceNow?

  • Unlike many tables in ServiceNow Attachments table (sys_attachment) is tricky. There are two tables that do the job of storing and retrieving the attachments in ServiceNow.
    • Attachments (sys_attachment)
    • Attachment Documents (sys_attachment_doc)
  • When you upload a file into ServiceNow as an attachment, the Attachments (sys_attachment) table stores the metadata such as File Name, Content-Type, File Size, Sys_ID, and Table of the Record on with the attachment is made, etc. 
  • Whereas the contents of the attachment are stored in the Attachment Documents (sys_attachment_doc) table.
  • Creating just a record in the Attachments table using GlideRecord.initialize() method will create an attachment for the record but when you try to open it, the file throws an error message stating the file is empty. This is because the attachment record doesn’t have corresponding Attachment Document records.
  • The binary data of the attachment is split into 4KB chunks and are stored in the Data field of the table.
  • The length field in the table defines the number of bytes stored in this chunk and the Position field defines the sequence of data that should be put back while retrieving the attachment for viewing or downloading and we got the Sys Attachment field which gives the sys_id of the Attachment Record.
  • Each Attachment file in attachments tables might have one or more Attachment Document records.
  • ServiceNow combines multiple Attachment Document records in sequence and returns them to the users for viewing.
  • ServiceNow provides GlideSysAttachment() API to handle attachments. It has some interesting methods which can be used to play with attachments and their contents. It creates an instance of GlideSysAttachment class.

What is ServiceNow Document Viewer?

ServiceNow comes with this interesting plugin- ServiceNow Document Viewer to view documents directly rather than download them to view them in their native applications. Though ServiceNow Document Viewer is active by default, it needs to be enabled at the table level to use it.

Make sure system property com.snc.documentviewer.enable_document_viewer is set to true or create it if it does not already exist.

Procedure:

  • Navigate to System Definition>Dictionary
  • Search for the table where you want to enable Document Viewer.
  • Open the record with type as Collections and empty name.
  • Enter use_document_viewer=true in the attributes.
  •  View UI Action will be visible on the attachments instead of Download, clicking it will open the attachment in a separate window.

How to Disable Attachments on a table in ServiceNow?

Attachments on a form can be disabled using dictionary attributes.

Procedure:

  • Navigate to System Definition>Dictionary.
  • Search for the table where you want to enable Document Viewer.
  • Open the record with type as Collections and empty name.
  • Enter no_attachment in the attributes.

Copy Attachment from one table to another | Attachment from Incident to Problem?

  • I have explained how to Copy Attachments from one table to another using Business Rules.
  • Table – Requested Item
  • When to Run – Before Update
  • Condition – Send Attachments to True
  • Scripts – below
(function executeRule(current, previous /*null when async*/ ) {
    // Add your code here
    var copy = new GlideRecord('problem');
    copy.addQuery('parent', current.getUniqueValue());
    copy.query();
    if (copy.next()) {
        GlideSysAttachment.copy('incident', current.getUniqueValue(), 'problem', copy.getUniqueValue());
    }
})(current, previous);

What is the maximum number of documents you can attached on Service Request catalog task in ?

  • In ServiceNow, the maximum number of documents that you can attach to a Service Request Catalog Task may vary depending on your specific instance configuration and any customization that has been implemented.
  • By default, ServiceNow allows you to attach multiple documents to a record, including catalog tasks.

What are the filetypes ServiceNow support for attaching file to Service Request Catalog Task ?

  • Regarding the file types supported for attaching files to a Service Request Catalog Task, ServiceNow generally supports a wide range of file types.
  • Common file types such as documents (e.g., PDF, DOCX), images (e.g., JPEG, PNG), spreadsheets (e.g., XLSX), and others are typically supported.
  • However, the exact file types supported can also depend on your ServiceNow instance’s configuration, including any customizations or restrictions implemented by your organization.

What is the the maximum file size of each document you can attached against a Service Request catalog task?

  • The maximum file size for each document that you can attach to a Service Request Catalog Task is also configurable and can vary based on your instance’s settings. 
  • By default, ServiceNow allows attachments up to a certain size limit.
  • The specific maximum file size limit can be adjusted by ServiceNow administrators in the system properties or through custom configurations.
  • To determine the maximum number of documents, supported file types, and maximum file size for attachments on Service Request Catalog Tasks in your specific ServiceNow instance, it is recommended to consult your instance administrator or refer to your organization’s ServiceNow documentation or guidelines.

Code to Copy attachments to RITM From Sc Task?

  • Configure Below After Business Rule :
    • Table  : sys_attachment 
    • When : After and Insert 
    • Filter condition : Table Name is sc_task
    • Script – below
(function executeRule(current, previous /*null when async*/) {
//GlideSysAttachment.copy('sc_task',current.sys_id , 'sc_req_item', current.request_item);
// Add your code here
var id = current.table_sys_id;
var gr = new GlideRecord('sc_task');
gr.addQuery('sys_id', id);
gr.query();
if(gr.next()){
var ritm = gr.request_item;
var att = new GlideRecord('sys_attachment');
att.initialize();
att.file_name = current.file_name;
att.content_type = current.content_type;
att.compressed = current.compressed;
att.table_name = 'sc_req_item';
att.size_bytes = current.size_bytes;
att.size_compressed = current.size_compressed;
att.table_sys_id = ritm;
var attRec = att.insert();
var attDoc = new GlideRecord('sys_attachment_doc');
attDoc.addQuery('sys_attachment', current.sys_id);
attDoc.query();
while(attDoc.next()){
var attDocCopy = new GlideRecord('sys_attachment_doc');
attDocCopy.initialize();
attDocCopy.sys_attachment = attRec;
attDocCopy.position = attDoc.position;
attDocCopy.length = attDoc.length;
attDocCopy.data = attDoc.data;
attDocCopy.insert();
}
}
})(current, previous);

How do you add images to a work notes?

If you are trying to add images to work notes, just upload the image as an attachment to the ticket, it gets added to the work notes.

How to export a ServiceNow record as a PDF file and attaching it back to the record?

  • In ServiceNow you often have the need to export a record as a PDF, whilst this is not necessarily difficult, occasionally you want to take this a step further and have this PDF automatically attached back onto the originating record as an attachment.
  • Below we outline a basic set of scripts that help you achieve this.
  • We start with a Server Script that uses a new custom user account to read and export the record, this record is then saved back to the originating record as an attachment.
var rm = new sn_ws.RESTMessageV2();
rm.setHttpMethod('GET');
var url = gs.getProperty("glide.servlet.uri") + current.getTableName() + '.do?PDF&sys_id=' + current.sys_id;
rm.setEndpoint(url);
rm.setBasicAuth(gs.getProperty('pdf.export.username'), gs.getProperty('pdf.export.password'));
rm.saveResponseBodyAsAttachment(current.getTableName(), current.sys_id, current.number + ".pdf");
var response = rm.execute();
  • This script requires setting up 2 system properties, a username and a password that correspond to a user account that is used to generate the PDF.
  • Make sure that you have a user account that matches these system properties otherwise, this will not work.

Leave a Reply