• Career Mentor Group

How to Validate File Attachments in ServiceNow Service Portal

ServiceNow is the market leading ITSM solution with thousands of customers. One of its core strengths is self-service combined with automation. However, file attachments that aren’t formatted properly can break the entire automation process. This results in longer times to resolution and decreased customer satisfaction. In this blog article I will describe how to solve the file formatting and data validation challenge for file attachments in ServiceNow Service Portal. I will first showcase some ServiceNow attachment basics. Then, I will provide a solution to validate user attachments before they’re submitted.


Service Portal and Service Catalog

Service Portal is a user-friendly alternative to using the Now platform designed for self-service and built with a more modern UI. The main benefit of Service Portal over the backend Now platform is the visual organization and modular aspect of the portal which allows multiple different apps to be visible on the page at once.


Service Catalog, on the other hand, is the set of self-service items that a user can request such as services and product offerings. For example, the service catalog may include a request to reset a user’s password, or it may have a monitor that a user can order.


Describing the Problem

When a user accesses Service Portal to submit a form, for incidents, requests, or catalog items, they are often asked to provide an attachment containing information required to complete a related task. In many cases, it’s important that the attachment is formatted perfectly. For example, when attaching an Excel sheet, the required column headers must be provided, and the data properly formatted. File validation not only saves time caused by user error but can be an important step in automating processes that depend upon files being submitted in a specified format.


Personally, I’ve found it important to validate user-submitted attachments that later go on to be used in PowerShell scripts to automate processes in Active Directory and Microsoft Exchange. But the possibilities of using attachments with automation are limited only by your imagination.


Making a Service Catalog Attachment Mandatory

Service Portal provides two easy options for creating a mandatory attachment on the UI. By default, almost all records in ServiceNow have a way to upload an attachment to the form, but in Service Portal you can also create an attachment variable if you want to have more control over what files users upload. Both options allow you to specify whether the attachment should be mandatory but creating a new variable of the attachment type has the benefit of giving you more control over the attachment when writing a client script. Regardless of what you choose, both options can be set to mandatory by simply checking the ‘mandatory’ checkbox as seen in the screenshots below.



Figure 1 - Mandatory default attachment

Figure 2 - Mandatory attachment variable

Alternative Client Script for Mandatory Attachments

If you want to have more control over how attachments are handled on the form you can write your own client script to check for an attachment instead. This allows you to not only make an attachment mandatory but also choose what to do when a form is submitted without one. The following script takes advantage of Service Catalog’s onSubmit function so that it is executed whenever the user tries to submit the form. If there is no attachment on the page, then the client script will stop the form from being executed and return an error message letting the user know to add an attachment.

function onSubmit() {
    if (window == null) {
        // portal
        if (this.document.getElementsByClassName('get-attachment').length == 0) {
           g_form.addErrorMessage('You must add an attachment before submitting this incident');
           return false;
        }
    } else {
        // native view
        var length = $j("li.attachment_list_items").find("span").length;
        if (length == 0) {
            g_form.addErrorMessage('You must add an attachment before submitting this incident');

           return false;
        }
    }
}

Figure 3 - Mandatory attachment client script


Figure 4 - Client script configuration for mandatory attachments

Validating an Attachment for Name and Content

You may want to validate a file that a user has uploaded before the form is submitted to ensure that the file is formatted as expected. For example, you may have a form which asks the user to upload a CSV file and want to make sure users are not uploading Excel, Word, or .txt files instead. Taking it a step further, it’s also possible to have a script “proofread” the attachment before a form is submitted, such as making sure that a file is in a specified format (checking column headers, properly formatted data, etc.). This can be very useful to cut down on time spent due to users uploading files with missing information or mis-formatted cells.


How? By using a client script with a GlideAjax call to the server, it is possible to check for an attachment that the user has uploaded and then read the file to ensure it’s in the correct format. The following is my example of a script that will check if a user has uploaded a CSV file with a “messageID” header column. If you’re not familiar with the GlideAjax API and using client/server scripts in tandem I suggest you take a look at this cheat sheet to help you first.


onChange Client Script to Trigger File Validation

