AbhishekGardade
Giga Sage

As you may aware of that you can store more than just text within ServiceNow, in the form of attachments. You can store binary data as well, including pictures, audio, and even executable files.

There are two tables which is dealing with attachments.

  • 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 the size of the attached file.

Important Classes / API’s: used :

  • GlideExcelParser() :You can parse .xlsx formatted Excel files. The GlideExcelParser methods can be used in global and scoped scripts. The API name space 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. 

 

1. Fetching Contents from Excel File Attached to your 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];

}

2.Fetching Contents from CSV File Attached to your 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);

       }

3. Fetching 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);

#Copying an Attachment from One Table/Record to Anothet 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);

#Attachment-related System 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. 

 

Property

Values

Description

glide.ui.attachment_drag_and_drop

true/false

Enable/disable drag-and-drop to attach a file

com.glide.attachment.max_size

Integer (MB)

The maximum size (in megabytes) for individual file attachments. Leaving this field blanks allows attachments up to 1GB.

glide.attachment.role

Comma-separated list

Enter 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.extensions

Comma-separated list

Enter 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/false

This 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.


That's it!!!! Thanks for reading and do comment with your suggestion/improvements if any.

Hope you will find it as helpful. Dont forget to Mark it Helpful, Bookmark.
Thanks,
Abhishek Gardade

 

EDIT : Added code for getting attachment content from TEXT File

Comments
Priyanka Patil2
Tera Contributor

What is obj[row[key]] = row[value];

AbhishekGardade
Giga Sage

Here I am creating a dynamic KEY and VALUE pair for json object. So depending upon excel rows, it will create a json object dynamically.

AbhishekGardade
Giga Sage

Here I am creating a dynamic KEY and VALUE pair for json object. So depending upon excel rows, it will create a json object dynamically.

Tippireddy Bhav
Tera Contributor

Thanks @Abhishek Gardade for the detailed information.

Can we fetch contents from a .msg file attached to a record?

Vishali3
Tera Contributor

I have owner column in csv file..... I need to fetch the owner value from csv and to populate it in the ritm owner field using script.... So please help me with that

Shobha N
Tera Contributor

Hi @AbhishekGardade ,

 

Do we have any method to extract content from PDF?

Community Alums
Not applicable

Man you are great hehe you helped me, it took me a while to understand what show, but it really helped me. thank you very much and from mexico greetings.

NileshSurwade
Tera Contributor

Hi anybody tried for CSV inputs seems it is not working for me, When I am trying to read data using getBytes function, giving me the error as "Function not available". Let me know if anybody is able to do it successfully.

NileshSurwade
Tera Contributor

Hi @AbhishekGardade , I have followed your steps I able to read CSV file data in Background Script with out error, However if i use the same code in Business Rule I am getting "Error MessageError running business rule 'Testing for Record' on sys_attachment: DataFile2.csv, exception: org.mozilla.javascript.EvaluatorException: The choice of Java constructor java.lang.String matching JavaScript argument types (null) is ambiguous; candidate constructors are: String(byte[]) String(java.lang.StringBuilder) String(java.lang.StringBuffer) String(char[]) String(java.lang.String) (sys_script.505e792807f4711099d1fa7f7c1ed0c7.script; line 9)" from the Line "var originalContentsInFile = Packages.java.lang.String(bytesInFile)" Any Suggestion on this one.

sajerond
Tera Contributor

NileshSurwade

 

Same here.

Steve214
Tera Contributor

This was helpful and I was able to get it to work (CSV) in my developer instance (Tokyo) on the incident table.  When I copied the code to the company Dev instance (Utah) (custom global table), I get indistinguishable data.  Any thoughts on why?  I'm using the same exact files to test

 

  

drew-easley
ServiceNow Employee
ServiceNow Employee

If you're running a server scoped script, I found this content helpful to retrieve attachments as strings:

 

 

/* var source = {
   table: 'table_name',
   sys_id: 'table_sys_id_where_attachments_are'
} */

function getAttachment(source) {

   var attachment = new GlideSysAttachment( );
   var agr = attachment.getAttachments(source.table, source.sys_id);
   while(agr.next()) {
      var content = attachment.getContent(agr);
    }
}

 

Documentation here

sajerond
Tera Contributor

I was able to get this to work successfully for csv.  The data from the csv populates a html field as a data dump (no parsing necessary)  The issue I had to create a workaround for was there were multiple attachments for the same record and each attachment had to be entered to a different field.  I ended up creating individual tasks to dump the data to a description field then copying the task desc field to the parent corresponding field and deleting the task.  Not ideal but it works

Prakash53
Tera Contributor

Hii  @AbhishekGardade  ,The info you provided is not working here

Fetching 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);

Abhishek_VG
Tera Explorer

@Prakash53 What error you are geting? have you checked the scope ? Please try adding try catch block

Version history
Last update:
‎08-31-2019 06:48 AM
Updated by: