From aa77acf6a1bb71eb546a4f4533343b9067a16709 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Fri, 10 Oct 2025 14:23:48 +0200 Subject: [PATCH 01/28] Catalog Item Explorer - Widget Update Functionality update: - Support for the external URL content items. - The default target window changed to "_self" (same window). - Option to open an item in a new window added at the end of the row. --- .../Catalog Item Explorer/template.html | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Modern Development/Service Portal Widgets/Catalog Item Explorer/template.html b/Modern Development/Service Portal Widgets/Catalog Item Explorer/template.html index 856787e696..053eeb6e71 100644 --- a/Modern Development/Service Portal Widgets/Catalog Item Explorer/template.html +++ b/Modern Development/Service Portal Widgets/Catalog Item Explorer/template.html @@ -31,22 +31,29 @@ +
  • +
    +
    + {{item.name}} +
    + +
    + {{item.description}} +
    +
    +
    + +
    + {{item.type}} +
    + +
    + +
    +
  • + -
    +
    @@ -54,5 +61,5 @@
    + {{c.filteredCatalogItems.length}}© 2025 Ivan Betev
    From ed18c98f8b654c836aa6d7ef4e42e6663e5c976a Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Fri, 10 Oct 2025 14:24:09 +0200 Subject: [PATCH 02/28] Update css.scss --- .../Catalog Item Explorer/css.scss | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/Modern Development/Service Portal Widgets/Catalog Item Explorer/css.scss b/Modern Development/Service Portal Widgets/Catalog Item Explorer/css.scss index a2ec3cce47..39f984658b 100644 --- a/Modern Development/Service Portal Widgets/Catalog Item Explorer/css.scss +++ b/Modern Development/Service Portal Widgets/Catalog Item Explorer/css.scss @@ -3,18 +3,18 @@ justify-content: center; flex-wrap: wrap; width: 100%; - padding: 10px 0; + padding: 1rem 0; margin: 0; } .catalog-category { - font-size: 25px; + font-size: 2.4rem; font-weight: 600; } .category-letter:hover { transform: scale(1.4); - border-radius: 10px; + border-radius: 1rem; cursor: pointer; } @@ -36,12 +36,35 @@ color: #428BCA; } +.list-group-item { + margin:0; + display: flex; + align-items: center; +} + .main-column { + flex: 55%; cursor: pointer; } +.item-type-column { + flex: 25%; + text-align: center; + font-size: 1.2rem; +} + +.external-redirect-cell { + flex: 10%; + text-align: center; +} + +.panels-container { + display: flex; + justify-content: center; +} + .panel-footer, .panel-heading { - height: 40px; + height: 4rem; display: flex; justify-content: space-between; align-items: center; From 562f55db65007ff70fd184c18ecc9ed3a7332ec9 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Fri, 10 Oct 2025 14:24:31 +0200 Subject: [PATCH 03/28] Update script.js --- .../Catalog Item Explorer/script.js | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Modern Development/Service Portal Widgets/Catalog Item Explorer/script.js b/Modern Development/Service Portal Widgets/Catalog Item Explorer/script.js index 66b8eb63d9..ba4e2d0768 100644 --- a/Modern Development/Service Portal Widgets/Catalog Item Explorer/script.js +++ b/Modern Development/Service Portal Widgets/Catalog Item Explorer/script.js @@ -22,10 +22,11 @@ /* Get Catalog ID */ var catalogsId = $sp.getParameter("used_catalog") || options.used_catalog; - /* Get all catalog items */ + /* Get all catalog items which are active and not marked hidden on service portal */ var catalogItems = new GlideRecordSecure('sc_cat_item'); catalogItems.addQuery('sc_catalogs', 'IN', catalogsId); catalogItems.addQuery('active', true); + catalogItems.addQuery('hide_sp', false); catalogItems.orderBy('name'); catalogItems.query(); @@ -51,6 +52,7 @@ itemId: catalogItems.getUniqueValue(), name: catalogItems.getValue('name'), description: catalogItems.getValue('short_description'), + type: catalogItems.getDisplayValue('sys_class_name'), externalUrl: extUrl }); } @@ -59,39 +61,37 @@ data.catalogCategories = getUniqueFirstLetters(data.catalogItems); function getUniqueFirstLetters(strings) { - /* Create an empty array to store the first letters */ - var firstLetters = []; + /* Create an object to store unique first letters */ + var firstLettersMap = {}; - /* Iterate over the input array of strings */ - for (var i = 0; i < strings.length; i++) { - /* Get the first letter of the current string */ - var firstLetter = strings[i].name.charAt(0); - var exists = false; + /* Iterate over the input array of strings */ + for (var i = 0; i < strings.length; i++) { + /* Get the first letter of the current string and convert it to uppercase */ + var firstLetter = strings[i].name.charAt(0).toUpperCase(); - /* Check if the letter already exists in the array */ - for (var j = 0; j < firstLetters.length; j++) { - if (firstLetters[j].letter === firstLetter.toUpperCase()) { - exists = true; - break; - } - } + /* Use the letter as a key in the object to ensure uniqueness */ + if (!firstLettersMap[firstLetter]) { + firstLettersMap[firstLetter] = true; + } + } - /* Check if the first letter already exist in the array */ - if (!exists) { - /* If not add it */ - firstLetters.push({ - letter: firstLetter, - selected: false - }); - } - } + /* Convert the object keys to an array of objects */ + var firstLetters = []; + for (var letter in firstLettersMap) { + if (firstLettersMap.hasOwnProperty(letter)) { + firstLetters.push({ + letter: letter, + selected: false + }); + } + } - /* Sort the array of objects, otherwise the simplier version of sort might be used */ - firstLetters.sort(function (a, b) { - return a.letter.localeCompare(b.letter); - }); + /* Sort the array of objects */ + firstLetters.sort(function (a, b) { + return a.letter.localeCompare(b.letter); + }); - /* Return the sorted array of unique first letters */ - return firstLetters; + /* Return the sorted array of unique first letters */ + return firstLetters; } })(); From 465b76da08bb761f4b7f9f7f5b56d1c916b03565 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Fri, 10 Oct 2025 14:24:51 +0200 Subject: [PATCH 04/28] Update client_script.js --- .../Catalog Item Explorer/client_script.js | 277 +++++++++--------- 1 file changed, 139 insertions(+), 138 deletions(-) diff --git a/Modern Development/Service Portal Widgets/Catalog Item Explorer/client_script.js b/Modern Development/Service Portal Widgets/Catalog Item Explorer/client_script.js index 7638ce2cb4..12d88efebb 100644 --- a/Modern Development/Service Portal Widgets/Catalog Item Explorer/client_script.js +++ b/Modern Development/Service Portal Widgets/Catalog Item Explorer/client_script.js @@ -1,151 +1,152 @@ -api.controller = function ($scope, $window) { - /* widget controller */ - var c = this; +api.controller = function($scope, $window) { + /* widget controller */ + var c = this; - /* Variable and Service Initizalization */ - setWidgetState("initial", c.data.catalogCategories); - - /* Function to be called when "Show All Items" has been clicked */ - c.showAllItems = function () { + /* Variable and Service Initizalization */ setWidgetState("initial", c.data.catalogCategories); - c.filteredCatalogItems = c.displayItems = c.data.catalogItems; - c.isShowAllSelected = true; - c.data.currentPage = resetCurrentPage(); - c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); - }; - - /* Function to be called when "Quick Search" is active */ - c.quickSearch = function () { - if ($scope.searchText.length == 0) { - setWidgetState("initial", c.data.catalogCategories); - return; + + /* Function to be called when "Show All Items" has been clicked */ + c.showAllItems = function() { + setWidgetState("initial", c.data.catalogCategories); + c.filteredCatalogItems = c.displayItems = c.data.catalogItems; + c.isShowAllSelected = true; + c.data.currentPage = resetCurrentPage(); + c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); + }; + + /* Function to be called when "Quick Search" is active */ + c.quickSearch = function() { + if ($scope.searchText.length == 0) { + setWidgetState("initial", c.data.catalogCategories); + return; + } + + setWidgetState("default-selected", c.data.catalogCategories); + c.data.currentPage = resetCurrentPage(); + c.filteredCatalogItems = c.displayItems = $scope.searchText.length > 0 ? quickSearch(c.data.catalogItems, $scope.searchText) : []; + c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); + }; + + /* Function to be called when category letter has been clicked */ + c.selectCategory = function(category) { + setWidgetState("default", c.data.catalogCategories); + category.selected = true; + c.data.currentPage = resetCurrentPage(); + c.filteredCatalogItems = selectCategory(c.data.catalogItems, category); + c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); + c.displayItems = calculateDisplayCatalogItems(c.filteredCatalogItems, c.data.currentPage, c.data.itemsPerPage); + }; + + /* Function to be called when reset button has been pressed*/ + c.resetState = function() { + setWidgetState("initial", c.data.catalogCategories); + }; + + /* Function to generate URL and define the target window */ + c.openUrl = function (itemId, externalUrl, openInNewWindow) { + var fullLink = ""; + fullLink = c.data.defaultCatalogLink + itemId; + + /* If external URL provided then replace the output with it */ + if (externalUrl) { fullLink = externalUrl; } + + /* Define the target window */ + var target = openInNewWindow ? '_blank' : '_self'; + $window.open(fullLink, target); + }; + + /* Pagination */ + + /* Function to be called by the form element when another page has been selected */ + c.pageChanged = function() { + c.displayItems = calculateDisplayCatalogItems(c.filteredCatalogItems, c.data.currentPage, c.data.itemsPerPage); + }; + + /* Functions */ + + /* If it is a quick seach then we are giving filtered array based on the condition */ + function quickSearch(items, searchText) { + return items.filter(function(item) { + try { + /* First we need to check that values are not null, otherwise assign them with empty space to avoid app crash */ + var itemName = item.name != null ? item.name.toLowerCase() : ""; + var itemDescription = item.description != null ? item.description.toLowerCase() : ""; + + /* Return item if quick search text we placed in our input field is contained in the item name or description */ + return (itemName).indexOf(searchText.toLowerCase()) != -1 || (itemDescription).indexOf(searchText.toLowerCase()) != -1; + } catch (error) { + console.log("Something went wrong while filtering searching by item name or description"); + } + }); } - setWidgetState("default-selected", c.data.catalogCategories); - c.data.currentPage = resetCurrentPage(); - c.filteredCatalogItems = c.displayItems = $scope.searchText.length > 0 ? quickSearch(c.data.catalogItems, $scope.searchText) : []; - c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); - }; - - /* Function to be called when category letter has been clicked */ - c.selectCategory = function (category) { - setWidgetState("default", c.data.catalogCategories); - category.selected = true; - c.data.currentPage = resetCurrentPage(); - c.filteredCatalogItems = selectCategory(c.data.catalogItems, category); - c.isMultiplePage = checkMultiPage(c.filteredCatalogItems.length, c.data.itemsPerPage); - c.displayItems = calculateDisplayCatalogItems(c.filteredCatalogItems, c.data.currentPage, c.data.itemsPerPage); - }; - - /* Function to be called when reset button has been pressed*/ - c.resetState = function () { - setWidgetState("initial", c.data.catalogCategories); - }; - - /* Function to make the whole row clickable */ - c.openUrl = function (itemId, externalUrl) { - - var fullLink = ""; - fullLink = c.data.defaultCatalogLink + itemId; - - /* If external URL provided then replace the output with it */ - if (externalUrl) { fullLink = externalUrl }; - - $window.open(fullLink, "_blank"); - }; - - /* Pagination */ - - /* Function to be called by the form element when another page has been selected */ - c.pageChanged = function () { - c.displayItems = calculateDisplayCatalogItems(c.filteredCatalogItems, c.data.currentPage, c.data.itemsPerPage); - }; - - /* Functions */ - - /* If it is a quick seach then we are giving filtered array based on the condition */ - function quickSearch(items, searchText) { - return items.filter(function (item) { - try { - /* First we need to check that values are not null, otherwise assign them with empty space to avoid app crash */ - var itemName = item.name != null ? item.name.toLowerCase() : ""; - var itemDescription = item.description != null ? item.description.toLowerCase() : ""; - - /* Return item if quick search text we placed in our input field is contained in the item name or description */ - return (itemName).indexOf(searchText.toLowerCase()) != -1 || (itemDescription).indexOf(searchText.toLowerCase()) != -1; - } catch (error) { - console.log("Something went wrong while filtering searching by item name or description"); - } - }); - } - - /* If it is a quick seach then we are giving filtered array based on the condition */ - function selectCategory(items, category) { - return items.filter(function (item) { - return (item.name.toLowerCase()).substring(0, 1) == category.letter.toLowerCase(); - }); - } - - /* Function to reset the category selection to default state (all are non-selected) */ - function resetSelected(items) { - for (var i = 0; i < items.length; i++) { - items[i].selected = false; + /* If it is a quick seach then we are giving filtered array based on the condition */ + function selectCategory(items, category) { + return items.filter(function(item) { + return (item.name.toLowerCase()).substring(0, 1) == category.letter.toLowerCase(); + }); + } + + /* Function to reset the category selection to default state (all are non-selected) */ + function resetSelected(items) { + for (var i = 0; i < items.length; i++) { + items[i].selected = false; + } + c.isShowAllSelected = false; } - c.isShowAllSelected = false; - } - - /* Function to reset quick search text in the input field */ - function resetQuickSearchText() { - $scope.searchText = ""; - } - - /* Function that accumulates reset of selected category and quick search text */ - function setWidgetState(state, items) { - /* Default state is intended to clear quick search text and reset category selection only */ - if (state == "default") { - resetSelected(items); - resetQuickSearchText(); - - return c.data.msgDefaultState; + + /* Function to reset quick search text in the input field */ + function resetQuickSearchText() { + $scope.searchText = ""; } - /* Default-Selected is intended to reset the category selection state only e.g. for All items category selection */ - if (state == "default-selected") { - resetSelected(items); + /* Function that accumulates reset of selected category and quick search text */ + function setWidgetState(state, items) { + /* Default state is intended to clear quick search text and reset category selection only */ + if (state == "default") { + resetSelected(items); + resetQuickSearchText(); + + return c.data.msgDefaultState; + } + + /* Default-Selected is intended to reset the category selection state only e.g. for All items category selection */ + if (state == "default-selected") { + resetSelected(items); + + return c.data.msgCategoryReset; + } + + /* Initial is intended to bring the widget to the initial state same as after pager reload */ + if (state == "initial") { + resetQuickSearchText(); + resetSelected(items); + c.filteredCatalogItems = c.data.catalogItems; + c.displayItems = []; + c.isShowAllSelected = false; + c.isMultiplePage = false; + + return "Initialization has completed"; + } + } - return c.data.msgCategoryReset; + /* Function to flag multipaging which is used by pagination to display page selector */ + function checkMultiPage(itemsToDisplay, numOfPages) { + return Math.ceil(itemsToDisplay / numOfPages) > 1 ? true : false; } - /* Initial is intended to bring the widget to the initial state same as after pager reload */ - if (state == "initial") { - resetQuickSearchText(); - resetSelected(items); - c.filteredCatalogItems = c.data.catalogItems; - c.displayItems = []; - c.isShowAllSelected = false; - c.isMultiplePage = false; + /* Function to reset the current page to 1 everytime the category changes */ + function resetCurrentPage() { + return 1; + } + + /* Function to prepare the list of items to display based on the selected page */ + function calculateDisplayCatalogItems(filteredItemsArray, currentPage, itemsPerPage) { + return filteredItemsArray.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); + } - return "Initialization has completed"; + /* Debug - Logs */ + if (c.data.isDebugEnabled) { + console.log(c); } - } - - /* Function to flag multipaging which is used by pagination to display page selector */ - function checkMultiPage(itemsToDisplay, numOfPages) { - return Math.ceil(itemsToDisplay / numOfPages) > 1 ? true : false; - } - - /* Function to reset the current page to 1 everytime the category changes */ - function resetCurrentPage() { - return 1; - } - - /* Function to prepare the list of items to display based on the selected page */ - function calculateDisplayCatalogItems(filteredItemsArray, currentPage, itemsPerPage) { - return filteredItemsArray.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage); - } - - /* Debug - Logs */ - if (c.data.isDebugEnabled) { - console.log(c); - } }; From 9f771b367a910b3116ec991c9820a4fe140bf1eb Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Fri, 10 Oct 2025 14:25:14 +0200 Subject: [PATCH 05/28] Update options_schema.json From f47ea54a202aba0cc1a1c8deeae2b9bc947c0b0a Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 15:37:31 +0200 Subject: [PATCH 06/28] Create script.js --- .../Hastag Extraction/script.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Specialized Areas/Regular Expressions/Hastag Extraction/script.js diff --git a/Specialized Areas/Regular Expressions/Hastag Extraction/script.js b/Specialized Areas/Regular Expressions/Hastag Extraction/script.js new file mode 100644 index 0000000000..6e4eb7cbba --- /dev/null +++ b/Specialized Areas/Regular Expressions/Hastag Extraction/script.js @@ -0,0 +1,15 @@ +(function() { + + var demoData = "Quick test for hashtag and mention extraction in ServiceNow. " + + "Let's make sure it catches #Hack4Good #ServiceNow #regex and mentions like @ivan and @servicenow."; + + var tagRegex = /[#@][A-Za-z0-9_]+/g; + var matches = demoData.match(tagRegex); + + if (matches && matches.length > 0) { + gs.info('Found ' + matches.length + ' tags: ' + matches.join(', ')); + } else { + gs.info('No hashtags or mentions found.'); + } + +})(); From 32f3c779ca5b5ce547008fa66b14db3caf0088ec Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 15:44:41 +0200 Subject: [PATCH 07/28] Create README.md --- .../Hastag Extraction/README.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Specialized Areas/Regular Expressions/Hastag Extraction/README.md diff --git a/Specialized Areas/Regular Expressions/Hastag Extraction/README.md b/Specialized Areas/Regular Expressions/Hastag Extraction/README.md new file mode 100644 index 0000000000..86987c0ad3 --- /dev/null +++ b/Specialized Areas/Regular Expressions/Hastag Extraction/README.md @@ -0,0 +1,35 @@ +# Hashtag & Mention Extractor for ServiceNow + +A simple yet useful **ServiceNow Background Script** that extracts all hashtags (`#example`) and mentions (`@user`) from any text input using regular expressions. + +This script demonstrates how to apply JavaScript RegEx in server-side ServiceNow logic to parse, analyze, or extend user-generated text - ideal for text-analysis demos or lightweight automation projects. + +--- + +## 💡 Example Use Cases +- Automatically identify hashtags and mentions in **incident comments**, **knowledge articles**, or **survey feedback**. +- Build internal analytics to track trending topics like `#VPN`, `#email`, or `#network`. + +--- +## 🚀 How to Run +1. In your ServiceNow instance, navigate to **System Definition → Scripts – Background**. +2. Paste the script from this repository. +3. Click **Run Script**. + +--- + +## 📦 Reusability +The logic is **self-contained** within a single function block — no dependencies or external calls. +You can easily **copy and adjust it** to fit different contexts: +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script**. +- Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. +- Adjust the regex to detect other patterns (emails, keywords, etc.). + +This makes it a **plug-and-play snippet** for any ServiceNow application or table that requires quick text pattern recognition. + +--- + +## 🔧 Possible Extensions +- Parse live table data (`sys_journal_field`, `kb_knowledge`) instead of static text. +- Store extracted tags in a custom table for analytics. +- Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. From 07826f251bb17f968dafc583691efd28c18fca94 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 15:45:54 +0200 Subject: [PATCH 08/28] Rename README.md to README.md --- .../{Hastag Extraction => Hashtag & Mention Extractor}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Specialized Areas/Regular Expressions/{Hastag Extraction => Hashtag & Mention Extractor}/README.md (100%) diff --git a/Specialized Areas/Regular Expressions/Hastag Extraction/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md similarity index 100% rename from Specialized Areas/Regular Expressions/Hastag Extraction/README.md rename to Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md From 6f2cc7f4bc089e3ca1d355a343b3836306ec6684 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 15:46:16 +0200 Subject: [PATCH 09/28] Rename script.js to script.js --- .../{Hastag Extraction => Hashtag & Mention Extractor}/script.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Specialized Areas/Regular Expressions/{Hastag Extraction => Hashtag & Mention Extractor}/script.js (100%) diff --git a/Specialized Areas/Regular Expressions/Hastag Extraction/script.js b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js similarity index 100% rename from Specialized Areas/Regular Expressions/Hastag Extraction/script.js rename to Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js From b88c0f3460b39a85eab38108550a4189212ee3bc Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 22:49:54 +0200 Subject: [PATCH 10/28] Update README.md --- .../Hashtag & Mention Extractor/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 86987c0ad3..3ea47cc347 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -6,20 +6,20 @@ This script demonstrates how to apply JavaScript RegEx in server-side ServiceNow --- -## 💡 Example Use Cases -- Automatically identify hashtags and mentions in **incident comments**, **knowledge articles**, or **survey feedback**. -- Build internal analytics to track trending topics like `#VPN`, `#email`, or `#network`. +### 💡 Example Use Cases +- Automatically identify hashtags and mentions in **incident comments**, **knowledge articles**, or **survey feedback**. +- Extract tags or mentions from user input in Catalog Items/Record Producers to populate hidden variables or drive logic. --- -## 🚀 How to Run +### 🚀 How to Run 1. In your ServiceNow instance, navigate to **System Definition → Scripts – Background**. -2. Paste the script from this repository. +2. Paste the script from this repository and adjust it according to your needs. 3. Click **Run Script**. --- -## 📦 Reusability -The logic is **self-contained** within a single function block — no dependencies or external calls. +### 📦 Reusability +The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: - Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script**. - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. @@ -29,7 +29,7 @@ This makes it a **plug-and-play snippet** for any ServiceNow application or tabl --- -## 🔧 Possible Extensions +### 🔧 Possible Extensions - Parse live table data (`sys_journal_field`, `kb_knowledge`) instead of static text. - Store extracted tags in a custom table for analytics. - Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. From 772dcb8cb5c5e4b0e1b45b1170d84482caa171d5 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 22:52:26 +0200 Subject: [PATCH 11/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 3ea47cc347..fa29c4d9f1 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -2,8 +2,6 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags (`#example`) and mentions (`@user`) from any text input using regular expressions. -This script demonstrates how to apply JavaScript RegEx in server-side ServiceNow logic to parse, analyze, or extend user-generated text - ideal for text-analysis demos or lightweight automation projects. - --- ### 💡 Example Use Cases From 2e9bf6cf5a1283f90a994542bf14bdca7d9a800d Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:11:31 +0200 Subject: [PATCH 12/28] Update README.md --- .../Hashtag & Mention Extractor/README.md | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index fa29c4d9f1..a770f47fa6 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -21,9 +21,7 @@ The logic is **self-contained** within a single function block - no dependencies You can easily **copy and adjust it** to fit different contexts: - Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script**. - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. -- Adjust the regex to detect other patterns (emails, keywords, etc.). - -This makes it a **plug-and-play snippet** for any ServiceNow application or table that requires quick text pattern recognition. +- Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. --- @@ -31,3 +29,66 @@ This makes it a **plug-and-play snippet** for any ServiceNow application or tabl - Parse live table data (`sys_journal_field`, `kb_knowledge`) instead of static text. - Store extracted tags in a custom table for analytics. - Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. + +#### Additional Instructions: +##### Use in Script Include + +1. Go to **Script Includes** in the Application Navigator. +2. Click **New**, and name it (e.g., `TagExtractorUtils`). +3. Set the following options: + - **Client Callable**: `false` + - **Accessible from**: `All application scopes` +4. Paste this code: + +```javascript +var TagExtractorUtils = Class.create(); +TagExtractorUtils.prototype = { + initialize: function () {}, + + extract: function (text) { + var result = { + hashtags: text.match(/#[A-Za-z0-9_]+/g), + mentions: text.match(/@[A-Za-z0-9_]+/g) + }; + return result; + }, + + type: 'TagExtractorUtils' +}; +``` +#### Use in Business Rule with a couple of custom text fields + +### ✅ Use in Business Rule + +1. Go to **Business Rules** in the Application Navigator. +2. Click **New**, choose a table (e.g., `sc_task`, `incident`). +3. Set **When** to `before`, `after`, or `async` (usually `async`). +4. In the **Script** section, call your tag-extracting logic: + +```javascript +(function executeRule(current, previous /*null when async*/) { + var text = current.short_description + ' ' + current.description; + var tags = new TagExtractorUtils().extract(text); + + current.u_hashtags = tags.hashtags.join(', '); + current.u_mentions = tags.mentions.join(', '); + +})(current, previous); +``` +#### ✅ Use in Flow Action Script + +1. Go to **Flow Designer > Action** and click **New Action**. +2. Give it a name like `Extract Tags from Text`. +3. Add an **Input** (e.g., `input_text` of type String). +4. Add a **Script step**, then paste the script there: + +```javascript +(function execute(inputs, outputs) { + var text = inputs.input_text || ''; + var tags = new TagExtractorUtils().extract(text); + + outputs.hashtags = tags.hashtags.join(', '); + outputs.mentions = tags.mentions.join(', '); +})(inputs, outputs); +``` +5. Use this **Action** in your flow to extract tags by passing the text to it as a parameter. From 5fa7c780d6241f98d6ebf2b28c880536562163ee Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:12:09 +0200 Subject: [PATCH 13/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index a770f47fa6..d04526afa2 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -58,8 +58,6 @@ TagExtractorUtils.prototype = { ``` #### Use in Business Rule with a couple of custom text fields -### ✅ Use in Business Rule - 1. Go to **Business Rules** in the Application Navigator. 2. Click **New**, choose a table (e.g., `sc_task`, `incident`). 3. Set **When** to `before`, `after`, or `async` (usually `async`). From 935dfd830cf66e888ccf0c70a33103e79ab6839c Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:12:35 +0200 Subject: [PATCH 14/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index d04526afa2..1163956b53 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -73,7 +73,7 @@ TagExtractorUtils.prototype = { })(current, previous); ``` -#### ✅ Use in Flow Action Script +#### Use in Flow Action Script 1. Go to **Flow Designer > Action** and click **New Action**. 2. Give it a name like `Extract Tags from Text`. From f8f7b02d6a817ea05a192946c1161aa9d2c9485f Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:14:00 +0200 Subject: [PATCH 15/28] Update script.js --- .../Hashtag & Mention Extractor/script.js | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js index 6e4eb7cbba..10da3fc9d9 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/script.js @@ -3,13 +3,32 @@ var demoData = "Quick test for hashtag and mention extraction in ServiceNow. " + "Let's make sure it catches #Hack4Good #ServiceNow #regex and mentions like @ivan and @servicenow."; - var tagRegex = /[#@][A-Za-z0-9_]+/g; - var matches = demoData.match(tagRegex); + // --------------------------------------------- + // Useful regex patterns (for future extension): + // - Hashtags: /#[A-Za-z0-9_]+/g + // - Mentions: /@[A-Za-z0-9_]+/g + // - Emails: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g + // - Ticket refs: /INC\d{7}/g (e.g., INC0012345) + // --------------------------------------------- - if (matches && matches.length > 0) { - gs.info('Found ' + matches.length + ' tags: ' + matches.join(', ')); + // Separate regex patterns for clarity + var hashtagRegex = /#[A-Za-z0-9_]+/g; + var mentionRegex = /@[A-Za-z0-9_]+/g; + + // Match both types + var hashtags = demoData.match(hashtagRegex); + var mentions = demoData.match(mentionRegex); + + if (hashtags.length > 0) { + gs.info('Found ' + hashtags.length + ' hashtags: ' + hashtags.join(', ')); + } else { + gs.info('No hashtags found.'); + } + + if (mentions.length > 0) { + gs.info('Found ' + mentions.length + ' mentions: ' + mentions.join(', ')); } else { - gs.info('No hashtags or mentions found.'); + gs.info('No mentions found.'); } })(); From 42285df23987ecf8e9b2b520199c2804acbd6195 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:14:41 +0200 Subject: [PATCH 16/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 1163956b53..d05f22534a 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -30,8 +30,8 @@ You can easily **copy and adjust it** to fit different contexts: - Store extracted tags in a custom table for analytics. - Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. -#### Additional Instructions: -##### Use in Script Include +### Additional Instructions: +#### Use in Script Include 1. Go to **Script Includes** in the Application Navigator. 2. Click **New**, and name it (e.g., `TagExtractorUtils`). From 6d4d166ce55af5a6ef1402376f6ae16a24b5203b Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:15:00 +0200 Subject: [PATCH 17/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index d05f22534a..0aafcc34f8 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -30,6 +30,8 @@ You can easily **copy and adjust it** to fit different contexts: - Store extracted tags in a custom table for analytics. - Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. +--- + ### Additional Instructions: #### Use in Script Include From 63bb026eb3cb9e2f5611921ed223d1d590f6975a Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:15:29 +0200 Subject: [PATCH 18/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 0aafcc34f8..5c0b2274ab 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -32,7 +32,7 @@ You can easily **copy and adjust it** to fit different contexts: --- -### Additional Instructions: +### ℹ️ Additional Instructions: #### Use in Script Include 1. Go to **Script Includes** in the Application Navigator. From 0ff1111caba2f997cb698b26e9e17e2b44904702 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:19:42 +0200 Subject: [PATCH 19/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 5c0b2274ab..620d7e5914 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -6,7 +6,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 💡 Example Use Cases - Automatically identify hashtags and mentions in **incident comments**, **knowledge articles**, or **survey feedback**. -- Extract tags or mentions from user input in Catalog Items/Record Producers to populate hidden variables or drive logic. +- Extract tags or mentions from user input in **Catalog Items/Record Producers** to populate hidden variables or drive logic. --- ### 🚀 How to Run @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script**. +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#additional-instructions)). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. From 29742f34c3a879764ba955d988c63c4cfce13ac3 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:20:30 +0200 Subject: [PATCH 20/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 620d7e5914..aadf1e07e0 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#additional-instructions)). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](##additional-instructions)). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. From 4e1efc2802cd990385c0f20a1a62b5593a8bd3fd Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:20:53 +0200 Subject: [PATCH 21/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index aadf1e07e0..40f0cf08bc 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](##additional-instructions)). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#-additional-instructions)). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. From c860d7b560701656657f31fd563910fc7ff4bac6 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:23:27 +0200 Subject: [PATCH 22/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 40f0cf08bc..3cc1847c0e 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#-additional-instructions)). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](###additional-instructions)). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. From ad90ef5ba25f1b4946a647a0910f8cedf3739eb2 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:24:20 +0200 Subject: [PATCH 23/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 3cc1847c0e..a80e665c95 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](###additional-instructions)). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#additional-instructions)). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. @@ -32,7 +32,7 @@ You can easily **copy and adjust it** to fit different contexts: --- -### ℹ️ Additional Instructions: +### ℹ️ Additional Instructions #### Use in Script Include 1. Go to **Script Includes** in the Application Navigator. From fa8c5f2590de60aa1577c147f91510f79341bd8f Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:24:59 +0200 Subject: [PATCH 24/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index a80e665c95..1b2c01c375 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#additional-instructions)). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#-additional-instructions) ). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. @@ -32,7 +32,7 @@ You can easily **copy and adjust it** to fit different contexts: --- -### ℹ️ Additional Instructions +### ℹ️ Additional Instructions: #### Use in Script Include 1. Go to **Script Includes** in the Application Navigator. From 6c483b2061d1aa8011dd97027b095e50a942ccf8 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:25:18 +0200 Subject: [PATCH 25/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 1b2c01c375..fc38492221 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -19,7 +19,7 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags ### 📦 Reusability The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: -- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see [Additional Instructions](#-additional-instructions) ). +- Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see additional instructions below). - Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. - Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. From f8a0fab859eb4b25679c53a9cbfb4623b16fae7f Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:26:54 +0200 Subject: [PATCH 26/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index fc38492221..bd803f15e1 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -92,3 +92,5 @@ TagExtractorUtils.prototype = { })(inputs, outputs); ``` 5. Use this **Action** in your flow to extract tags by passing the text to it as a parameter. + +🤖 This contribution was partially created with the help of AI. From f43b54358210f5b6344f1dd3589db66a0be65fd9 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:32:17 +0200 Subject: [PATCH 27/28] Update README.md --- .../Hashtag & Mention Extractor/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index bd803f15e1..4da0710a65 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -20,15 +20,14 @@ A simple yet useful **ServiceNow Background Script** that extracts all hashtags The logic is **self-contained** within a single function block - no dependencies or external calls. You can easily **copy and adjust it** to fit different contexts: - Use it inside a **Business Rule**, **Script Include**, or **Flow Action Script** (see additional instructions below). -- Replace the sample `demoData` with a field value (e.g., `current.comments`) to analyze live data. -- Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for examples. +- Replace the sample `demoData` with a field value (e.g., `current.description`) to analyze the data. +- Adjust the regex to detect other patterns (emails, incident reference, etc.). See comments in the code for the additional examples. --- ### 🔧 Possible Extensions -- Parse live table data (`sys_journal_field`, `kb_knowledge`) instead of static text. +- Parse table data (`sys_journal_field`, `kb_knowledge`) instead of static text. - Store extracted tags in a custom table for analytics. -- Schedule a nightly “Top Tags” report with **Flow Designer** or **PA Widgets**. --- @@ -58,6 +57,8 @@ TagExtractorUtils.prototype = { type: 'TagExtractorUtils' }; ``` +5. Use it as any other script include. + #### Use in Business Rule with a couple of custom text fields 1. Go to **Business Rules** in the Application Navigator. From 5b72602f78ac46c31fd3848e3fb6a863efb260b4 Mon Sep 17 00:00:00 2001 From: Ivan Betev Date: Sun, 12 Oct 2025 23:35:22 +0200 Subject: [PATCH 28/28] Update README.md --- .../Regular Expressions/Hashtag & Mention Extractor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md index 4da0710a65..cafd512f1e 100644 --- a/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md +++ b/Specialized Areas/Regular Expressions/Hashtag & Mention Extractor/README.md @@ -59,7 +59,7 @@ TagExtractorUtils.prototype = { ``` 5. Use it as any other script include. -#### Use in Business Rule with a couple of custom text fields +#### Use in Business Rule with a couple of custom text fields and previously created script include 1. Go to **Business Rules** in the Application Navigator. 2. Click **New**, choose a table (e.g., `sc_task`, `incident`). @@ -76,7 +76,7 @@ TagExtractorUtils.prototype = { })(current, previous); ``` -#### Use in Flow Action Script +#### Use in Flow Action Script and previously created script include 1. Go to **Flow Designer > Action** and click **New Action**. 2. Give it a name like `Extract Tags from Text`.