The client script below will check for an attachment on the form and send the attachment data to the server where it will be read and processed. The server will send an object back containing the results of the processing, i.e., what type of file the user uploaded and if the file is in the expected format. If the file has an error, a message will be displayed on the service catalog form. Below you can see the client script to send the attachment data from my attachment variable named ‘csv_file’. I use the g_form.getValue() method to retrieve the sys_id of the attachment so the server can find it in the database.


function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || newValue == '') {
        return;
    }
//Get value of attachment variable named ‘csv_file’
    var attachment_id = g_form.getValue('csv_file');
//Call server script ‘getSC_attachment’ and send data
    var ga = new GlideAjax('getSC_attachment');
   ga.addParam('sysparm_name', 'get_attachment');
   ga.addParam('sysparm_attachment_id', g_form.getValue('csv_file'));
//Response from server is used as a parameter in the readAttachment function below
   ga.getXMLAnswer(readAttachment);
}

function readAttachment(answer) {
    var clearvalue; // Stays Undefined
    if (answer) {
        var returneddata = JSON.parse(answer);
        if (returneddata.status.includes('failed')) {
           g_form.addErrorMessage(returneddata.message);
           g_form.clearValue('csv_file');
           g_form.showFieldMsg('csv_file', 'File must be in CSV format and contain a MessageID column', 'error');
        }
    } else {
        alert("No answer from the server");
    }
}

Figure 5 - onChange client script for file validation


Figure 6 - onChange client script configuration for file validation

Server-side Script Include

While the client script above is used to check for an attachment and trigger a job on the server, the server-side script is meant to do the heavy lifting. Since the client is not able to open and read an attachment on its own, a client-callable script include will be called that will run on the server to process the user’s attachment. My script below checks that the attachment sent from the client is a CSV file containing a header labelled ‘messageID’ and does the following:

  • Find the user’s attachment in the database

  • Validate the file name/ file type

  • Open and read the file contents (contents can be displayed on the form)

  • Process file for a specified format (e.g., checking column headers and values in a CSV or Excel file)

Basically, the server script can be configured to read and validate files and then let the user know if they’ve uploaded the wrong file type or if there’s a typo. Keep in mind that this script can be customized to validate almost any kind of file and its contents for whatever project you have.


var getSC_attachment = Class.create();
getSC_attachment.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    get_attachment: function() {
        var message = "";
        var grAttachment = new GlideRecord('sys_attachment');
        grAttachment.get(this.getParameter('sysparm_attachment_id'));

        var filename = grAttachment.file_name.toString();
        var filetype = filename.split('.').pop().toString();

        if (!filetype.includes('csv')) {
           gs.log('file type is not csv, setting results', 'SCTASK');
            var results = {
               "status": 'failed',
               "content": "null",
               "filetype": filetype,
               "message": "Incorrect attachment format, file must be in CSV format"
            };
           grAttachment.deleteRecord(); //invalid file type, removing file
            return JSON.stringify(results);
        } else {
            //file is CSV but read file for a proper MessageID column
            /*
            This section is where the server script will read and validate the file for the messageID header. If you would like assistance in setting up the script to parse and validate your custom file please feel free to contact us at the link below. 
           */
        }
    }
});

Figure 7 - Script include for file validation


Figure 8 - Script include configuration for file validation

In the screenshot and script above you can see that the script is checking to make sure that the user has uploaded a CSV file with a ‘MessageID’ column header and will remove the attachment and return an error for other file types. The error message will be sent back to the client script and will be displayed on the form (as seen below), letting the user know to upload the correct file instead.


While this script is great at checking for a CSV file with a certain header, it’s also very easy to edit this script to validate other files for whatever use cases you may have!



Figure 9 - Service Catalog form w/ attachment error message

Conclusion

Attachment validation can be critical when it comes to automating actions, such as PowerShell Scripting based off an incident submittal. Hopefully this blog gave some good insight on how to begin the process of validating a wide variety of attachments.


Interested in how we can help you with ServiceNow file validation or other automation tasks? Reach out to us! You can set up a meeting with us by clicking here. We’d love to have a conversation on how we can help you!