Skip navigation

Developer Community

8 Posts authored by: rfedoruk

If you're an ancient & decrepit geezer like me and grew up in the 1980's, you probably remember seeing advertisements for these in your Archie comics...

XRay specs!  Giving you vision into untold secrets.

 

 

This month, I rediscovered an administrative "XRay Spec" for ServiceNow:  Show XML.  With it, you can see the invisible, and glean valuable secrets.  Here's 3 use cases to capitalize on Show XML

 

USE CASE 1:  DISCOVERY OF INVALID REFERENCES

Ever been in this situation?  You're looking at a form with a blank reference field, but for some reason the preview icon is still visible?

It happens when you have an invalid reference.  There's an invalid sys_id in the Affected CI field, or a record that has a sys_id but no display.  You'll see this in cases like...

- When you're populating stuff via manual sys_id's in a record producer or inbound action

- When you've used bad code migration strategies and have different sys_id's between instances THEN imported/exported data depending on those references.

- A rookie has populated a reference field in a script by using display value instead of sys_id

 

So lets use Show XML to figure out what's wrong.... (Right click in header -> Show XML).

This pops open a new window with the entire record in XML format.

OOPS!  Somehow Affected CI populated without a sys_id!

 

 

USE CASE 2:  FINDING THE SYS_ID OF A RECORD LIKE A BOSS!

You're looking at an incident for Prostetnic Vogon-Jeltz.  For whatever reason, you need his sys_id.  How do you get it?

 

If you said "click the preview, then right-click the user record header & copy sys_id" you're correct, but also slowShow XML right from the Incident!

 

USE CASE 3:  FINDING VALUES OF FIELDS NOT ON THE FORM

How many times have you needed to see the value of a field and actually modified the form to get access to it?  Don't be ashamed, we've all done it (but go ahead and slap yourself once, just to be sure).  If you've ever put a field on a public form exclusively for admin usage, slap yourself twice.  From now on, Show XML is all you need.  Lets say I have an eBonding relationship with a vendor.  I don't have correlation ID on the form, but I want to know if my Incident is related to an external ticket.  Right Click -> Show XML.

HOLY COW!!

 

SUMMARY

Remember... with Show XML, the *entire* record is at your fingertips.  Why bother with background scripts, form/list personalization, or record transitions when that powerful little Action is just a click away!

A customer recently notified me that they were missing a lot of important updates to tickets.  The updates were expected to be delivered via an email integration.

Checking sys_email, I noticed a ton of new received-ignored messages with failure messages like this...

The error string didn't provide any help, so I dug into the headers.  BAM!  All the failures had X-ServiceNow-Spam flags in the headers. 

That's critical info because of this default sys_property:

What troubled me is why this suddenly became a problem.  I managed to find KB0549426 which stated...
"Note that as of 6/29/2017, SPF checks now factor more heavily into a mail's spam score.  In order to be flagged as spam, a message must have an aggregate score of 6.2 or higher.  A soft SPF failure will add 6.0 to the score, whereas a hard SPF failure will add 7.0 to the score (immediately flagging it as spam).  It is recommended to check and ensure that your company's SPF records are correct and up-to-date, or some messages may be inadvertently marked as spam."

 

So that explains why inbound email actions have been so unreliable for the past couple weeks.  I recommend everyone check their sys_email logs for anything with "received-ignored" state.  You could be in my customer's position with a *TON* of missing data.

 

POSSIBLE RESOLULTIONS

- So the KB article instructs you to "update the SPF records", but this is coming from another ServiceNow instance.  Does this mean all SN to SN mail integrations are now suspect?

- Remove X-ServiceNow-Spam-Flag:YES from the "Ignore mail with these headers" sys_property.

But... but... #KillEmail

Yes, kill email when you can. In reality, Some systems and processes may still have components depending on an email initiation.  Here are some examples from my own history.

- support@company.com, service@company.com, contactus@company.com etc addresses that are externally facing need workflow driven responses.  (this is common in the hospitality space)

- legacy system is a starting point and has no rest/soap integration capabilities

- highly specialized staff that, for cultural or practical reasons, only uses email + 1 or 2 specialized tools (traders, field service staff, doctors, lawyers, etc)

 

