logo

NJP

Friendly Short URLs with Processors and UI Actions

Import · Mar 28, 2018 · article

Hi Everyone!

A few weeks after our Go-Live of ServiceNow I received a request from someone on our Service Desk to think about a TinyURL-Like service for sharing links to tickets across our organisation. While it works to just copy/paste the ugly URL that is generated when you go to an Incident, in some circumstances a human-readable link is nicer (Company communications, chat windows, talking to people who may not trust illegible URLs, generally understanding where you are going to land if you click the link)

After some digging through Community (sources at the bottom) and not coming up with a lot of help, I was able to use a Processor and some UI Actions to accomplish what I think is a fairly elegant solution. I'm sharing it here to help anyone with a similar request.

Step 1: Write a processor

As I was looking to make this work across a few tables (Incident, Request, Request Item) I would have liked to make my code more reusable, but including the table as a parameter was again undermining the whole idea of a "short URL". Here is my solution:

URL Format: https://.service-now.com/short_url.do?tsknum=INC0000123

following your standard number schemes & very readable!

Type: ScriptParameters: "tsknum"

Path: "short_url"

Script:

(function process(g_request, g_response, g_processor) {

    //Get the parameter
    var taskparam = g_request.getParameter("tsknum");
    var sysid = '';

    // If it's an incident
    if (taskparam.toLowerCase().includes("inc")) {
        var gr = new GlideRecord("incident");
        gr.addQuery("number",taskparam);
        gr.query();
        if (gr.next()) {
            sysid = gr.getUniqueValue();
            g_processor.redirect("/nav_to.do?uri=/incident.do%3Fsys_id%3D" + sysid);
            //For troubleshooting / testing, swap the above line with this one:
            //g_processor.writeOutput("Found Incident: " + gr.getUniqueValue());
        } else {
            g_processor.redirect("/navpage.do");
            g_processor.writeOutput("No Incident Found");
        }
    // If it's a request
    } else if (taskparam.toLowerCase().includes("req")) {
        var grReq = new GlideRecord("sc_request");
        grReq.addQuery("number",taskparam);
        grReq.query();
        if (grReq.next()) {
            sysid = grReq.getUniqueValue();
            g_processor.redirect("/nav_to.do?uri=/sc_request.do%3Fsys_id%3D" + sysid + "%26sysparm_view=my_request");
            //g_processor.writeOutput("Found Incident: " + gr.getUniqueValue());
        } else {
            g_processor.redirect("/navpage.do");
            g_processor.writeOutput("No Request Found");
        }
    // Finally, if it's a Request Item
    } else if (taskparam.toLowerCase().includes("ritm")) {
        var grRitm = new GlideRecord("sc_req_item");
        grRitm.addQuery("number",taskparam);
        grRitm.query();
        if (grRitm.next()) {
            sysid = grRitm.getUniqueValue();
            g_processor.redirect("/nav_to.do?uri=/sc_req_item.do%3Fsys_id%3D" + sysid + "%26sysparm_view=my_request");
            //g_processor.writeOutput("Found Incident: " + gr.getUniqueValue());
        } else {
            //redirect to homepage if it doesn't match
            g_processor.redirect("/navpage.do");
            g_processor.writeOutput("No Request Item Found");
        }
    } else {
        //Generic catchall redirect to homepage
        g_processor.redirect("/navpage.do");
    }

})(g_request, g_response, g_processor);

I know the above has some limitations, like no handling of two records with the same "number" - but I'm OK with this. For a normal OOTB implementation it should work nicely.

Step 2: Create UI action(s)

For our Service Desk friend to be able to access this action easily, it should be accessable on the forms of the tasks they are using. In my implementation, I'll create three actions on incident, sc_request, and sc_req_item tables. As these all extend the Task table, the number field is compatible!

Name: Copy ShortLinkTable: Show Update: TrueClient: True

Form Button/Context/Link:

Onclick: getShortLink();

This is the function we are going to write and call when the user clicks the action

Script:

function getShortLink() {
    var instance = window.location.hostname + "/";
    var shortUrl = g_form.getValue('number');
    window.prompt("Copy to clipboard: Ctrl+C, Enter", instance + "short_url.do?tsknum=" + shortUrl);
}

Very simply, the script gets the current domain (so it'll work in all your environments) and formats the URL with the current number field, then presents it to the user in a prompt pre-selected for quick copy/paste. Neat!

Here's the end result:

image

And the popup:

image

I hope this helps another admin somewhere along the line!

-Andrew

References:

Constructing Tiny URLs by rickseiden(infosys)

Processors (SN Docs)

Processor Redirects (SN Docs / API)

UI Action - Copy certain fields to the clipboard by Brad Tilton

Client/Server UI Action Code by SNGuru

image

View original source

https://www.servicenow.com/community/itsm-articles/friendly-short-urls-with-processors-and-ui-actions/ta-p/2307123