I am releasing my Google Chrome extension with tools to automate many ServiceNow ticket tasks. It is a easily extendable extension in which you can autopopulate and autoroute tickets, automatically refresh your queues, play a sound when a new chat comes in, present hints and tips to agents, and many other features.
Every ServiceNow implementation is different so don’t expect to be able to drop this extension right in. To use it will require modifications specific to your implementation of ServiceNow. If you understand basic Javascript you should be able to make use of this. No APIs are used other than what is available in ServiceNow itself.
This tool was developed using the Chrome Developer Tools (Ctrl+Shift+I) to get fields and ids you will need to make the tool work. I do not recommend even attempting to use this unless you are a fairly experienced web developer.
All code is available at my GitHub link at the very top of this web site or click here
Disclaimer
I am in no way affiliated with ServiceNow. This is simply a suite of assisting and automation tools I developed when I was an agent for a large multinational corporation that handled thousands of tickets per day. All trademarks and intellectual property are owned solely by ServiceNow. This tool is simply a easy way to fill out some of the fields within the webpage to save agents/technicians a lot of time.
If you attempt to develop your own version of this tool you should use your test environment and not a live server.
Features
- Ticket Autopopulation – Uses regular expressions (RegEx) to search ticket subject and text for common issues and presents a dialog to populate the ticket based on potential matches
- Chat notifications (sound and notification bubble) – Pops up a Google Chrome notification bubble when new chats are received and plays a sound
- Autorefresh & Notifications – Automatically refreshes incident and task lists and pops up a notification bubble when new ones appear
- One-click Routing – Allows you to put a ticket into the “In Progress” state and send it to a resolver group without filling out any fields (useful for routing to yourself to fill out later or foreign language resolvers)
- SLA monitoring – Incident list uses color coding going from Green to Orange to Red based on how close to SLA the ticket is
- Popup Menu – Programmable pop-up menu with quick functions to help agents perform tasks quickly
Getting Started With ServiceNow Automation
You will need to update the URLs in the manifest and the files. By default they are .servicenow.com. If you do not update the manifest before creating a Google extension Google will not run the code on any of the pages as the correct URLs are required in the manifest for any code to execute.
Once you have made that change you will need to install the extension in your Chrome browser. There are lots of good instructions online on how to do this. I recommend starting at Google’s own tutorials here if you have never developed a Chrome extension before.
Now it’s time to head to your ServiceNow implementation. Again I highly recommend using your company’s test environment to avoid causing any production issues.
Autorouting in ServiceNow with RegEx
To handle the most common tickets we use regular expressions to search the tickets for common issues. This is done in an array located in autoroute.js. Here is an example:
{ RegEx: ".*\\b(BOX|APP-BOX.COM|APP-BOX|BOX.COM)\\b.*", CI: "Box External File Sharing-PROD", Resolver: "APP-BOX.COM", Category: "application", SubCategory: "enterprise", SubCategoryType: "configure", INCCategory: "application", INCSubCategory: "configuration_error_single", INCSubCategoryType: "other_single", KB: "Attached Knowledge article: [code]<a href='https://*.service-now.com/kb_view.do?sys_kb_id=909764ae8746f000297afb49c9434da6'>KB0018582</a>[/code]" Notice: "All Box issues should go to the Box resolver group" Label: "Box File Sharing Service" }
In this example we are looking for tickets submitted about the popular Box file sharing service. The first line is the RegEx line and looks for Box, App-Box, Box.com, etc. You can search for as many keywords as you want to. You may also use more advanced regular expressions to get extremely accurate and tailored results.
Usage – How to use the ServiceNow Chrome extension
When you open up a ticket the extension will search the ticket. Then it will present possible matches at the top as bubbles. The agent/technician can then click the correct bubble. The agent can fill out the ticket the old fashioned way if no matches are found.
If a bubble is pressed the following actions occur:
- The Configuration Item (CI) is automatically populated
- All categories and subcategories are selected
- The relevant KB article is attached
- The ticket is presented to the agent for review
- Nothing is saved until you submit the ticket providing the opportunity to ensure everything has populated correctly
You may also use the optional “Notice” and “Label” fields. These allow the extension to provide specific labeling and instructions to the technician to help reduce routing errors.
That’s about it! Let me know if you have any questions and I will try my best to answer them for you.
Hello James!
I’m in the process of creating my own ServiceNow plugin for my company, and I was excited to see this post because I was hoping I could pick your brain about something..
I looked through the code of your plugin, and it seems that you’re using some ServiceNow API functions like g_form.setValues to populate certain fields.
Whenever I try to use those same g_form functions in my plugin, I receive the errors that “g_form” is not defined, or that “g_form” is an anonymous function. This was really confusing to me, because when I run those same functions through the Chrome console, it behaves exactly as intended…
I did some research about it, and my understanding was that Chrome Plugins can’t use use web-page side functions
And yet, you seem to have made it work. Any tips & tricks you can provide me are greatly appreciated!
Respectfully,
Mike E
Hey Mike,
Your research is absolutely right that the content scripts from plugins can’t access the webpage.
But there are some things we can do that allow me to get away with the things I do in this extension. Check out the section on the document you linked called “Understand Content Script Capabilities”.
In here there is a list of APIs that are actually allowed for extensions to use in the isolated world. These are the ones of interest to us:
“i18n
storage
runtime:
connect
getManifest
getURL
id
onConnect
onMessage
sendMessage”
So Chrome allows us to use sendMessage and onMessage to communicate with content scripts. It’s a special exception they allow in case the extension and the webpage need to communicate with each other.
Now, understanding this, let’s take a look at some code:
var s=document.createElement('script');s.src=chrome.extension.getURL('autoroute.js');s.onload=function()
{this.parentNode.removeChild(this);};(document.head||document.documentElement).appendChild(s);var s=document.createElement('script');s.src=chrome.extension.getURL('incident-script.js');s.onload=function()
{this.parentNode.removeChild(this);};(document.head||document.documentElement).appendChild(s);chrome.runtime.onMessage.addListener(function(request,sender,sendResponse)
{console.log('Content Incident: Message posted');postMessage(request,'*');});
Now in this script we are injecting my incident-script.js onto the web page. Now I add an event listener to listen for chrome.runtime.onMessage (we are allowed to see a Chrome runtime level message despite being sandboxed) and calling sendMessage for it to be able to communicate with the DOM script object.
Now let’s look at the script we are injecting.
Here is the listener for our injected script to receive messages from our content script via the Chrome message API:
addEventListener('message',function(request)
{console.log("Incident Script message received from postMessage "+request);if(request.data&&request.data.data)
{if(request.data.type=="route")
{if(confirm("Route to "+request.data.data.ResolverName+"?"))
{routeTicket(request);}}
else if(request.data.type=="action")
{if(confirm("Put ticket into 'In Progress' state?"))
So what happens here is that the injected script and the sandboxed content script use postMessage to communicate with each other without violating Chrome’s separation of DOM variables from content scripts. You can see that I can send different message types of my choosing such as “route” or “action”. You can also pass data in these messages!
So to make a long story short we are still using script injection to inject our own script to the DOM. This injected script *can* access on-page variables but normally our plugin’s content scripts cannot. We use Chrome’s onMessage framework to work around this so that our content script can communicate with our injected script!