Sometimes we have no choice in our inputs, and its better to win small than not win.

 

Before We Begin

  • Understand Inbound Email Actions, especially Section 6, which outlines how to handle email variables.
  • Understand Service Catalog Script API.  For further research, you can look at the Script Include "Cart" on your dev instance.
  • It is advised that you create your own email address in your environment to handle the intake.  In my example I created "term@company.com".  We ended up creating this such that anyone emailing the address was also sending to company@servicenow.com without realizing it.  In this fashion both the original sender & term@company.com are retained.  A further benefit is you can make separate addresses per workflow you wish to trigger. 
  • Text analysis is your enemy.  As much as possible ensure that your sender automated, not a person.  If that's not possible, resist attempts to make programatic decisions based on user entered email text.

 

Example:  Email initiated Termination

I've already created a Catalog Item with 3variables: terminee, subject, emailbody (HTML)

I'm assuming that whatever person / system sending will include in the body "priority:high" if priority needs adjustment.

Its also important to note that I don't generally use the request layer, so I will *also* want to modify the sc_req_item

 

Inbound Action

Name:  Email Based Term

Target Table:  Requested Item [sc_req_item]

Type: New

Order:  Anything lower (numerically) than your existing Incident items

Condition: email.recipients.toLowerCase().indexOf("term@company.com") > -1  (checks to ensure its coming to the controlling email address)

 

createRequest();
function createRequest() {
  var cart = new Cart();  //calling the cart API
  var item = cart.addItem('eb89a3b937e7d200a2982863b3990eab');  //sys_id of the catalog item I want to fire
  cart.setVariable(item, 'subject', email.subject) //sets catalog variable to the email's subject
  cart.setVariable(item, 'emailbody', email.body_html);  //sets catalog variable to email's body
   var rc = cart.placeOrder();  //this launches the catalog item, and creates a request object.  rc = the request object
  updateRITM(rc.sys_id);  //call a function immediately to update the ritm.  This must be a nested function, otherwise inbound actions get weird.
      //also, we're passing the sys_id of the request so we know what RITM to grab.
}

function updateRITM(req){
  var ritm = new GlideRecord('sc_req_item');
  ritm.addQuery('request', req);  //req is what we passed from the previous function. the sys_id of the request.
  ritm.query();
  while (ritm.next()){
    ritm.u_customer = gs.getUserID();  //my ritm table separately tracks its own customer, since I don't use Request
    ritm.description = email.body_text;  //we're still in the inbound action so why not exploit?
    ritm.priority = email.body.priority;   //good example of how to exploit email body variables
    ritm.update();
  }
}
event.state="stop_processing";  //stop evaluating inbound actions. This is why I keep this record's order lower than my incident from email rules.

 

Key Take-Aways

  • It is possible, and even handy to trigger workflow from email
  • if you want to modify RITM post insert, use a nested function where-ever you're calling the Cart API
  • Make sure inbound action(s) evaluate before your Incident creation inbound actions
  • Use stop processing once the script is complete.
  • Don't be afraid to exploit email.body.variables... especially if the email source is automated.

 

I can't remember when I was more disappointed with a ServiceNow message. 
Every year the Knowledge marketing message pushes deeper into near-IT and non-IT circles.  Stories of value delivered across business are elegantly written and beautifully shot in white papers and customer testimonials.  But what of those who's hands still bear the dust of the build?

 

"Get your geek on".  Oh you zany geeks, you!  Up to your old shenanigans again!  Anyone else feel like a box of crayons just got spilled onto the kids table at Thanksgiving? 
"Make something pretty now!"

 

But let me tell you this.. this product and this company would be *NOTHING* if it weren't for the kinds of people who #HackNow.  This company owes its dominant market position not only to the genius of Fred and his devs, but also to *YOU*, the developers and admins who slogged through terrible processes and work dynamics.  Expended your own sweat, tears, and effort to build great things.  Great things this company didn't even imagine when they sold it to you.

 

HACKERS LEAD THE WAY

What won the inaugural Hackathon at K13?  An ideation module.  Two product versions later, its emerging in the base product.

FruDevCon13?  A business continuity and disaster recovery automation app.  Two years later, 2/5 Innovation of the Year finalists are for BCDR

