DirkRedeker
Mega Sage

Hi

Recently, I found a question on how to run Flows every hour, but only during business time (let's sa on Mondays through Fridays between 8:00 and 18:00).

I think there are a lot of possible approaches, but I just wanted to stay inside of Flow-Designer to solve this. My intention was, NOT to spread this logic around at different places in the system.

So, I created a solution, which may also become handy for you. You can take it as a baseline and change it easily according to your personal needs.

 

Let's go.....

 

I just created an example for your which you can leverage in any of your flows.

1) I created a new "Action" in Flow Designer, see screenshot below:

find_real_file.png

The content of the custom Action can be reviewed in the screenshot below.

Mainly, this Action has ONE Output value (of type true/false), which returns "true", when the current time is between 8:00 and 18:00 and today is a day between Monday and Friday.

Otherwise, the Action returns "false" in the one any only Output field called "Is During Office hours" (see below).

find_real_file.png

Steps:

- Create a new "Action" and insert a "Script step" (1)

- You you do NOT need any "Input Variables" (2) for this "Script step"

- Create an "Output Variable" (3) as shown in the screenshot above (4) named "isofficehour"

- The value of "isofficehour" will be set in the "Script" (5) to true or false.

 

"true" means => IS currently an Office Hour (weekly between 8:00 and 18:00 and Monday through Friday)

"false" means => is any other time (non Office Hour)

here is the script for Copy/paste:

(function execute(inputs, outputs) {
  var myDateTime = new GlideDateTime();
  var myDay      = myDateTime.getDayOfWeek();  // 1 = Monday, 2 = Tuesday ... 7 = Sunday

  // 1,2,3,4 and 5 are weekdays (Monday - Friday)
  if ((myDay >= 1) && (myDay <= 5)) {
    // gs.info("today is a weekday");

    // and now check for the hours
    var myTime = myDateTime.getTime();       // gs.info("the time is: "  + myTime);
    var myHour = myTime.getHourOfDayUTC();   // gs.info("the hour is: " + myHour);

    // Check time of day between 8:00 and 18:00
    if ((myHour >= 8) && (myHour < 18)) {
      outputs.isofficehour = true;       // OK to run the job
    } else {
      outputs.isofficehour = false;      // DO NOT run the job
    }
  } else {
    // gs.info("today is NOT a weekday");
    outputs.isofficehour = false;       // DO NOT run the job
  }
  
})(inputs, outputs);

 

Next, define an Output for the Action as shown in the screenshot below (of Type "true/false") and map the Script output to the Action Output.

After creating the Output field of the Action, you need to DRAG&DROP the Data Pill (the output) from the Script Step into the CheckBox of the Output field (like shown in the screenshot below).

find_real_file.png

Note:
Do NOT get confused by:

a) the output of the Script Step, AND

b) the output of the Action

The Action Output is usable OUTSIDE the Action and can be leveraged in the Flow later. The Output of the Script Steps are limited to "internal" use INSIDE the Action. To get them (or their values) available OUTSIDE, you need to link them with the Action Output (just like we did here).

As another hint:

You could have a custom Action with THREE Script Steps, which EACH have an Output called "resultValue".

These three Outputs do have the same name, but are NOT visible outside and have different memory (any maybe different values).

You could match each of them to separate Outputs of the Action, or even COMBINE them to ONE Action output. Think about the needs that you have an about the "Interface" your Action needs to have.

 

Save and "PUBLISH" the new Action, to be available in your Flows.

 

Remember, when you ever change the Action LATER, you first need to "re-publish" it, before it takes affect in your Flow. Until THEN, the former published version will be used in your Flows!!!

 

 

2) Create a Flow to leverage your new Action

Set the Trigger to run the Flow "Repeat"ly on every hour, just like I did in the screenshot blow.

Set the "Seconds" to Zero (which is set to "1" by default")!

find_real_file.png

 

Add your newly created Action (1) to your flow, which will create an Output Data Pill "Is Office Hour" (2):

find_real_file.png

From this point in time, the "Is Office Hour" Data Pill will hold true/false depending on the current date/time.

Next, insert a "IF" Condition to your flow and check the value of the "Is Office Hour" Data Pill (1) in your condition (2) set to be "False" (3):

find_real_file.png

The left hand thread will be called if the condition is false (which means you DO have Office hours)

Note, this was a "double-false check" !!!

The nested path (right branch) will just END the flow and will run when NOT in Office hours.

 

3) Run a Test-Drive

Test your Flow in Flow Designer and open the execution results, like shown in the Screenshot below.

find_real_file.png

 

That's it. This is just the Scaffloding part of it. No you cango ahead and build something awesome on top of it.

 

Just give it a try and let me know on commenting this article below.

Maybe you have another approach or an addition on this, or maybe even found a bug.

Just let me know. Any comments are welcome.

 

If you enjoyed this article, just support me by marking helpful and/or bookmarking this article.

 

Thanks a lot

Have fun & Enjoy ServiceNow

Dirk

 

--------------------------------------------------------------------------------------------------------

If you like to also review my other articles on the ServiceNow Community, please have a look at the overview here:

Overview of my articles

NOTE: The content I provide here is based on my own experiences and does not necessarily represent my employer's views.

Comments
DrewW
Mega Sage
Mega Sage

I know you said you wanted to keep it in the flow but I found using a scheduled job to be a little easier, so this as another option.

//This may interfear with production so do not run it all the time in subprod.
(function() {
	//Only rung the flow between 7am and 7pm, Monday to Friday. Monday equals 1, Sunday equals 7.
	var gdt = new GlideDateTime();
	var day = gdt.getDayOfWeekLocalTime();
	var hour = parseInt(gdt.getLocalTime().getByFormat('h'));
	if((hour >= 7 || hour <= 19) && day <= 5){
		//Make sure the flow is not already running and if it is not then run it.
		var gr = new GlideRecord("sys_flow_context");
		gr.addEncodedQuery("flow=52ae2cafdb4e9cd086e6876f6896195e^stateINWAITING,IN_PROGRESS,QUEUED");
		gr.query();
		if(!gr.next()) {
			try {
				var inputs = {};
				sn_fd.FlowAPI.startFlow("x_mahe2_cgna.create_appeal_from_files", inputs);		
			} catch (ex) {
				var message = ex.getMessage();
				gs.error(message);
			}
		}
	}
	
})();
Pascal Verdieu
Mega Sage

One step further would be to check if it is a Business Day.  Same logic would apply, and assuming the Business Schedule information is stored in a schedule, you can then use the isInSchedule function in the Action script step to validate if the current (or provided) time is in the Schedule.

 

(function execute(inputs, outputs) {
    var sched = new GlideSchedule(inputs.schedule);
    var checkTime;
    if(inputs.timeStamp == undefined || inputs.timeStamp == null || inputs.timeStamp == '') {
        checkTime = new GlideDateTime();
    } else {
        checkTime = new GlideDateTime(inputs.timeStamp);
    }
    outputs.isinschedule = sched.isInSchedule(checkTime);
    outputs.log = 'Checking time: ' + checkTime.toString() + ' - Is in schedule: ' + outputs.isinschedule
    gs.info(outputs.log);
    
})(inputs, outputs);

  

Isha Panditrao
Tera Contributor

Hi DirkRedeker,

 

I am new to Flow designer. I have a similar requirement and was trying what you have done. However, while creating Action, I am not getting the output variable from a script in the Data panel. Therefore, I am not able to set the value of Script output to Action output. Can you guide what could be going wrong?,

 

DineshSankar
Tera Contributor

@Isha Panditrao why not consider sharing a screenshot of your action ?

Isha Panditrao
Tera Contributor

Hi Dinesh, 

 

Please find below the screenshots of a similar thing I am trying in my PDI on Incident table.  I am creating a custom action Check Operational Day in which I am checking if it is a weekend as my flow should execute only on weekends. However I am not getting the output variable in the data panel which I can set to Output step. Please guide me if you can recognize what I going wrong here. 

 

CustomAction_Screenshot.jpg

 

 

 

 

Version history
Last update:
‎12-16-2020 11:37 AM
Updated by: