Giter VIP home page Giter VIP logo

jace.pro's People

Contributors

dependabot[bot] avatar dorsy99 avatar jacebenson avatar johncaruso avatar patmyron avatar pulliam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

jace.pro's Issues

Move to algolia search from google search

Is your feature request related to a problem? Please describe.
I want the search to not have ads.

Describe the solution you'd like
Implement Algolia Search

Describe alternatives you've considered
No change or remove search.

Post Request: Cancelling workflows

What is the post about?
Cancelling Workflows
What things would help with writing the post

Something almost always asked for and rarely delivered is the ability to cancel a requested item. I’ll try to explain why this is so difficult and how I’ve suggested implementing this.

Why is this difficult? The problem is not with the actual canceling the requested item. It’s because asking groups to undo what they did is not a simple statement.

Take for example the following workflow. There’s an approval and two tasks.

graph LR
Begin --> Approval
Approval --> Create AD account
Create AD account --> Create email
Create email --> End

Say this item gets cancelled before “Create email” is complete. Do we assume someone needs to check if the email was created but not activated, or just make a task to remove the AD account. Do we need to inform the approval chain?

This is a pretty simple example, but should show some of the issues with trying to cancel an item. I’m of the opinion that I think there are two ways to broadly address this, and one way to specifically address it.

  • For each task updated (sys_mod_count>0) create a task to undo work done in task #.
  • Create a task to the group to undo all work done from this ritm#.
  • For specific have a path in your workflow waiting for the cancel and depending where the workflow is, create appropriate tasks to cancel this item completely.

The first option will require less involvement from each group to set up, but may find some tasks don’t make sense. Imagine you have a request to make a doctors account in Epic. Sometimes the folks who make the account don’t give the roles. So if you had two tasks one to create the account and another to give the roles. If the group who made the account got a task to “undo” the account, the roles couldn’t be removed.

The second option requires you to identify a single group who is primary owner for the group (which has other great benefits but I’m not going to go into those now). That has some office politics attached and more often then not if this is done I’ll bet a number of non service now items are owners of automated or complex items.

The third option would only work for items where the cancelling was thought through at the time the item was sized or after a conversation came up to clear up questions. Where this is different from the first option is this will create very specific tasks per the workflow. The first option would always make “undo” tasks.

Project to make activity formatter

What is the post about?

Project to make activity formatter

What things would help with writing the post

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
	<g:evaluate>
		var documentId = RP.getParameterValue('sys_id');// would return url r= value
		var referringURL = RP.getReferringURL();
		var table = referringURL.split('.')[0];
		var sys_journal_field = new GlideRecord('sys_journal_field');
		sys_journal_field.addQuery('element_id', documentId);
		sys_journal_field.orderByDesc('sys_created_on');
		sys_journal_field.query();
		var entries = [];
		while(sys_journal_field.next()){
		    entries.push({
		        value: sys_journal_field.getValue('value'),
		        element: sys_journal_field.getValue('element'),
		        elementDisplay: sys_journal_field.element.getDisplayValue(),
		        createdOn: sys_journal_field.sys_created_on.getDisplayValue(),
		        createdBy: sys_journal_field.getValue('sys_created_by'),
		        createdByDisplay: (function(){
		          var sys_user = new GlideRecord('sys_user');
		          sys_user.addQuery('user_name', sys_journal_field.getValue('sys_created_by'));
		          sys_user.query();
		          if(sys_user.next()){
		            return sys_user.getDisplayValue();
		          } else {
		            return 'unknown';
		          }
		        })()
		    });
		}
		var x = 0;
	</g:evaluate>
	<p>${documentId}</p>
	<p>${referringURL}</p>
	${entries.length}
	<j:while test="${parseInt(x,10)!=parseInt(entries.length,10)}">
		
		<blockquote class="blockquote">
		  <p class="mb-0">${entries[x].value}</p>
			<footer class="blockquote-footer">${entries[x].createdByDisplay} (
				<cite title="Source Title">${entries[x].createdOn}</cite>
				)
		  </footer>
		</blockquote>
		<g:evaluate>
		  x = x + 1;
		</g:evaluate>
	</j:while>
</j:jelly>

image

Making the community more useable

What is the post about?

What things would help with writing the post

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://community.servicenow.com/*
// @grant        none
// ==/UserScript==
/* global $ */
(function() {
    'use strict';
    var checkExist = setInterval(function() {
        if ($('sp-page-row').length) {
            console.log("Exists!");
            $($('sp-page-row > .row >.col-md-9')[0]).attr('class','col-md-12');
            $($('sp-page-row > .row >.col-md-3')[0]).attr('class','hide');
            clearInterval(checkExist);
        }
    }, 100); // check every 100ms
})($);

Calculating Date Time based on user's TZ and Schedule's TZ

What is the post about?
Calculating Date Time based on user's TZ and Schedule's TZ

What things would help with writing the post
Prayer.

Script include