FruDevCon14?  Instantaneous portal deployment.  A year later... ServicePortal

 

Biometric scanning, robotics orchestration, social media asset databases, social media campaign automation, password archiving, public disaster portal pages, availability automation.

 

What will be next?  How many years would it have taken to realize those possibilities without Hackers like you?

 

A REAL MESSAGE FOR HACKNOW

 

Let the executives pat themselves on the back, toasting their success discussing solutions they've neither imagined nor built.

 

You, ServiceNow developer are not a geek at play.  It is the work of your hands that will be remembered.  YOU are the keystone of the Knowledge conference.  You are the font of the phalanx.  The very tip of the spear that's driving value creation in our industry. 

 

rain 300 hail

 

Join me on the front lines of the ServiceNow hacking.  Bring your frustrations, your rage, and your dreams.

Now that you have no excuses from attending, lets discuss the end-game:  Victory.  Having competed in 5 hackathons, with 4 final four finishes, and 3 wins, here's a few things I've learned.

 

1 - Think big, then think bigger

Almost every hackathon win starts with a *much* smaller idea revolving around a feature.  Your job is to think of progressively bigger consequences and applications to the feature.

  • "Hey, wouldn't it be cool if people could vote on projects?" turned into a complete rebuild of Kickstarter in ServiceNow, complete with skill / cash donations, and buzz aggregation.  We challenged the way an enterprise could propose AND decide AND fund AND staff their projects.
  • "Can we integrate with twitter" turned into a social media asset management system, with campaign automation.

 

Forcing yourself to think bigger and bigger will ensure a few things

  • your solution is framed inside a problem that people can feel
  • you expand your own horizons on the platform capability
  • you produce more angles to tell your story
  • you aren't dismissed as a "cute" feature that doesn't really do anything

 

2 - Story telling and development are equally important

None of it matters unless you can develop it.  But even if you develop it, you need someone to tell its story.  Lets not kid ourselves about human decision making.  For the most part the feelings rule, and the mind compensates.  Whatever it is you develop, your audience has to *feel* it.  In many ways this is a hack all on its own.  How do I maximize the *emotional* impact of whatever it is I'm doing.

 

Look, at K13 there were *far* more impressive technical feats than what we won with.  Turning ServiceNow into a blackjack game?  Biometric scanning integration?  FAR harder to pull off.  The only reason we won is we capitalized on the cold patronage of the modern corporation.  "Hey, isn't it bullsh!t that so few people influence what projects are actually done at a company?"  "You're right!  That *IS* BS!".  They were bought into our story before they even saw the product.

 

Another example?  At K15 our team didn't even finish, and I STILL have red hand prints on my back from the kudos we received.  It wasn't our product, it was the story we were (attempting) to tell.

 

3 - It *only* has to work

This was my hardest lesson over 5 hackathons.  Your application will *not* be used.  In only a matter of hours, it will cease to exist.  The care we take in our daily lives is to ensure the tool works reliably for the longest duration possible.  You, my readers and only friends, have a one-way trip to a single point in time (the pitch).  Cleanliness doesn't count.  There is no such thing as "proper".  "Done" is only measured by "did it work at the pitch".

 

Remove all safety measures.

 

(Practical and specific pro tip:  Don't put your app in a scope for hackathon, unless you're specifically hacking app scopes)

 

4 - Know your storyteller ahead of time

Not every one has their story made up before they get to Hackathon.  Statistically, 75% of all participants will be building someone else's idea.  It *is* advantageous to know who the story alpha is before you get to Hackathon.  You're not supposed to pre-develop or migrate code into the Hackathon, and I thoroughly agree with that.  But if you can deconstruct and plan the work ahead of time, you'll save yourself some churning guts.

Each year I hear the same story.

"I'd do the hackathon, but I'm not skilled enough"

"I'd do the hackathon, but I'm not a hacker"

"I'd do the hackathon, but I don't have a team already"

"I'd do the hackathon, but I don't have a cool idea"

 

As a three time Hackathon winner (K13, FruDevcon13, FruDevCon14), I'm here to tell you - forget your limitations, and hack.

 

HACKATHON REQUIRES ALL TYPES

In the 5 Hackathons I've attended, I've seen several roles emerge on hackathon teams.  Keep in mind, its not necessarily a 1-to-1 relationship between role and person

 

