Skip to content

Commit a8a4ba1

Browse files
authored
Merge branch 'ServiceNowDevProgram:main' into record-as-link
2 parents f13371d + 7dd74b5 commit a8a4ba1

File tree

8 files changed

+176
-20
lines changed

8 files changed

+176
-20
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# CancelFlow UI Action
2+
3+
A ServiceNow utility that dynamically cancels flows associated with the current record, ensuring seamless process management.
4+
5+
## Challenge
6+
7+
Managing running flows in ServiceNow can be challenging, particularly when multiple flows are tied to a single record. This utility streamlines the process by offering a dynamic solution to identify and cancel running flows, minimizing manual intervention and ensuring seamless operations.
8+
9+
This tool is especially useful in scenarios where you need to halt the current execution and initiate a new flow or process. Additionally, it can be leveraged to forcefully terminate the automation lifecycle when necessary, providing greater control over flow management.
10+
11+
## Description
12+
13+
This UI Action is designed to identify and cancel all running flows associated with the current record in a ServiceNow instance. It provides a user-friendly interface for administrators and developers to manage flow cancellations efficiently. This utility is particularly useful in scenarios where flows need to be terminated to prevent conflicts or errors during record updates.
14+
15+
## Functionality
16+
17+
The CancelFlow UI Action provides the following capabilities:
18+
- Dynamically identifies running flows for the current record.
19+
- Cancels the identified flows programmatically.
20+
- Displays success or error messages to the user for better visibility.
21+
- Ensures smooth handling of flow cancellations without manual intervention.
22+
23+
## Usage Instructions
24+
25+
### UI Action Script
26+
27+
Add the given script to your UI Action:
28+
29+
30+
### Example Usage
31+
32+
1. Open the record where you want to cancel the associated flows.
33+
2. Click on the **Cancel Flow** UI Action button.
34+
3. The system will identify and cancel all running flows for the current record.
35+
4. The same can be used in Business rules as well based on trigger conditions
36+
37+
38+
### Visibility for UI Action
39+
40+
In certain scenarios, it may be necessary to restrict the visibility of this operation to specific user groups. For example, only HR administrators or members of a designated group (e.g., "X Group") should have access to this functionality. These requirements can be addressed by configuring the **Condition** field in the UI Action. You can tailor the conditions to align with your specific use case, ensuring that only authorized users can execute this operation. One edge case about not having an active flow execution can also be handled in the condition which will restrict the visibility if no active flow execution is present.
41+
42+
43+
## Dependencies
44+
45+
- `sn_fd.FlowAPI`
46+
47+
## Category
48+
49+
Client-Side Components / UI Actions
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function cancelRunningFlows() {
2+
3+
try {
4+
var grFlowExecution = new GlideRecord("sys_flow_context");
5+
grFlowExecution.addQuery("source_record", current.sys_id);
6+
grFlowExecution.query();
7+
8+
while (grFlowExecution.next()) {
9+
sn_fd.FlowAPI.cancel(grFlowExecution.getUniqueValue(), "Canceling Flows");
10+
}
11+
} catch (error) {
12+
gs.error("Error cancelling flows: " + error.message);
13+
}
14+
}
15+
16+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Duplicate Incident Detection and Creation**
2+
3+
**Description**
4+
This inbound email action detects duplicate incidents from incoming emails and either updates existing incidents or creates a new one.
5+
6+
- Duplicate Found: Updates the existing incident's work notes with the new email content and aborts new incident creation.
7+
- No Duplicate Found: Creates a new incident with the email subject as short description and the email body as description.
8+
9+
**Use Case**
10+
When multiple users report the same issue via email, this automation prevents duplicate incidents, keeping the incident queue cleaner and improving triage efficiency.
11+
12+
**Inbound Action Configuration**
13+
- Target Table: incident
14+
- Action Type: Record Action
15+
- Type: New
16+
17+
**How It Works**
18+
1. The inbound email action scans the email subject for matches against active incidents whose short description contains the subject excluding Closed or Cancelled incidents.
19+
2. If a matching incident is found:
20+
- Updates the incident's work notes with the email content.
21+
- Aborts creation of a new incident.
22+
3. If no match is found:
23+
- Creates a new incident using the email subject as the short description and the email body as the description.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(function runAction(current, event, email, logger, classifier) {
2+
var subject = email.subject.trim();
3+
4+
//Look for duplicate incident
5+
var gr = new GlideRecord('incident');
6+
gr.addActiveQuery();
7+
gr.addQuery('short_description', 'CONTAINS', subject);
8+
gr.addQuery('state', 'NOT IN', '3,4'); //Ignore resolved or closed incidents
9+
gr.query();
10+
11+
if(gr.next()){
12+
//Update existing incident with duplicate email
13+
gr.work_notes = 'Duplicate email received for this incident:\n' + email.body_text;
14+
gr.update();
15+
16+
//Abort creating new incident
17+
action.setAbortAction(true);
18+
return;
19+
}
20+
21+
//Create new incident if no duplicate incident found
22+
current.short_description = email.subject;
23+
current.description = email.body_text;
24+
current.update();
25+
})(current, event, email, logger, classifier);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix script to unsync a Asset from a CI . OOB the field is read only, this allows admin to unsync when required.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
unsyncCI();
2+
3+
function unsyncCI() {
4+
5+
var grAsset = new GlideRecord("alm_hardware");
6+
grAsset.addEncodedQuery('sys_id='); //replace query with rrequired list
7+
grAsset.query();
8+
if (grAsset.next()) {
9+
var grCI = new GlideRecord("cmdb_ci");
10+
grCI.addQuery("sys_id", grAsset.ci);
11+
grCI.setLimit(1);
12+
grCI.query();
13+
if (grCI.next()) {
14+
grCI.asset = '';
15+
grCI.setWorkFlow(false);
16+
grCI.update();
17+
}
18+
grAsset.ci = '';
19+
grAsset.setWorkFlow(false);
20+
grAsset.update();
21+
}
22+
}
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
The regex in the file getIP4OrIPV6address.js files validates for both ip address(ipv4) or ipv6 based on the input.
1+
This snippet extracts IPv4 and IPv6 addresses from free text. For single-value validation, see `validateIPInput.js` and `Validate IPv6 Address/script.js`.
22