var maintenanceWindowUtil = Class.create();
maintenanceWindowUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
  getDateThings: function (startDateStr, endDateStr) {
    try {
      var rObj = {};
      var start_unformatted_date = startDateStr.split('T')[0];
      var start_formatted_date = [start_unformatted_date.substring(0, 4), start_unformatted_date.substring(4, 6), start_unformatted_date.substring(6, 8)].join('-');
      var start_unformatted_time = startDateStr.split('T')[1];
      var start_formatted_time = [start_unformatted_time.substring(0, 2), start_unformatted_time.substring(2, 4), '00'].join(':');
      var end_unformatted_date = endDateStr.split('T')[0];
      var end_formatted_date = [end_unformatted_date.substring(0, 4), end_unformatted_date.substring(4, 6), end_unformatted_date.substring(6, 8)].join('-');
      var end_unformatted_time = endDateStr.split('T')[1];
      var end_formatted_time = [end_unformatted_time.substring(0, 2), end_unformatted_time.substring(2, 4), '00'].join(':');
      rObj.formatted = {
        start_date: start_formatted_date,
        start_time: start_formatted_time,
        end_date: end_formatted_date,
        end_time: end_formatted_time
      };
      rObj.start = start_formatted_time;
      rObj.start_date_time = [start_formatted_date, start_formatted_time].join(' ');
      rObj.end_date_time = [end_formatted_date, end_formatted_time].join(' ');
      rObj.start_gdt = new GlideDateTime(rObj.start_date_time);
      rObj.end_gdt = new GlideDateTime(rObj.end_date_time);
      rObj.durationMS = rObj.end_gdt.getNumericValue() - rObj.start_gdt.getNumericValue();
      return rObj;
    } catch (e) {
      rObj.error = e;
      return rObj;
    }
  },
  getNextWindow: function () {
    try {
      var iObj = JSON.parse(this.getParameter('sysparm_obj'));
      var rObj = {
        from: "server",
        input: iObj,
        output: {}
      };
      var now = new GlideDateTime();
      if(iObj.startDate != ""){
        iObj.start_date_gdt = new GlideDateTime();
        iObj.start_date_gdt.setDisplayValue(iObj.startDate);
      } else {
        iObj.start_date_gdt = new GlideDateTime().addDaysUTC(3);
      }
      if(iObj.endDate != ""){
        iObj.end_date_gdt = new GlideDateTime();
        iObj.end_date_gdt.setDisplayValue(iObj.endDate);
      } else {
        iObj.end_date_gdt = new GlideDateTime().addDaysUTC(3);
      }
      rObj.output.schedule = {};
      rObj.output.span = {};
      rObj.output.user = {};
      var user = new GlideRecord('sys_user');
      if (user.get(gs.getUserID())) {
        rObj.output.user.tz = user.getValue('time_zone') || gs.getProperty('glide.sys.default.tz');
      }
      // get the selected schedule
      var schedule = new GlideRecord('cmn_schedule_maintenance');
      schedule.addQuery('sys_id', iObj.maintenance_window);
      schedule.query();
      if (schedule.next()) {
        rObj.output.schedule.time_zone = schedule.getValue('time_zone') || gs.getProperty('glide.sys.default.tz');
        // get the first span
        var span = new GlideRecord('cmn_schedule_span');
        span.addQuery('schedule', iObj.maintenance_window);
        span.query();
        if (span.next()) {
          // return the span (if theres more than one span we will have issues)
          rObj.output.span = this.getDateThings(span.getValue('start_date_time'), span.getValue('end_date_time'));
        }
      }
      var nowStr = iObj.start_date_gdt.toString().split(' ')[0] + ' ' + rObj.output.span.start;
      var nextSpan = new GlideDateTime();//the GDT for the next span on the maintenance window
      nextSpan.setValue(nowStr);//set this to date given or 3 days from now and at the hour of the span
      nextSpan.addSeconds(nextSpan.getDSTOffset() * -1);//add/subtract time for DST Offset
      while (nextSpan.getNumericValue() < now.getNumericValue()) {//if nextspan is in the past, move it up a day
        nextSpan.addDaysUTC(1);
      }
      var glideSchedule = new GlideSchedule(iObj.maintenance_window, rObj.output.schedule.time_zone);
      var ms = glideSchedule.whenNext(nextSpan);//the milleseconds until the next span
      if (ms === -1) {//if the ms is -1, there is no next span
        rObj.whenNext.error = "Schedule never has a 'whenNext'";
      } else {
        nextSpan.addSeconds(glideSchedule.whenNext(nextSpan) / 1000);//move nextspan to the beg of next span
        rObj.start_date = nextSpan.getDisplayValue();//returns beg next span in user format
        nextSpan.addSeconds(rObj.output.span.durationMS / 1000);//move nextspan to the end of next span
        rObj.end_date = nextSpan.getDisplayValue();//returns end next span in user format
        nextSpan.setTZ(Packages.java.util.TimeZone.getTimeZone(rObj.output.user.tz));
        rObj.output.user.DSTOffset = nextSpan.getDSTOffset();
        rObj.output.user.isDST = nextSpan.isDST();
      }
    return JSON.stringify(rObj);
  } catch(e) {
    rObj.error = e;
    return JSON.stringify(rObj);
  }
},
  type: 'maintenanceWindowUtil'
});

Client Script

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
	if (isLoading || newValue === '') {
		return;
	}
	var ga = new GlideAjax('global.maintenanceWindowUtil');
	ga.addParam('sysparm_name', 'getNextWindow');
	ga.addParam('sysparm_obj', JSON.stringify({
		"start_date":g_form.getValue('start_date'),
		"end_date": g_form.getValue('end_date'),
		"maintenance_window": newValue
	}));
	ga.getXML(function(response){
		var responseDocument = response.responseXML.documentElement;
		var answer = responseDocument.getAttribute('answer');
		var serverObj = JSON.parse(answer);
		console.log(serverObj);
		g_form.setValue('start_date',serverObj.start_date);
		g_form.setValue('end_date',serverObj.end_date);
		
	});
}

This assumes you make a field on Change called u_maintenance_window that is a reference to cmn_schedule_maintenance