The Source - Because someone has to have the idea in the first place.  No hackathon team will win without the source.  You don't have to be a top tier developer to be the source, you just need that unscratched itch in your mind that "it would be way better if...."

 

The Power Dev - Don't have a winning idea, but you can code like blazes?  Its no secret, the winning hackathon entries almost always have *at least one* preposterously difficult technical barrier. 

 

The Auxiliary Developer - So if you're thinking big (which you should be to win the hackathon), you have a large solution to build.  Most of my hackathon success has emerged from weaving our narrative into the widest scope of the platform as possible.  That means while your Power Dev is solving some major technical hurdle there's still *plenty* of good old fashioned hard work to do.

 

The Story Teller - The story teller serves two purposes.  First, as an analog to the Source (if no the same person), and second as the spokesperson for the app.  Make no mistake, story tellers win hackathons.  None of my winning hackathon entries had jaw-dropping tech.  But they *did* have a problem the audience could *feel* and a solution that wrapped up the story in their minds.  You can do very little else in a hackathon (even though anyone can do auxiliary dev) and still be a critical part to the hack team.

 

The Task Master - You're kidding yourself if you think an 8 hour job with 4 people doesn't need a little bit of management.  I've found this to be one of the more difficult people components of the 5 hackathons I've been in.  Often times you won't "hit your stride" until 4 hours in.  If you're a natural at breaking down a job (quickly), ordering the tasks, and applying them to the right skill, you need to fill the task master role. 

 

BUT I DON'T HAVE A TEAM

In the *unlikely* event that you can't find a team before the Hackathon, just show up.  At every event I've competed at there's been plenty of people in the same position.  If I'm not mistaken, the victorious K15 team (or at least one of the finalists) was assembled on the spot, just before the Hackathon began.

 

 

 

The Hackathon is an invaluable for skill sharpening, networking, and broadening your understanding of platform possibilities.  If ServiceNow is your profession, you owe it to yourself to compete. 

 

Join me at the K16 Hackathon this year.  If you need help with teams, ideas, or suggestions as to which role you can fit, I am ever at your service.

ACL's have the perception of being hard because they aren't easy to see in action, and have several layers of interactivity.  This blog won't make you a master, but it should ramp up your troubleshooting competency in a hurry.  Before reading you should...

 

Understand how to impersonate users

Understand ACL basics

 

So you're minding your own business, impersonating a user for a new feature you're building when...

SecurityConstraints.png

or...

FieldSecurity.png

 

STEP 1 - TWO BROWSERS / TWO MODES

I usually have two Chrome browsers open, with one in Incognito mode, but you could easily do one FireFox / one Chrome.  The idea here is to allow two different sessions so one browser can simulate the problem, and the other can be used as admin.  We'll call these Debug Browser and Admin Browser respectively.

 

First, as an admin on the Debug Browser, turn on Debug Security.  You'll know its on when it gives you the following message

DebugSecurity.pngDebugSecurityConf.png

Then impersonate the user experiencing security issues on the Debug Browser

 

 

STEP 2 - EXPERIENCE THE ISSUE

Get to the same spot you were previously experiencing issues.  You should now see a TON of new information at the bottom of your screen.  For this post, as beginners, we're only interested in a small portion of it.

 

DebugSecurity-Info.png

 

 

STEP 3 - MOUSE OVER ICONS TO DISCOVER FAILURE POINTS

Lets look at just one of the entries:

DebugSecurity-Entry.png

This tells us three things immediately

  • Which record (context) was evaluating via the hyperlink on the first line
  • That it was evaluating a record ACL on the Problem table for the Read operation.
  • That there were two possible read ACLs, but both failed.

 

But we can learn so much more!  Hover over the icons beside each of the ACL evaluations and it tells you *how* it failed.  Lets hover over the icons on the second ACL that evaluated...

 

Here we're being told the ACL was expecting the user to have no roles.  Our logged in user has no roles, so that part of the ACL was a success!

2DebugSecurity-Hover1.png

The next icon tells us that there was a condition on the ACL.  Whatever it was, we passed.  Success!

2DebugSecurity-Hover2.png

But the third icon tells us the ACL had a script condition, which resulted in false, which caused the ACL to fail.