3-
This regex cover the folloing IPv6 examples:
4-
Full IPv6 addresses (e.g., 2001:0db8:85a3:0000:0000:8a2e:0370:7334).
5-
Shorthand versions (e.g., fe80::1, where :: represents omitted zeros).
6-
IPv6 with embedded IPv4 addresses (e.g., ::ffff:192.168.1.1).
7-
And also includes following IPv4 addresses.
8-
Following are the valid IP address examples:
3+
The regex in `getIP4OrIPV6address.js` finds both IPv4 and IPv6 addresses within arbitrary text content.
94

10-
192.168.1.1
5+
IPv6 coverage includes:
6+
- Full addresses like `2001:0db8:85a3:0000:0000:8a2e:0370:7334`
7+
- Compressed forms like `fe80::1` (`::` for omitted zeros)
8+
- IPv4-embedded forms like `::ffff:192.168.1.1`
119

12-
127.0.0.1
10+
IPv4 validation now strictly enforces each octet to be in the range 0–255.
1311

14-
0.0.0.0
12+
Valid IPv4 examples:
1513

16-
255.255.255.255
14+
- 192.168.1.1
15+
- 127.0.0.1
16+
- 0.0.0.0
17+
- 255.255.255.255
18+
- 1.2.3.4
1719

18-
256.256.256.256
19-
20-
999.999.999.999
21-
22-
1.2.3
23-
24-
1.2.3.4
20+
Invalid IPv4 examples (correctly rejected by the regex):
2521

22+
- 256.256.256.256
23+
- 999.999.999.999
24+
- 1.2.3
Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
1+
// Extracts IPv4 and IPv6 addresses from arbitrary text content
2+
// For single-value validation, use validateIPInput.js or Validate IPv6 Address/script.js
13
extractIPAddresses: function(text) {
2-
var ipRegex = /\b((\d{1,3}\.){3}\d{1,3})\b|\b([a-fA-F0-9:]+:+[a-fA-F0-9:]+)\b/g;
3-
var matches = text.match(ipRegex);
4+
var ipv4 = "(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}";
5+
var ipv6 = "("+
6+
"(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}|"+
7+
"(?:[A-Fa-f0-9]{1,4}:){1,7}:|"+
8+
"(?:[A-Fa-f0-9]{1,4}:){1,6}:[A-Fa-f0-9]{1,4}|"+
9+
"(?:[A-Fa-f0-9]{1,4}:){1,5}(?::[A-Fa-f0-9]{1,4}){1,2}|"+
10+
"(?:[A-Fa-f0-9]{1,4}:){1,4}(?::[A-Fa-f0-9]{1,4}){1,3}|"+
11+
"(?:[A-Fa-f0-9]{1,4}:){1,3}(?::[A-Fa-f0-9]{1,4}){1,4}|"+
12+
"(?:[A-Fa-f0-9]{1,4}:){1,2}(?::[A-Fa-f0-9]{1,4}){1,5}|"+
13+
"[A-Fa-f0-9]{1,4}:(?:(?::[A-Fa-f0-9]{1,4}){1,6})|"+
14+
":(?:(?::[A-Fa-f0-9]{1,4}){1,7}|:)|"+
15+
"fe80:(?::[A-Fa-f0-9]{0,4}){0,4}%[0-9A-Za-z]{1,}|"+
16+
"::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:"+
17+
"(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}"+
18+
")|"+
19+
"(?:[A-Fa-f0-9]{1,4}:){1,4}:(?:"+
20+
"(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}"+
21+
")"+
22+
")";
23+
var ipRegex = new RegExp("\\b(?:" + ipv4 + "|" + ipv6 + ")\\b","g");
24+
var matches = text.match(ipRegex);
425
return matches;
526
},

0 commit comments

Comments
 (0)