Welcome to another article where our Technical Architect, Callum Ridley, looks into Advanced MID Server solutions. In this article he shares how to create your own version of the JavaProbe Script Include that adds additional functionality and helps us protect our sensitive data in transit.
Fixing what’s broken
OK, so the JavascriptProbe isn’t technically broken, but there are certainly some oversights and some things we can add to make our lives a bit easier. Here’s a list of what we’ll be adding:
- Encryption of sensitive data
- Synchronous processing (for development testing)
- Automatic discovery sensor skipping
Protect your credentials!
The JavascriptProbe provided by ServiceNow includes just one method for adding parameters to our requests addParameter(name, value). Let us take a look at this method:
addParameter : function(name, value) {
var el = this.payloadDoc.createElement("parameter");
el.setAttribute("name", name);
el.setAttribute("value", value);
},
What happens if for example we want to send a username and password to the MID server for some sort of integration? Well this is going to send it in plaintext. Yes, you read that right! In practical terms the means the following:
- The sensitive data will be stored within the ECC queue for any user with enough access to go and steal
- The sensitive data will be transferred over the public internet in plaintext
- The sensitive data will be stored on the MID server in plaintext for a time whilst the job is processing
Admittedly, the second point there is of less concern due to the connection between MID Server and ServiceNow instance using SSL/HTTPS, but you just never know…
The good news is that this is reasonably easy to fix. ServiceNow actually provide the AutomationAPI that we can leverage to encrypt this data and have it automatically decrypted in memory on the MID server. I’m not entirely sure why ServiceNow hasn’t implemented this already.
addParameter : function(name, value) {
var el = this.payloadDoc.createElement("parameter");
el.setAttribute("name", name);
el.setAttribute("value", value);
},
addEncryptedParameter : function(name, value) {
var automationApi = new sn_automation.AutomationAPI();
var encryptedValue = automationApi.encrypt(value);
this.addParameter(name, encryptedValue);
},
Testing our new method, we can see the results in the outgoing ecc_queue entry:

Go on, I dare you, refresh that list again.
When developing on ServiceNow, if you’re anything like me, you’ll make good and extensive use of Background Scripts as a simple and quick way to test your script without having to navigate to a specific page, click a specific button, get a flow to trigger etc.
The same can also be said of MID Server scripts, but annoyingly there is then the need to navigate to the ECC queue and refresh the list over and over until you see a response come in for your request. You could be spending this time doing something much more productive, like sipping that sweet oat chai latte that’s slowly leaking through the bottom of the disintegrating takeaway cup. But let’s be honest, you don’t want (or have time) to clean up that mess, so let’s update our script to make this easier for us.
The MID Server is asynchronous by design, meaning that we need to find a way to make it function as though it’s synchronous. What if instead of manually refreshing ECC queue, we could get our script include to do it for us and let us know when a response has come in? We can do exactly that using GlideRecord to look for responses to our instruction and gs.sleep(milliseconds) to place a 2 second delay between “refreshes”. Couple both of those with a do-while loop and we’ve got ourselves a solution.
createSync: function () {
4141var strOutputEccId = this.create();
4141var intMaxItterations = 30;
4141var intCurrentItteration = 0;
4141var intWaitMillis = 2000;
4141
4141do {
414141gs.sleep(intWaitMillis);
414141var grEccInput = new GlideRecord('ecc_queue');
414141if (grEccInput.get('response_to', strOutputEccId)) {
41414141return gs.getProperty('glide.servlet.uri') + grEccInput.getLink();
414141}
414141intCurrentItteration += 1;
4141} while (intCurrentItteration < intMaxItterations);
4141return 'No response returned within allowed time of ' + ((intWaitMillis * intMaxItterations) / 1000) + ' seconds';
41},
My response says there’s been an error

Don’t worry, our response probably doesn’t have an error. The state we’re seeing is related to Discovery, the original and sole intended use for the MID Server (how times change). We can easily prevent this from showing an error state by adding a parameter to our request.
var bjp = new BetterJavascriptProbe('PersonalDevMID');
bjp.setJavascript('new MyClass().getMIDDateTime()');
bjp.addParameter('skip_sensor', 'true');
gs.info(bjp.createSync());

That’s great, but now we have to remember to add that parameter in every time we use the MID Server for executing javascript… or we could just add it in automatically. Back to our Script Include, where we can simply add the following into our create method.
create: function () {
41this.addParameter('skip_sensor', 'true');
41var egr = new GlideRecord("ecc_queue");
41egr.agent = "mid.server." + this.midServer;
41egr.queue = "output";
41egr.state = "ready";
41egr.topic = "JavascriptProbe";
41egr.name = this.name;
41egr.source = this.source;
41egr.payload = this.payloadDoc.toString();
41return egr.insert();
},
And that’s it. We’ve now got ourselves a better JavascriptProbe than the one provided out of the box. If you’ve followed along, you may already have your new Script Include ready to go. If not, download your own copy here.
Thanks Callum for such providing such a useful tool and an alternative for the out-of-the-box JavascriptProbe. If you're looking to enhance your digital transformation with customised solutions, UP3 can help you with that, take a look at our ServiceNow Managed Service page to see how.