Post Request: DB Views and measuring the lack of something

What is the post about?
DB Views and measuring the lack of something

What things would help with writing the post

So DB views, ive realised achieve alot
they have their flaws
but.. they are pretty powerful
but ive been at work and thought "Dam yeah, cant do that with reports...." so many times.
My mind has blanked, ill try recall a use case
Yeah, like finding the inverse of querys is cool
like, "How many KBs havent been viewed?"
"What user doesnt have an asset?"
i mean, choosing what table you put "left join = true" on still baffles me. Its like the inverse of what i'd expect
reporting on the absence of things is tough, and yea db views help solve that.

Post Request: When to Scope

What is the post about?
When to Scope
What things would help with writing the post

Service-now's Stance

According to the community;

When should you build an app under global scope versus private application scope?

There are two use cases when considering application scope: extending an existing app or creating a custom app from scratch. If you are extending or modifying an existing global scope application and the changes are having a high impact on other applications, then leave the change in the global scope. However, if the changes are going to have less impact to other applications, then the modifications can be done as a scoped app.

When you are creating a new application from scratch, you should be creating it as a scoped app. ServiceNow’s product strategy is to develop more and more scoped apps to make it easier for customers to deploy the application and to simplify future upgrades. Also, backing out changes to scoped apps is much simpler and can be done with a single push of a button.

Thoughts

Generally it looks like Servicenow has broken up things in the scoped applications by function or business unit, e.g.

  • Guided Setup
  • Knowledge Management - Service Portal
  • Service Portal Surveys
  • Human Resources

That's the precident Servicenow has set.

The pro's and cons of by function and business unit are such

Business Unit

Pro Con
Easy to tell what needs to be updated based on the ask Hard to expand to othre area's if some functionality needs to be shared.
Having --

Notes

Our dev team is a little gun-shy when it comes to scoped apps. Do you have a written policy about what goes in a new scoped app?
e.g. Our team is concerned about a future state where our drop-down of scoped apps is 200-items long. (edited)
I'm looking for a decision matrix of when to go scope, when to stay global.
Like if you're extending incident, stay Global because it's already in global. - Jarod M

taht line i think is everyones question
sn's done it at a business unit with HR
I'd follow suit w/ SN where you make an app per unit, if all units are going to use said table add it to some core app - Jace

We're leaning towards our IT solution hierarchy. if it's a separate product, then it's separated in the CMDB.
that's our current draft policy - Jarod M

im so confused - jace

We have SN as a Business Service.
We also have SN-Incident as a Business Service that is a module of the root SN. This has separate ownership, etc...
so if we're going to track something as a new product (e.g. "Advanced Reporting App") as a Business Service (in the CMDB), we will make it a new scoped app. (edited)
That, or if there's a security/performance concern, it can be in a scope.
That's our draft policy. I was curious how other teams decide when to put enhancement (new functionality) requests in scope - Jarod M

right but, where is the line drawn, is an application considered just a form on the catalog, or a net new table? what if the catalog item needs data from a net new table? - Jace

Me and @Rolf were talking about the other side of this issue too, When to use great discussion to have but then a few of us have made them and still struggling on how to maintain . clone ect. So maybe these questions would be a great addition to the TechNow were were hoping for over in #lchh - kcimpulse

i guess if you looking for how others are doing it. we have no process around it. we have a "marketing" app scope, and some weirdly named other unit scope - jace

https://community.servicenow.com/docs/DOC-7746
When should you build an app under global scope versus private application scope?
There are two use cases when considering application scope: extending an existing app or creating a custom app from scratch. If you are extending or modifying an existing global scope application and the changes are having a high impact on other applications, then leave the change in the global scope. However, if the changes are going to have less impact to other applications, then the modifications can be done as a scoped app.
When you are creating a new application from scratch, you should be creating it as a scoped app. ServiceNow's product strategy is to develop more and more scoped apps to make it easier for customers to deploy the application and to simplify future upgrades. Also, backing out changes to scoped apps is much simpler and can be done with a single push of a button. - Jarod M

We are using them pretty liberally here. When we upgraded to Istanbul earlier this year we decided to prioritize developing in scoped apps. Our main motivation was to make the upgrade process smoother (less conflicts on upgrade!) - rolf

Do you have a naming convention (so they are sorted in the dropdown)? - Jarod M

Only for Scoped Apps in which we're creating a Service Catalog Category, where we preface it with an SC
other than that it's just search, but we only have around 35 apps right now so it's not a huge deal - rolf

We are doing the Abvr for the team name - Because the OCD in me hates the scope being in the same long table name as the name of the table. Like We made an Investment application. So I might have made it INV but didnt want the table name being INV_Investment (edited) - kcimpulse

Even with 200 apps though I don't think we'd be running into any naming conflicts. The list is sorted by creation date so most of the time the stuff you want to work on is on top
While there's definitely some confusing aspects at first with scoped app dev, it's been worth it for our team to make the switch to primarily working out of global. Making a large scale application while knowing that you can always uninstall and be back to PDI functionality is really nice. I think it'll help us as we scale... right now we are a small team of 4 (3 devs and a manager). - rolf

Great video@chrismaloy very appreciated and good timing on a few discussions we have been having - https://www.youtube.com/watch?v=DLqkDxGVLbE - kcimpulse

Thanks @kcimpulse! The video is a little old but still relevant. Thank you for the shout out. - chrismaloy

What is "Application Scoping"?

  • I don't like the name "Application Scoping". It's more like a workspace.
  • It's a way of collecting application files together that do a specific a function.
  • That function may be a full blow app e.g. invoice management
  • That also may be minor additive changes to out of box apps or integrations, or utility apps not even needing a data model (e.g. tables)

What does the the Scoped Application Model do for me?

  • Design and Runtime Protection
  • Universally enforced namespace
  • Contextual Development
  • Runtime Application Separation
  • Installation and Un-installation
  • Public and Private API definitions
  • Table level data access controls
  • Dependency Tracking
  • Delegated Development

Easy Migration Tools to move things from Global.

  • New Changes

Promoting code all the ways to do it

Post Request: Implementing chargebacks

What is the post about?
Implementing chargebacks

What things would help with writing the post

Implementing Chargebacks

Start with speaking

Talk in terms that you're providing these forms, and customizations at your business's cost but talk about things in a way to be clear, there is a cost.

E.g.

We will customize that form, it will take ~ x points or ~ x hours.
Today we don't charge other units for this work.
In time these requests will need to provide a return of investment greator than the cost of development

Start with showback

Once you start talking that way, determine what the cost actually is.
Identify Rate of pay per hour or per point based on average of staff or some arbitrary number

Use estimated points/hours to show estimated cost, use actual points/hours to actual cost.

Continue to provide work even if it's at a loss during this time.

Implement Chargeback

Now that this work has been shown to have cost and what a return on investment would be.
Start using that data.

Best Practices: Integrations - Using Import Sets

What is the post about?
How to use Import sets for both Inbound Integrations, and Integrations where you get data and write it back to Sn.

What things would help with writing the post

Activate plugins by script

What is the post about?
Activating plugins via script

What things would help with writing the post

//Partial Version
//you can check following URL to see if the work is finished. It is finished when the completion time is set and the percent complete is 100.
//<instance>/sys_execution_tracker_list.do?sysparm_query=name%3DPlugin%20Installer
var plugins = [];
plugins.push('com.snc.pa.change');
plugins.push('com.snc.pa.problem');
plugins.push('com.snc.pa.premium');
plugins.push('com.snc.pa.solution.library');
var main = new GlideMultiPluginManagerWorker();
main.setPluginIds(plugins);
main.setProgressName("Plugin Installer");
main.setBackground(true);
main.start();

Source: https://community.servicenow.com/community?id=community_question&sys_id=e6db5e4bdb47ab002e8c2183ca9619a2

Post Request: Email Examples

What is the post about?
Email Examples

What things would help with writing the post

Survey 1

Subject: ServiceNow Customer Satification Survey for [RECORD]

We would like to thank you again for being our customer.

Customer satisfaction is our priority, and we hope the solution to incident [RECORD] has met your expectations.

Please grade our performance by clicking the link below to complete a short survey. Every survey is acted upon and your input is vital.

Customer Satisfaction Survey

Thank you for your input.