2DebugSecurity-Hover3.png

 

In table ACLs, all we need is one full ACL success to get the rights, but in this case both ACLs failed, which means the whole record evaluation failed.

 


STEP 4 - INVESTIGATE THE ACLs SPECIFICALLY

Notice anything interesting about the text after the icons that tell us the failure points?  They look like hyperlinks... because they are.

Unfortunately they're useless hyperlinks at this point because we're impersonating a user experiencing an ACL issue.  That user is likely NOT a security admin.  But by Crom, we're going to find out why these two ACLs failed

 

This is why we need two browsers.  First, copy one of the link addresses...

CopyLinkAddress.png

... then paste it into your Admin Browser.  Presto... the *exact* ACL that failed.

ACL.png

 

Having the two browsers open (one in Incognito mode) will allow you to both experience and research the issue simultaneously in real time.  Without this method, you could spend hours bouncing back and forth between users and screens.

 

Hope that was of some value to you.  With all the time you're going to save, why not drop a bookmark or a like.

 

Oh, and remember to disable your security debugging too.

Disable.png

THE PROBLEM WITH OOB CAPABILITIES

Those of you who've had rigorous testing protocols on ServiceNow know that there's a critical weakness with notification handling on non-production systems.  You have only three options:

  1. Disable all notifications - "Great, now I can't test notifications at all!" 
  2. Enable all notifications - "Great, now my customers get notifications they neither want nor expect"  x2
  3. Send all notifications to specified email addresses -  "Great, now my testers have to separate signal from noise"

 

There must be a better way.

 

SOLUTION:  FILTER INTENDED RECIPIENTS

We need a solution that provides the following

  • Req1 - authorize whole groups to receive notifications on non-prod
  • Req2 - authorize single users to receive notifications on non-prod
  • Req3 - exists on all instances, but only works on non-prod instances

 

We'll provide this solution with one dictionary entry and one before-insert business rule.

 

First, we build a true/false field named u_subprodemail on the Group table only.  You might look at Req2 and say "don't we need this on User table too"?  Nope!  We're solving two use cases here.  First is flagging whole groups that want to receive notifications.  For individuals, we'll simply create a new group (with u_subprodemail = true) that we can put those 'one of' users in.

 

Now we create a Before Insert business rule on the Sys_Email table.  We're going to intercept outbound email and bend it to our will!

NAME:  Control Sub-Prod Email

CONDITION

gs.getProperty('glide.servlet.uri') != "https://<yourinstancename>.service-now.com" && current.type != "received"

 

SCRIPT:

function onBefore(current, previous) {
  var validSends = [];
  var ga = new GlideAggregate('sys_user_grmember');
  ga.addQuery('group.u_subprod_email',true);
  ga.groupBy('user');
  ga.query();
  while (ga.next()){
    if (current.recipients.indexOf(ga.user.email.toString()) >= 0){
      validSends.push(ga.user.email.toString());
    }
  }
  current.recipients = validSends.toString();
  current.body = "SENT FROM NON-PRODUCTION SYSTEM \n\n" + current.body;
  gs.log(gs.getProperty('glide.servlet.uri') + " " + validSends, 'Sub-Prod Notifications');
}

 

SCRIPT EXPLAINED

  • We declare validSends variable as a blank array.
  • We query the sys_user_grmember table finding all group members for groups that have the u_subprod_email set to true.
  • We’re using GlideAggregate and GroupBy so that multiple memberships with the same User are represented only once.
  • For each result we compare the group member’s email against the list of recipients targeted for the sys_email insert.
  • If there’s a match, we push the value to the validSends array.
  • After we’ve tested all validated addresses, we overwrite current.recipients with validSends.
  • We also add text to the top of the email body to reinforce it was sent from a non-prod system.
  • REMEMBER:  Because we're checking *group memberships* to groups that have been flagged as enabled, you may have users part of multiple groups, only one which is email enabled.  A user only needs one "enabled" membership to receive all email targeted at them.

 

CONGRATULATIONS!

  • You can include notifications as a component of your UAT. 
  • You can precision control the groups and users to receive those notifications.
  • You can push this customization to prod so you don't have to rebuild it after every clone-back.

Filter Blog

By date: By tag: