Fun with Webhooks, Part II

“Well done is better than well said.”
Benjamin Franklin

Now that we have the idea fairly well formulated, it’s time to get to work. The first thing that we need to do is create our Scoped Application, which you can do by navigating to My Company Applications and then clicking on the Create new button in the upper right-hand corner. I still use the classic UI rather than the Studio, so you may approach this task a little differently, but the end result should be the same.

New Simple Webhook Application

At this point, I have just created the most basic of empty shells. There are no modules or tables or roles or any other artifacts … it’s basically just the bare application record itself. Creating the app does create a scope, and also puts you into that scope, so as long as you don’t change that, everything that you do from this point on will be built in that scope. The first thing that we will want to build is the database table for our registry, which we can do by navigating to System Definition -> Tables and clicking on the New button.

New Webhook Registry table

Once you give it a Label it will generate the appropriate name, and the next thing that you are going to want to do is to uncheck the Create module option, as we only want the table at this point and we don’t need all of those other artifacts generated. We want to give our registrations an ID using the platform’s built-in tools, so we will want to create a field labeled Number of type String and put the following in the Default value:

javascript:getNextObjNumberPadded();

We have a number of other columns to define, but let’s save this for now and go set up our auto-numbering before we forget. To do that, navigate to System Definition -> Number Maintenance and click on the New button. Select our new table from the list and then let’s set the Prefix to WHR for Webhook Registry,

Setting up auto-numbering for our new Webhook Registry table

With that out of the way, we can go back to our table and add the rest of the fields. Here are the ones that I added to get things started:

  • Active – True/False, with default of True
  • Table – Table Name, with default of incident
  • Owner – Reference to the sys_user table
  • Type – String, with four initial choices (Single Item, Caller / Requester, Assignment Group, and Assignee)
  • URL – URL
  • Authentication – String, with two initial choices (None and Basic)
  • User Name – String
  • Password – Password
  • Document ID – Document ID
  • Person – Reference to the sys_user table
  • Group – Reference to the sys_user_group table

We may add a few more later on as we add new features, but this will get us by for now. Event though my intent is to focus solely on the Incident table for now, I went ahead and added the Table column and just defaulted it to Incident. That was mainly so that I could use as the Dependent field on the Document ID field. If you have never worked with Document ID fields before, you can just think of them as a special form of Reference field where you don’t have to specify the table that is being referenced. Instead, you point to another field on the record that contains the name of the table. This way, one of your records can reference one table and another record in that same table can reference a different table, all based on the table specified in the Dependent field. To set up the Dependent field, use the Dependent Field tab on the Dictionary Entry for the Document ID field.

Document ID Dependent field specification

After entering all of the fields, I used the Show form link at the bottom of the page to bring up the form for the new table. Using the Configure -> Form Layout option, I rearranged the fields on the screen to my liking, and then removed the Table field completely, as that will default to Incident for now and we don’t want anyone changing it to anything else at this point.

After getting everything laid out just right, the next thing that I did was to add a few UI Policies to control certain fields based on the value in other fields. For example, I hide the User Name and Password fields unless you set the Authentication to Basic. Similarly, the presence of the Document ID, Group, and Person fields are all dependent on the value of the Type field. Basically, this just hides fields that are not needed and reveals them when they are.

The other things that I wanted to do on this form was to give the user the ability to test their URL. That seemed like a good use for a new UI Action, but rather than putting all of the code for that process in the Action itself, I decided to start a Script Include to house these types of utilitarian functions. Putting all of that together seems like a good exercise for our next installment in this series, so this looks like a good stopping point for now.

Reference Type System Properties

“To succeed in life, you need two things: ignorance and confidence.”
— Mark Twain

Whenever I create a ServiceNow application, I invariably end up setting up one or more System Properties to control the behavior of the app, set up options for the app, or allow the app to function differently in different environments such as Test or Production. Recently, I wanted to create a property that would be selected from a table, or in ServiceNow terms, a Reference property. Unfortunately, when I scanned the list of available property types, Reference was not on the list.

Available System Property Types

Well, not to worry. Choice Lists are easily modified, so I went to sys_properties.list, then Configure -> Table, and clicked on the Type column to bring up the Dictionary Entry. From there, I clicked on the Choices (13) tab and then clicked on the New button to create a new choice. I typed the word reference into both the Label and Value fields and then clicked on the Submit button to save the new choice. Voila! Now my instance supports System Properties of Type Reference:

New Reference Type added to the Choice List

Of course, that was the easy part … there’s still much to do. First of all, we are going to need to add another field so that we can capture the Table we will be using for the Reference. And now that I am looking at that form, there are a couple of things that are irritating my sense of The Way Things Ought To Be that I am just going to have to clean up while I’m in there. For one, the need for the Choices field is dependent on the value of the Type field, so the Type field should come first. Additionally, the Choices field shouldn’t even appear on the form if the Type is not Choice List. The new Table field, which itself should be a Reference to the Table table, should only appear if the Type is Reference. If the Type is not Choice List and the Type is not Reference, then the very next field should be Value. Let’s see if we can’t clean all of that up next.

To begin, we can add the new column to the sys_properties table right from the form itself using the hamburger menu:

Updating the Table from the Form

This will take us to the list of columns where we can click on the New button to create a new column on the table. Select Reference as the Type, enter Table as the Label and then go down to the Reference Specification tab and select Table as the Reference.

New Table Column

Saving the new column will return us to the Table specification, and clicking on the return (<) icon up in the left corner will get us back to the form where we can use the hamburger menu to select Configure -> Form Layout to move things around. Doesn’t that look better!

Rearranged System Property fields

Now, with a little UI Policy magic, we can hide both the original Choices and the new Table unless the appropriate Type has been selected. Back again to the hamburger menu where we can select Configure -> UI Policies to implement the desired changes. We’ll need to add two new policies, one for the Choices field and one for the Table field. You first have to create the policies and save them, then you can go back in and add the actions to take when the conditions are met. The condition on the first will be Type = choice list and the condition on the second will be Type = reference. Be sure the check the Reverse if false option, as we will want these policies to toggle between the true and false conditions.

Once the policies have been created, you can go back in and add the appropriate action. On the Type = choice list policy, the action will be to make the field Choices visible. On the Type = reference policy, the action will be to make the new field Table visible. Because you selected the Reverse if false option on both policies, when the the Type is not set to the specified value, the result will be that the relevant field will no longer be present on the screen.

System Property form with neither Choice List nor Reference selected

There are still a couple of more things that we could do here to make this complete, but at this point I don’t really have a pressing need for either, so I am just going to let those go for now. The first would be a potential filter for the reference fields, as there are occasions where you don’t want the user choosing from the entire contents of the table. That would basically be handled like the Table field itself, appearing on the form only when reference was selected as the Type.

The other thing that could be done at this point would be to alter the Value field to behave in accordance with the selected Type. This would seen like the appropriate thing to do, but out of the box, the open text input box does not transition to a selection of choices when you select choice list as the Type. I think the main reason that it doesn’t do that is because this is not really the place where property values are set. Properties are defined on this form, but there is another form that is generally used to set the value. We’ll tackle that form next time, as that work will be a job in and of itself.