[Person's name]
[Role, Department]
[Company]

Resolved by: [Resolvers Name]
Short description: [Short Description]

Survey 2

Subject: Survey invitation: New Survey on Customer Satisfaction Survey

You have been invited to take the survey: Customer Satisfaction Survey.

Click here to take your survey:
[Link to survey]

Unsubscribe | Notification Preferences

Record Commented

Subject: [Priority] Record Class Commented - [Company] - [Record]: [Short Description]

[Record Updated]
[Priority] Record Class: [Record]

Hi
Record Class [Record] has been updated.

Priority:
[Priority]
Short Description:
[Short Description]
Comments

[Comments]
Steps to reproduce:
[Steps to reproduce]
Business Cricality: [Imact]
Affected Users: [Quantity of users]
Start Date: [Start Date]
End Date: [End Date]

Click here to view Record Class [Record]

Sincerely,
ServiceNow Customer Support

Post Request: Step away from emails a step by step guide

What is the post about?
Step away from emails a step by step guide
What things would help with writing the post

An easy way to start is to have inbound emails use the new call application.

TL; DR Record Producers created specific to your most commonly reported incidents that gather the data needed to resolve those incidents (including optional data based on answers in the RP) can greatly reduce your TTR and cause overall greater customer satisfaction despite the bigger hurdle to incident submission.
careful pushing of folks to these Structured Record Producers can be handled in many ways, including closing incidents submitted improperly and pointing them to the new RP

ajb [< 1 minute ago]
Emails & SP:
Emails created entries cost more, introduce delay for most interactions, initial send is quicker for user to send, slower to help them in general case
Structured data and clear services via SP are a large difference - cuts down on back and forth, aids in automation, helps routing and fulfillment expectations, transparency and prioritization. Better expectations and up front data collection leads to happier users quickly.

Phased Approach is recommended Show incentive to go to no inbound email with Time to resolved Time to resolved is lessened by less categorizing, less back and forth to/from the customer.

Some organizations saw a 25%-75% better resolution time after disallowing email.

Ensure you offer specific services that handle most the calls to allow the faster resolution.

I asked The other day in the sndevs slack channel what do people's companies stopped incoming emails doing;

User Generation: 9
Ticket Generation: 5
Ticket Updates: 4
Approvals: 2
Company lives on email: 3

Emails

Pros Cons
Faster to send the email then fill out the form Email missing required data in structured format
Required data needs to evaluated in the new record

Record producer

Pros Cons

Post Request: Best Practices

What is the post about?
Best Practices

What things would help with writing the post

Best Practces

Source: https://community.servicenow.com/community?id=community_blog&sys_id=6e7d6269dbd0dbc01dcaf3231f9619c0

Behind the scenes here at ServiceNow, the Knowledge Management and Multimedia teams work closely with subject matter experts to dis-seminate critical information to our customers. We've found that certain topics come up frequently, in the form of best practices that can help you keep your ServiceNow instances running smoothly. This series targets those topics so that you and your organization can benefit from our collective expertise. If you have a best practices topic you'd like us to cover in this series, please let us know in the comments below.

ATF (Automated Test Framework)

Best practices for using ATF 9/26/17
How to avoid ATF testing failures 5/30/17

Development

Best practices for using the Flow Designer 2/22/18
Dictionary overrides—what they are and how to use them 7/24/17
When running business rules, timing is everything 7/11/17
Six ways to Improve the Performance of Client Scripts 6/21/17
Properly deploy changes using Team Development 5/23/17
How to keep variables from stepping on each other 3/17/17
User account or service account? What to use for web service tasks 3/10/17
Outsmart fickle networks, firewall changes, and down servers in your web services integration 2/24/17
Why you should never use external iFrames - and the one exception to this rule 2/15/17
How to clone to a target instance that has in-development applications 2/14/17
Why you shouldn't develop on your production instance 1/17/17
Annotate scripts and customizations with comments 12/20/16

HI

Requesting assistance with quarterly patching or version upgrade changes 5/17/17
The high importance of managing your company contacts on HI 5/1/17
Adding new users in HI—the how and the why 4/24/17

HR Service Delivery

The basics of integrating with SuccessFactors and other HR management systems 4/27/18

Information Technology & Business Management (ITBM)

[Agile 101—What is Agile development and why do you need it?](community?id=community_blog&sys_id=e300ac23dbf69bc09d612926ca961977" target="_blank) 6/28/18
PPM 101
What is PPM, and why do you need it? 6/18/18

Information Technology Operations Management (ITOM)

CMDB 101
[](community?id=community_blog&sys_id=e300ac23dbf69bc09d612926ca961977" target="_blank)—
What is a configuration management database, and why do you need one? 4/13/18
ITOM 101
[](community?id=community_blog&sys_id=e300ac23dbf69bc09d612926ca961977" target="_blank)—
What is ITOM and why do I need it? 3/30/18
Tips for implementing and troubleshooting Cloud Management - 3/2/18
Best practices for setting up Discovery schedulesBest practices for setting up Discovery schedules 12/14/17
Best practices for MID Server setup and tuning 11/9/17

Information Technology Services Management (ITSM)

ITSM 101
[](community?id=community_blog&sys_id=e300ac23dbf69bc09d612926ca961977" target="_blank)—
What is ITSM and why do you need it? 6/1/18
Service Catalog in Kingston—podcast and best practices 2/8/18
Best practices for a successful ITSM implementation 1/18/18
Best practices for implementing the Problem Management application 1/11/18
Best practice: Make the most of standard changes 12/18/17
Best practices for implementing the Incident Management application 10/26/17
Best practices for implementing the Change Management application 10/11/17

Platform

Tips for streamlining ServiceNow upgrades - podcast and best practices 3/16/18
Why you should give each of your sub-production instances its own unique look 4/12/17
Set up currency properties correctly 4/6/17
How do you plug in a plugin? The ins and outs of plugin activation 3/3/17
Limit the Number of Users with the Admin Role 1/5/17

Forms

Best practices for creating and editing forms 8/24/17
Choosing the correct field type when building a form 6/9/17

Lists

Best practices for configuring lists 9/11/17
Where to avoid linking to a reference field when configuring a list 1/12/17

Tables

Avoid issues when modifying shared fields in extended tables 3/29/17
When to Create a New Table vs. When to Extend 1/28/17

Reporting and Performance Analytics

Best practices for creating responsive dashboards 12/8/17
Best practices for creating and sharing reports 8/11/17

Security Operations

Vulnerability Response 101
[](community?id=community_blog&sys_id=e300ac23dbf69bc09d612926ca961977" target="_blank)—
Understanding Vulnerability Response with ServiceNow 5/18/18

For more information:

Links to all NOWsupport resources
ServiceNow Customer Success Center

ATF and scopes

if describe is only avaiable in the global scope....how in the world do I unit test in a scoped application?

Post Request: Debugging SP Widgets

What is the post about?
Debugging Service Portal Widgets

What things would help with writing the post

This article sets out a standard set of Service Portal Widget debugging techniques and is intended both for informational and training purposes. For many incidents, an understanding of the "Basic Techniques" section will suffice. For higher priority incidents on heavily customized instances, a firm grasp of the "Advanced Techniques" may be required. The techniques in this article are a compilation of techniques gathered from currently available ServiceNow resources and new techniques which are documented for the first time.

All examples in this article are run on a widget called "Global Objects Demo Widget". To run the examples in the article you will need to see section "Running the Example Tests" at the end of the article to get setup.

Basic Techniques

  1. Logging to the JavaScript console

The console.log() function will log data to the JavaScript console in the browser. This technique will work in the Client Script of the widget and also in the Server Script.

Example

If you look at line 3 and line 16 of the Server Script of the Global Objects Demo Widget, you'll notice that the "input" and "data" objects are logged to the console.

Open the JavaScript console in Chrome developer tools. Refresh the preview pane and you'll notice the following result in the console:

The input object is undefined and the data object is printed to the console.

  1. Using the inbuilt debugger function in Chrome and Firefox

The debugger function can be used in the Client Script of the widget but not the Server Script. Adding the debugger function is like inserting a break point into your code allowing you to step through the code line by line.

Example

In the Client Script of the widget, add the code debugger; at line 23.

Open Chrome Developer Tools. Save the widget and refresh the preview pane. Press the "server.get({collectionName: "presidents"})" button. The JavaScript execution will stop at the word debugger. To see the "response" object contents, hover your mouse over the word "response" in line 14 of the code in devtools.

To step into the next line in the code use the down arrow button. To allow the JavaScript execution to proceed without stopping, press the "Resume script execution" button.

  1. Log the widget's "scope" object to the console

Hold down the control key and right-click on the widget. Choose "Log to console: $scope.data" or "Log to console: $scope". The only difference is whether you want to log the entire scope object to the console or only the data property of the scope object.

Example

Navigate the to the following URL: https://.service-now.com/sp?id=demo_widget_example

Hold down the control key and right-click on the widget. Choose "Log to console $scope.data". Open Chrome Developer Tools and expand the object dumped to the console and verify that the value of $scope.data.prop1 is "Apple".

Advanced Techniques

The advanced debugging techniques described below can be highly affective when troubleshooting on a production instance where it is not possible to make any changes. All the techniques below are run through Chrome Developer Tools.

  1. Creating a reference to the widget's scope in the console ("The puppet master"):

You can think of this technique as an analogy to a puppet show. The puppeteer activates and manipulates the puppets (widgets) with a set of strings. In this case we are creating a second set of strings to the puppet so that we can activate and manipulate the widget from the JavaScript console!

This technique allows you to:

Change the widget's scope data
Run widget scope function
Re-run the widget Server Script

Steps to get a reference to the widget's scope in the JavaScript console:

Right-click on the widget and choose "Inspect"
In devtools Elements tab, click on the element with attribute widget=”widget”. It should be a few elements above the currently inspected element. This points the $0 scripting tool at the widget.
In the Javascript console, run the following code:

var scopeRef = angular.element($0).scope();

Changing the widget's scope data:

Once you have a reference to the widget in the JavaScript console, you can take any piece of data in the widget's scope and just change it. After changing a value, run the AngularJS $apply() function on the scope to apply your changes to the page.
Example

After getting a reference to the Global Objects Demo Widget in the console, run the following code:

scopeRef.data.prop1 = "Pear";
scopeRef.$apply();

Running the widget's Client Controller functions from the console

Any function that is defined in the Client Scipt (client controller) of the widget is available from the widget's scope. This means that once you have a reference to a widget's scope in the console you will not only be able to change data in the scope object but you can also run any of the client controller functions!

Example

The getPrettyData() function is defined in the Client Script of the Global Objects Demo Widget. Now that we have a reference to the widget's scope in the console, we can run the function directly from the JavaScript console.

Re-run the widget's Server Script

Let's say that we've made some changes to the scope of the widget with the techniques above, we've got our reference to the widget in the console, and we want to see what happens when the server refreshes the data sent to the client controller. We can re-run the widget's Server Script from the console as per below:

scopeRef.server.refresh();

  1. Debugging and editing the widget client script directly from the Chrome devtools "Sources" panel

The client controller scripts for all widgets on the page can be found in the "Sources" panel of Chrome Developer Tools. If you look at the screen capture below, you'll notice that they are all listed under the "top" window then under the "(no domain)" section. Clicking on the script will open it in the Sources panel code editor window. Most of the widget client controller scripts are listed as <widget_id>.js, others will be listed by the id attribute value of the top level HTML element of the widget.

Once the client controller script is open in devtools you can begin debugging directly from there.

Making local changes to the client controller code from devtools

Example

Navigate the to the following URL: https://.service-now.com/sp?id=demo_widget_example.

Open Chrome developer tools.

Click on the "Sources" panel in devtools.

Open the global-objects-demo-widget.js file

Between lines 7 and 8 add the following line of code:

alert("Server script now refreshed");

Right-click in the script editor window and Save. Do not refresh the page.

Click the "server.refresh()" button in the widget.

Notice the alert window pops up showing that you've been able to alter the widget directly from devtools! This is a powerful technique when debugging production instances.
Adding break points to widget client controllers from within devtools

Another great thing about having access to the client controller code from within devtools is that you can add in break points. Break points can be added to the code by clicking on the line numbers in the code editor window of the "Sources" panel.

Example

Navigate the to the following URL: https://.service-now.com/sp?id=demo_widget_example

Open Chrome developer tools.

Click on the "Sources" panel in devtools.

Open the global-objects-demo-widget.js

Click on line number 15 to add in a break point.

Click on the "server.get({collectionName: "presidents"})" button.

Notice that JavaScript execution stops directly at line 15.

Hover the mouse over the "data" in line 15 to inspect the response.

Resume JavaScript execution with the button to the right of the code editor window.

Running the example tests

Attached to this KB article you'll find a update set which contains one Service Portal widget called "Global Objects Demo Widget" and one Service Portal page called "demo_widget_example". The demo page contains one instance of the demo widget.

To import the update set to your test instance:

1. Click on "Retrieved Update Sets" in the Application Navigator.
1. Click on the Related Link "Import Update Set from XML" at the bottom of the page.
1. Click "Choose File", location the downloaded update set from the KB article and press the "Upload" button
1. Click on the newly uploaded update set in the list of Retrieved Update Sets. The name will be "Service Portal Global Objects Demo"
1. Click the Preview Update Set button in the header.
1. Click on Commit Update Set.

To run the tests, it's good to have two browser tabs open; one with the widget's code and preview pane and the other with the demo page showing.

Tab 1: https://.service-now.com/sp_config?id=widget_editor&sys_id=072cfcbc4f04130050d128201310c7d7&spa=1

Tab 2: https://.service-now.com/sp?id=demo_page

In the widget editor, you can enable a preview pane to test any changes that you've made to the widget. To do this click on the hamburger menu at the top right of the editor and select "Enable Preview". Then just use the eye button toggle the widget preview on and off.

After every test remember to remove any changes made and resave the widget.

Post Request: ACLs or Query Business Rules

What is the post about?
ACLs vs Query Business Rules

There are opinions on using (Access Controls) ACLs or (Query Business Rules) QBRs. So lets look at this in more depth; ServiceNow seems to recommend using ACLs as they only use QBRs sparingly, the only one I can think of is on sys_user for active users. However the more I think about this, the more I think it makes more sense to manage any row level access in QBRs.

Query Business Rules

Pros

  • No "X Rows have been removed due to security constraints" messages
  • Takes less time to load lists as ACLs do not run on things they can not list

Cons

  • Yet another place to manage security
  • You have to code it, unlike some parts of ACLs

Access Controls

Pros

  • You can easily specify conditions, and roles to have it apply

Cons

  • Runs extra scripts to show/hide rows

Post Request: Notification Dialogs

What is the post about?
Notification Dialogs

What things would help with writing the post

UI Notification vs Notification Dialogs

To figure out what to use and when really is going to come down to each specific situation, but I'll go through my thoughts on what these are, how to use them, and why I favor one over another.  To do this lets introduce our contenders.  On the left we have the quick and dirty, to the point, not always clean UI Notifications.  On the right we have the attention grabbing, mouse-taking, extensions exist to block Notification Dialogs.

UI Notifications, what they are and when to use them

By on the left I mean first.  So UI Notifications for me have been a progression for debugging.  I almost always use some sort of logging of UI Notification to test some problematic script.  Way back when I used alerts because Internet Explorer didn't support console log for debugging but that was a long time ago. Then I used started using gs.addInfoMessage because it wasn't as "In your face."  Then Servicenow was nice enough to g_form.showFieldMsg. They had error and information styles.

The only UI Notifications in Servicenow are the following and are used these ways;

  1. gs.addInfoMessage (server) and gs.addErrorMessage (server)
  • When you have a message from the server, perhaps when the record is "Awaiting User Info" and you want it to be more clear, this can be done to show a message at the top of the screen.
  • client g_form.showFieldMsg()
  • When a field changes, you may clear the messages for the field, then check if it's valid, if not, show a field message.
  • NotificationMessage (client)
    • This is what triggers when you change update sets.

Why are notification dialogs are important?

Using the right type of notification dialog is important to convey the message to your users. Most the time I believe these are just a distraction or waste of a click, however sometimes they are necessary to inform the user.  There are a log of these and you can make them look nice.  The issue with the

I also have used GlideDialogWindow, GlideWindow, and GlideModal in place of the alerts and confirmation messagebut they are all essentially the same except they work slightly differently.

Available notification dialogs today.

Examples of the notification dialogs.

  • spModal - Just a wrapper to uibModal
  • uibModal - uibModal
  • SweetAlerts - sweetAlert
  • GlideModal - glideModal
  • GlideWindow
  • GlideDialogWindow
  • Native - Alerts/Dialog/Confirm
  • AddInfoMessage
  • AddErrorMessage

Using the right type of dialog window is important to convey the message to your users. Most the time I believe any distraction or waste of a click. However sometimes as much as you recommend against sometimes you got to do things you don't like. Like making a pop up window. Might as well make it look nice.

/scripts/classes/doctype/GlideModal.js

Any client-side library the browser needs -has to be shipped to the browser-. Now, by default ServiceNow will bundle these into -includes files and send them down all appended together, but we _also- put a marker in that gives you the original filename and where you can access it directly when we do that.

So you can use the 'search all files' feature of Chrome (or the equivalent in other browsers) to find references to what you're interested in. When you find the definition of said thing, see if it's in an _includes.js file

If so, scroll up to the closest Resources tag, and it should tell you where to go find that file by itself.
In this case, I loaded the Incident form, and found the definition in js_includes_last_doctype.js (edited)
So I just scrolled up a tiny bit and got the direct URL out of the _includes file
If the modal is just going to submit to an existing form, you could use GlideModalForm instead (that takes a title, a table name, and a callback for when the submit is successful) and that handles closing the modal and whatnot for you.

Post Request: Upgrades and patching

Post the Workflow API stuff

What is the post about?

https://docs.servicenow.com/bundle/london-application-development/page/app-store/dev_portal/API_reference/Workflow/concept/c_Workflow_api.html

What things would help with writing the post

////where current is a task record with a workflow context
var id = '3452d5259f2002002920bde8132e7028';
var current = new GlideRecord('std_change_proposal');
current.get('8e119a99db6b03c8d9ca72ec0f9619be');
var w = new Workflow();
var context = w.startFlow(id, current, 'insert', {});

Post Request: Inbound Action debugging

What is the post about?
Inbound Action debugging
Inbound Email debugging

What things would help with writing the post
Source
Youtube

If emails are not received or processed as expected,
it is important to identify the root cause. The following
steps help understand the inbound email process as well
as guide you through troubleshooting common issues.

  • A message is sent from a customer’s email such as Microsoft Outlook, Hotmail, or Gmail.
  • Email is delivered to a mail server.
  • The ServiceNow instance polls the email server every two minutes to download sent messages.
    • Verify if the instance is configured to receive emails
    • Identify if the scheduled job (POP Reader) in an error state
  • Confirm the scheduled job (POP Reader) is running.
    • Note: Polling time is configurable and may vary by instance.
  • Emails are received in the ServiceNow instance and processed.
    • Emails are stuck in the inbox
    • Validate the inbound email action is performed
  • Confirm the email is processed by the instance.

Post Request: Api of Apis

What is the post about?
GlideScriptEditorManager (api for apis)
This is a way to get the apis listed in the text editors. Below I include a script on how to get the data, it seems to come back in some malformed JSON. So i have to copy the JSON out and paste into something like JSON Editor Online and correct it.

var tables = [
  'sys_script_include',
  'sys_script_email',
  'catalog_client_script'
];
tables.map(function(table){
  try {
    var gsem = new GlideScriptEditorManager();
    var si = new GlideRecord(tables);
    si.newRecord();
    var api = gsem.getApis(table, "script", si).toString();
    gs.info(table);
    gs.info(api);
  } catch(e) {
    // gs.info(e);
  }
});

I've used this code in the past to generate markdown tables for these things in the past;

for(var thing in api){
    getThings(thing)
}

function getThings(thing){
    var output = ['---','---','# ?','','| Property/Method | Description |','| --- | --- |'];
    for (var prop in thing){
        output.push('| ' + prop + ' | ' + thing[prop]['!doc'] + ' |');
    }
    console.log(output.join('\n'));
}

uibmodals

What is the post about?

What things would help with writing the post

c.openModal = function(action) {
        c.modalInstance = $uibModal.open({
            templateUrl: 'ticket-modal.html',
            controllerAs: 'modalC',
            scope: $scope,
            controller: function() {
                var modalC = this;
                modalC.modalInstance = c.modalInstance;
                modalC.action = action;
                modalC.messages = c.getMessages(action);
                modalC.data = c.data;
                modalC.record = c.data.recordId;
                modalC.action_reason = '';
                //modalC.fnSubmit = c.submitModal(action,modalC.record,modalC.action_reason);
            }
        });
    }

image

Flesh out K19 Talk

What is the post about?

Learn by supporting or starting your own local Developer Meetup CCDT0335

I didn't want what happened to the SNUG's happening to this event so I 
volunteered to start a Developer Meetup.  That was two years ago.  The 
meetups main purpose, have some ad-hoc labs and have happy hours.

I'll go over what it takes to run these events. Attendees will learn 
how to:

- Identify how often and about what the meetup should meet. 
- Finding content to use for labs and / or for happy hour.
- Finding hosting locations in your area.

What things would help with writing the post

Timeline

  • Finalize Titles and abstracts Jan 10 2019
    Finalize the Abstract and Title for your presentation.
  • Final Bios and Pictures Jan 10 2019
    Finalize your bio and picture for the scheduler.
  • 1st Presentation Draft Feb 11 2019
    Complete your draft of your presentation.
  • Outline Lab/Workshop Guidebook Feb 11 2019
  • Draft Presentation Lab/Workshop Mar 18 2019
    Complete your presentation for your lab/workshop.
  • Draft Presentation Lab/Workshop Guidebook Mar 18 2019
    Complete your draft for your lab/workshop.
  • 2nd Presentation Draft Mar 18 2019
  • Draft Presentation Lab/Worksthop Mar 18 2019
  • UAT Lab/workshop ICE Apr 5 2019
  • Final Presentation Apr 19 2019
    Any files uploaded into "Final Presentation task" will be made available to attendees at the start of the conference. If your presentation is considered confidential and not intended to be shared, please DO NOT upload it in the Final Presentation task.
  • Final lab/workshop guidebooks
    Submit your final guidebook for lab/workshop.
  • Scheduled Speaker Rehearsal
    Speaker rehearsals will take place March 18 - April 19, 2019.

Exposed Data on the community

What is the post about?
Exposed Data on the community

What things would help with writing the post

var companies = {};
var endpoint = document.location.origin + "/api/now/table/sn_communities_profile?";
// endpoint += "sysparm_query=nameLIKE@^state=MN&";
// endpoint += "sysparm_fields=name,company&";
// endpoint += "sysparm_limit=100"
var client=new XMLHttpRequest();
client.open("get", endpoint);
client.setRequestHeader('Accept','application/json');
client.setRequestHeader('Content-Type','application/json');
client.setRequestHeader('X-UserToken', g_ck);
client.onreadystatechange = function() {
    if(this.readyState == this.DONE) {
        var responseObj = JSON.parse(this.response);
        responseObj.result.map(function(user){
          if(companies[user.company]){
            companies[user.company].push(user);
          } else {
            companies[user.company] = [user];
          }
        });
        console.log(companies);
    }
};
client.send("");

Export to CSV (Custom)

What is the post about?

Exporting to a custom CSV format

What things would help with writing the post

// Export to CSV 
var attachment = new GlideSysAttachment();
var data = "Number,Name\n"
var gr = new GlideRecord('incident');
gr.addQuery('active', 'true');
gr.query();
while(gr.next()){
	data += gr.number + "," + gr.caller_id.name + "\n";
}
incident = new GlideRecord('incident');
incident.get('85071a1347c12200e0ef563dbb9a71c1'); //Gets the record I want to attach the file too

var newFile = attachment.write(incident, 'Incidents.csv', 'text/csv', data);

Post Request: Upgrade Modal

What is the post about?
About using the Upgrade Modal
What things would help with writing the post
This is for either the oob sn upgrade modal
overview_help.visited.helsinki

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.