From aacae3703289b0ee17f11ec57ec422f9b5136a8d Mon Sep 17 00:00:00 2001 From: Ankit Shukla Date: Fri, 4 Oct 2024 01:18:18 +0530 Subject: [PATCH 001/103] News Article Parser Parses news articles using the News API. The bot extracts title, author, description, and URL from articles based on user-provided keywords. Added error handling for cases where no articles are found. --- Parsers/News Article Parser.js | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Parsers/News Article Parser.js diff --git a/Parsers/News Article Parser.js b/Parsers/News Article Parser.js new file mode 100644 index 0000000..a79145b --- /dev/null +++ b/Parsers/News Article Parser.js @@ -0,0 +1,37 @@ +/* +activation_example:!parse_news name of news website +regex:!parse_news +flags:gmi +*/ + +var where = current.text.indexOf('!parse_news ') + 12; +var term = current.text.substr(where).trim(); + +// Build the search URL using a public news API +var searchUrl = 'https://newsapi.org/v2/everything?q=' + term + '&apiKey=981bfffa7e064a22aa8d7c8723e673ae'; + +// Replace "YOUR_API_KEY" with your actual News API key +var chatReq = new sn_ws.RESTMessageV2(); +chatReq.setEndpoint(searchUrl); +chatReq.setHttpMethod("GET"); +var chatResponse = chatReq.execute(); +var chatResponseBody = chatResponse.getBody(); + +// Parse the API response as JSON +var responseData = JSON.parse(chatResponseBody); + +// Check if the API response contains any articles +if (responseData.articles.length > 0) { + // Extract information from the first article + var article = responseData.articles[0]; + var title = article.title; + var author = article.author; + var description = article.description; + var url = article.url; + + // Send the extracted information as a Slack message + var message = "**Title:** " + title + "\n**Author:** " + author + "\n**Description:** " + description + "\n**URL:** " + url; + new x_snc_slackerbot.Slacker().send_chat(current, message, false); +} else { + new x_snc_slackerbot.Slacker().send_chat(current, "Sorry, I couldn't find any news articles related to \"" + term + "\".", false); +} From adf84a4fa21ac402bc34d1ea01280bf1826a9fcb Mon Sep 17 00:00:00 2001 From: Ankit Shukla Date: Fri, 4 Oct 2024 01:27:25 +0530 Subject: [PATCH 002/103] Update News Article Parser.js correct a line for property call --- Parsers/News Article Parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Parsers/News Article Parser.js b/Parsers/News Article Parser.js index a79145b..7184199 100644 --- a/Parsers/News Article Parser.js +++ b/Parsers/News Article Parser.js @@ -8,7 +8,7 @@ var where = current.text.indexOf('!parse_news ') + 12; var term = current.text.substr(where).trim(); // Build the search URL using a public news API -var searchUrl = 'https://newsapi.org/v2/everything?q=' + term + '&apiKey=981bfffa7e064a22aa8d7c8723e673ae'; +var searchUrl = 'https://newsapi.org/v2/everything?q=' + term + '&apiKey='+gs.getProperty("newsapi.key"); // Replace "YOUR_API_KEY" with your actual News API key var chatReq = new sn_ws.RESTMessageV2(); From d4c78350260449e542b2c304ac00950e78a8e016 Mon Sep 17 00:00:00 2001 From: Ankit Shukla Date: Fri, 4 Oct 2024 23:50:35 +0530 Subject: [PATCH 003/103] Update News Article Parser.js Made changes as per the Sugestion --- Parsers/News Article Parser.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Parsers/News Article Parser.js b/Parsers/News Article Parser.js index 7184199..39fccf2 100644 --- a/Parsers/News Article Parser.js +++ b/Parsers/News Article Parser.js @@ -1,16 +1,14 @@ /* -activation_example:!parse_news name of news website -regex:!parse_news +activation_example:!news topic or story to search for +regex:!news flags:gmi */ -var where = current.text.indexOf('!parse_news ') + 12; -var term = current.text.substr(where).trim(); +var term = current.text.replace("!news ", "").trim(); -// Build the search URL using a public news API -var searchUrl = 'https://newsapi.org/v2/everything?q=' + term + '&apiKey='+gs.getProperty("newsapi.key"); +// Build the search URL using a public news API to search for a specific topic or story +var searchUrl = 'https://newsapi.org/v2/everything?q=' + encodeURIComponent(term) + '&apiKey=' + gs.getProperty("newsapi.key"); -// Replace "YOUR_API_KEY" with your actual News API key var chatReq = new sn_ws.RESTMessageV2(); chatReq.setEndpoint(searchUrl); chatReq.setHttpMethod("GET"); @@ -25,13 +23,13 @@ if (responseData.articles.length > 0) { // Extract information from the first article var article = responseData.articles[0]; var title = article.title; - var author = article.author; - var description = article.description; + var author = article.author || "Unknown author"; + var description = article.description.length > 255 ? article.description.substring(0, 252) + "... Read More" : article.description; var url = article.url; // Send the extracted information as a Slack message - var message = "**Title:** " + title + "\n**Author:** " + author + "\n**Description:** " + description + "\n**URL:** " + url; - new x_snc_slackerbot.Slacker().send_chat(current, message, false); + var message = "*Title:* " + title + "\n*Author:* " + author + "\n*Description:* " + description + "\n*URL:* " + url; + new x_snc_slackerbot.Slacker().send_chat(current, message, true); } else { - new x_snc_slackerbot.Slacker().send_chat(current, "Sorry, I couldn't find any news articles related to \"" + term + "\".", false); + new x_snc_slackerbot.Slacker().send_chat(current, "Sorry, I couldn't find any news articles related to \"" + term + "\".", true); } From e9fa98d359a094a047186ec0ed1126753a1fa98a Mon Sep 17 00:00:00 2001 From: Ankit Shukla Date: Sat, 5 Oct 2024 18:13:23 +0530 Subject: [PATCH 004/103] Create Currency_convertor.js (#353) Add currency conversion functionality to Slack bot - Implements a command to convert currencies - Uses Exchangerate.host API to fetch exchange rates - Sends the converted amount to Slack --- Parsers/Currency_convertor.js | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Parsers/Currency_convertor.js diff --git a/Parsers/Currency_convertor.js b/Parsers/Currency_convertor.js new file mode 100644 index 0000000..d287028 --- /dev/null +++ b/Parsers/Currency_convertor.js @@ -0,0 +1,39 @@ +/* +activation_example:!convert to +regex:!convert (\d+) (\w+) to (\w+) +flags:gmi +*/ + +var input = current.text.trim(); // Get entire user input after trimming + +// Extract amount, fromCurrency, and toCurrency from the input +var match = input.match(/!convert (\d+) (\w+) to (\w+)/); +var amount = match ? match[1] : ""; +var fromCurrency = match ? match[2] : ""; +var toCurrency = match ? match[3] : ""; + +// Build the search URL using the Currency Converter API +var baseUrl = 'https://api.exchangeratesapi.io/latest'; +var searchUrl = baseUrl + '?base=' + fromCurrency; + +// Make the API request +var chatReq = new sn_ws.RESTMessageV2(); +chatReq.setEndpoint(searchUrl); +chatReq.setHttpMethod("GET"); +var chatResponse = chatReq.execute(); +var chatResponseBody = chatResponse.getBody(); + +// Parse the API response as JSON +var responseData = JSON.parse(chatResponseBody); + +// Check if the API response   + contains exchange rates +if (responseData.rates && responseData.rates[toCurrency]) { + var exchangeRate = responseData.rates[toCurrency]; + var convertedAmount = amount * exchangeRate; + + // Send a formatted message to Slack + new x_snc_slackerbot.Slacker().send_chat(current, `${amount} ${fromCurrency} is equal to ${convertedAmount.toFixed(2)} ${toCurrency}`, false); +} else { + new x_snc_slackerbot.Slacker().send_chat(current, "Sorry, I couldn't find the exchange rate for ${fromCurrency} to ${toCurrency}.", false); +} From a286b5354609bf9483557f900fc7e22107148099 Mon Sep 17 00:00:00 2001 From: Daniel Aagren Seehartrai Madsen <8853612+DanielMadsenDK@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:19:34 +0200 Subject: [PATCH 005/103] Added Stranger Things quote parser (#355) --- Parsers/Stranger things quote.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Parsers/Stranger things quote.js diff --git a/Parsers/Stranger things quote.js b/Parsers/Stranger things quote.js new file mode 100644 index 0000000..ff332a9 --- /dev/null +++ b/Parsers/Stranger things quote.js @@ -0,0 +1,22 @@ +/* +activation_example:!strangerthings +regex:!strangerthings +flags:gmi +*/ + +var input = current.text.trim(); +if (/!strangerthings/i.test(input)) { + var quote = new sn_ws.RESTMessageV2(); + quote.setEndpoint('https://strangerthings-quotes.vercel.app/api/quotes'); + quote.setHttpMethod('GET'); + + var chatResponse = quote.execute(); + var chatResponseBody = JSON.parse(chatResponse.getBody()); + + if (chatResponseBody && chatResponseBody.length > 0) { + var quoteText = chatResponseBody[0].quote; + var author = chatResponseBody[0].author; + + new x_snc_slackerbot.Slacker().send_chat(current, 'Here is a Stranger Things quote for you:\n "' + quoteText + '" - ' + author, false); + } +} From e5e7047c0b0fb6158e496f98d263d05beb425dfd Mon Sep 17 00:00:00 2001 From: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> Date: Sun, 6 Oct 2024 06:33:22 +1100 Subject: [PATCH 006/103] Several parser fixes (#357) --- Parsers/Animal Facts.js | 3 ++- Parsers/Convert Miles to Kilometre.js | 2 +- Parsers/Corporate Joke.js | 1 + Parsers/{Currency_convertor.js => Currency Converter.js} | 3 +-- 4 files changed, 5 insertions(+), 4 deletions(-) rename Parsers/{Currency_convertor.js => Currency Converter.js} (95%) diff --git a/Parsers/Animal Facts.js b/Parsers/Animal Facts.js index 3de02aa..1ed2aae 100644 --- a/Parsers/Animal Facts.js +++ b/Parsers/Animal Facts.js @@ -6,6 +6,7 @@ flags:gmi var where = current.text.indexOf('!animal ') + 8; var term = current.text.substr(where).trim(); +term = gs.urlEncode(term); var chatReq = new sn_ws.RESTMessageV2(); chatReq.setEndpoint('https://api.api-ninjas.com/v1/animals?name=' + term); chatReq.setHttpMethod("GET"); @@ -65,4 +66,4 @@ if (Array.isArray(responseData) && responseData.length > 0) { } } else { new x_snc_slackerbot.Slacker().send_chat(current, "No fun facts for the provided animal.", false); -} \ No newline at end of file +} diff --git a/Parsers/Convert Miles to Kilometre.js b/Parsers/Convert Miles to Kilometre.js index 205e22f..6fee985 100644 --- a/Parsers/Convert Miles to Kilometre.js +++ b/Parsers/Convert Miles to Kilometre.js @@ -4,7 +4,7 @@ regex:(?:^|\s)(=?-?\d{1,5}\.?\d{0,8})\s?mi(le|les)\b flags:gmi */ -var regextest = /(?:^|\s)(=?-?\d{1,5}\.?\d{0,8})\s?mi(le|iles)\b/gmi; +var regextest = /(?:^|\s)(=?-?\d{1,5}\.?\d{0,8})\s?mi(le|les)\b/gmi; var match = regextest.exec(current.text); var numbertest = /-?\d{1,}\.?\d{0,}/; var numbermatch = numbertest.exec(match[0]); diff --git a/Parsers/Corporate Joke.js b/Parsers/Corporate Joke.js index cd1db91..cc5fec9 100644 --- a/Parsers/Corporate Joke.js +++ b/Parsers/Corporate Joke.js @@ -6,6 +6,7 @@ flags:gmi var where = current.text.indexOf('!corporatejoke ') + 13; var term = current.text.substr(where).trim(); +term = gs.urlEncode(term); // Build the search URL using a public joke API var searchUrl = 'https://api.chucknorris.io/jokes/search?query=' + term; diff --git a/Parsers/Currency_convertor.js b/Parsers/Currency Converter.js similarity index 95% rename from Parsers/Currency_convertor.js rename to Parsers/Currency Converter.js index d287028..11194fa 100644 --- a/Parsers/Currency_convertor.js +++ b/Parsers/Currency Converter.js @@ -26,8 +26,7 @@ var chatResponseBody = chatResponse.getBody(); // Parse the API response as JSON var responseData = JSON.parse(chatResponseBody); -// Check if the API response   - contains exchange rates +// Check if the API response contains exchange rates if (responseData.rates && responseData.rates[toCurrency]) { var exchangeRate = responseData.rates[toCurrency]; var convertedAmount = amount * exchangeRate; From 866409fd95c2aaef4ada55f1743b2741beedd420 Mon Sep 17 00:00:00 2001 From: Soham Shee <83713160+soham-shee@users.noreply.github.com> Date: Sun, 6 Oct 2024 03:37:47 +0530 Subject: [PATCH 007/103] Find Paper Parser (#359) --- Parsers/Find Paper.js | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Parsers/Find Paper.js diff --git a/Parsers/Find Paper.js b/Parsers/Find Paper.js new file mode 100644 index 0000000..da28e40 --- /dev/null +++ b/Parsers/Find Paper.js @@ -0,0 +1,49 @@ +/* +activation_example:!findpaper paper details +regex:!findpaper +flags: +*/ + +// Extracting the search query +var searchQuery = current.text.replace(/!findpaper/gmi, "").trim().substring(0, 1000); + +// Searching for a research paper +var researchPaperRequest = new sn_ws.RESTMessageV2(); +researchPaperRequest.setEndpoint('https://api.semanticscholar.org/graph/v1/paper/search?query=' + encodeURIComponent(searchQuery) + '&limit=1'); +researchPaperRequest.setHttpMethod("GET"); +researchPaperRequest.setRequestHeader("Accept", "application/json"); + +// Executing the API call +try { + var response = researchPaperRequest.execute(); + var responseBody = response.getBody(); + var responseJson = JSON.parse(responseBody); + + // Extracting details of the first paper found + if (responseJson && responseJson.data && responseJson.data.length > 0) { + var paper = responseJson.data[0]; + var title = paper.title || "Title not available"; + var authors = "Authors not available"; + if (paper.authors && paper.authors.length > 0) { + var authorNames = []; + for (var i = 0; i < paper.authors.length; i++) { + authorNames.push(paper.authors[i].name); + } + authors = authorNames.join(", "); + } + var year = paper.year || "Year not available"; + var url = paper.url || "URL not available"; + + // Creating the message to send + var message = `Here's a research paper I found:\n\nTitle: ${title}\nAuthors: ${authors}\nYear: ${year}\nURL: ${url}`; + + // Sending the response message + new x_snc_slackerbot.Slacker().send_chat(current, message, false); + } else { + // No paper found for the given search query + new x_snc_slackerbot.Slacker().send_chat(current, "Sorry, I couldn't find any research papers for your query.", false); + } +} catch (e) { + // Handling errors + new x_snc_slackerbot.Slacker().send_chat(current, "An error occurred while trying to find a research paper.", false); +} From 67d19b0454492c8902175640c3561c6d062a5920 Mon Sep 17 00:00:00 2001 From: Ron Karim <46779291+ronaldkarim@users.noreply.github.com> Date: Sun, 6 Oct 2024 18:06:23 +0100 Subject: [PATCH 008/103] Update !dalle parser to include error response (#363) On Status code not 200, respond to the user informing of failure and log error. Property may be created to disable error logging. On Status code of 200, continue to Upload to Cloudiary as per previous functionality, additional error response if cloudiary url nonexistant. --- Parsers/Generate an AI image.js | 64 ++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/Parsers/Generate an AI image.js b/Parsers/Generate an AI image.js index 2bde30c..3c7012e 100644 --- a/Parsers/Generate an AI image.js +++ b/Parsers/Generate an AI image.js @@ -12,35 +12,49 @@ dalleReq.setRequestHeader('Content-Type', "application/json"); dalleReq.setRequestHeader('User-Agent', "ServiceNow"); dalleReq.setRequestHeader("Accept", "*/*"); var body = { - "prompt": prompt, - "n": 1, - "size": "1024x1024", - quality: "standard", - model: "dall-e-3", - "response_format": "url", - "user": current.user.name.toString() + "prompt": prompt, + "n": 1, + "size": "1024x1024", + quality: "standard", + model: "dall-e-3", + "response_format": "url", + "user": current.user.name.toString() }; dalleReq.setRequestBody(JSON.stringify(body)); var dalleResponse = dalleReq.execute(); +var dalleResponseStatusCode = dalleResponse.getStatusCode(); var dalleResponseBody = JSON.parse(dalleResponse.getBody()); +var failureMessage = "Image Generation failed. If this is your first error please try again, otherwise contact an admin"; -//Cloudinary -var cloudinary = new sn_ws.RESTMessageV2(); -cloudinary.setEndpoint('https://api.cloudinary.com/v1_1/dxllc568e/image/upload'); -cloudinary.setHttpMethod('POST'); -cloudinary.setRequestHeader('Content-Type', "application/json"); -cloudinary.setRequestHeader('User-Agent', "ServiceNow"); -cloudinary.setRequestHeader("Accept", "*/*"); -var cloudinaryBody = { - "file": dalleResponseBody.data[0].url, - "upload_preset": gs.getProperty("cloudinary_upload_preset"), - "api_key": gs.getProperty("cloudinary_api_key"), - "timestamp": Math.floor(new Date().getTime() / 1000), -}; +if (dalleResponseStatusCode != 200) { + new x_snc_slackerbot.Slacker().send_chat(current, failureMessage); + if (gs.getProperty("generateaiimage.debug.enable", "true") == "true") { + gs.error("Error: " + dalleResponseStatusCode + " \n" + dalleResponseBody.error.message + "\n" + "Prompt: " + prompt); + } + +} else { + //Cloudinary + var cloudinary = new sn_ws.RESTMessageV2(); + cloudinary.setEndpoint('https://api.cloudinary.com/v1_1/dxllc568e/image/upload'); + cloudinary.setHttpMethod('POST'); + cloudinary.setRequestHeader('Content-Type', "application/json"); + cloudinary.setRequestHeader('User-Agent', "ServiceNow"); + cloudinary.setRequestHeader("Accept", "*/*"); + var cloudinaryBody = { + "file": dalleResponseBody.data[0].url, + "upload_preset": gs.getProperty("cloudinary_upload_preset"), + "api_key": gs.getProperty("cloudinary_api_key"), + "timestamp": Math.floor(new Date().getTime() / 1000), + }; + + cloudinary.setRequestBody(JSON.stringify(cloudinaryBody)); -cloudinary.setRequestBody(JSON.stringify(cloudinaryBody)); + var cloudinaryResponse = cloudinary.execute(); + var cloudinaryResponseBody = JSON.parse(cloudinaryResponse.getBody()); -var cloudinaryResponse = cloudinary.execute(); -var cloudinaryResponseBody = JSON.parse(cloudinaryResponse.getBody()); -new x_snc_slackerbot.Slacker().send_chat(current, "<" + cloudinaryResponseBody.url + "|" + prompt + ">\n"); -//new x_snc_slackerbot.Slacker().send_chat(current, "<" + cloudinaryResponseBody.url + "|" + prompt + "> (<" + "https://collection.cloudinary.com/dxllc568e/86896fd03420bdbdb47adcc037086bdf" + "|" + "gallery>)"); + if (cloudinaryResponseBody.url) { + new x_snc_slackerbot.Slacker().send_chat(current, "<" + cloudinaryResponseBody.url + "|" + prompt + ">\n"); + } else { + new x_snc_slackerbot.Slacker().send_chat(current, failureMessage); + } +} From 0df10935294a7a66d34a4cdfe581cbc56d93b3da Mon Sep 17 00:00:00 2001 From: Ankit Shukla Date: Tue, 8 Oct 2024 00:43:01 +0530 Subject: [PATCH 009/103] Create Translator.js (#367) This parser uses a regex pattern to capture the phrase and the target language [Spanish, French, German, Italian] from the user's message. It then makes a POST request to the 'libretranslate.de' API, which provides free translation services without the need for an API key. The parser sends a response message with the translated text or an error message if the API call fails, the language is not supported, or the format is incorrect. Please note that the language map should be expanded to include more languages and their corresponding language codes as needed. --- Parsers/Translator.js | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Parsers/Translator.js diff --git a/Parsers/Translator.js b/Parsers/Translator.js new file mode 100644 index 0000000..992c339 --- /dev/null +++ b/Parsers/Translator.js @@ -0,0 +1,61 @@ +/* +activation_example:!translate Hello world to Spanish +regex:!translate\s+(.+)\s+to\s+(\w+) +flags:gi +order:500 +stop_processing:false +*/ + +var regex = /!translate\s+(.+)\s+to\s+(\w+)/gi; +var match = regex.exec(current.text); +if (match && match[1] && match[2]) { + var phrase = match[1].trim(); + var language = match[2].trim().toLowerCase(); + var languageMap = { + 'spanish': 'es', + 'french': 'fr', + 'german': 'de', + 'italian': 'it', + // Add more languages as needed + }; + + var targetLanguageCode = languageMap[language]; + if (!targetLanguageCode) { + new x_snc_slackerbot.Slacker().send_chat(current, 'Sorry, I do not support the language "' + language + '".', false); + return; + } + + var apiUrl = 'https://libretranslate.de/translate'; + var requestBody = { + 'q': phrase, + 'source': 'en', + 'target': targetLanguageCode, + 'format': 'text' + }; + + // Make an API call to the translation service + var restMessage = new sn_ws.RESTMessageV2(); + restMessage.setHttpMethod('POST'); + restMessage.setEndpoint(apiUrl); + restMessage.setRequestHeader('Content-Type', 'application/json'); + restMessage.setRequestHeader('Accept', 'application/json'); + restMessage.setRequestBody(JSON.stringify(requestBody)); + + try { + var httpResponse = restMessage.execute(); + var httpResponseStatus = httpResponse.getStatusCode(); + + if (httpResponseStatus === 200) { + var translationData = JSON.parse(httpResponse.getBody()); + var translatedText = translationData.translatedText; + var responseMessage = 'The translation of "' + phrase + '" to ' + language + ' is: ' + translatedText; + new x_snc_slackerbot.Slacker().send_chat(current, responseMessage, false); + } else { + new x_snc_slackerbot.Slacker().send_chat(current, 'Sorry, I could not translate the phrase "' + phrase + '" to ' + language + '.', false); + } + } catch (error) { + new x_snc_slackerbot.Slacker().send_chat(current, 'There was an error with the translation service. Please try again later.', false); + } +} else { + new x_snc_slackerbot.Slacker().send_chat(current, 'Please use the format `!translate [phrase] to [language]` to translate text.', false); +} From 41c1d41e1a15bc9c38812d20aff0a256688d0369 Mon Sep 17 00:00:00 2001 From: ynr-ram <44225058+ynr-ram@users.noreply.github.com> Date: Tue, 8 Oct 2024 01:02:07 +0530 Subject: [PATCH 010/103] Random Number generator.js (#377) The Random Number Generator parser enables users to generate a random number within a specified range by entering commands like `!random 1 10`. It captures the minimum and maximum values provided, calculates a random number within that range, and returns the result to the user in a clear format. This parser enhances user engagement by adding an element of fun and unpredictability to the chat, making it suitable for games, decision-making, or simple entertainment. --- Parsers/Random Number generator.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Parsers/Random Number generator.js diff --git a/Parsers/Random Number generator.js b/Parsers/Random Number generator.js new file mode 100644 index 0000000..d29c210 --- /dev/null +++ b/Parsers/Random Number generator.js @@ -0,0 +1,17 @@ +/* +activation_example: !random 1 10 +regex: !random (\d+) (\d+) +flags: gmi +order: 100 +stop_processing: true +*/ + +var matches = current.text.match(/!random (\d+) (\d+)/); +if (matches) { + var min = parseInt(matches[1], 10); + var max = parseInt(matches[2], 10); + var randomNumber = Math.floor(Math.random() * (max - min + 1)) + min; + new x_snc_slackerbot.Slacker().send_chat(current, `Random number between ${min} and ${max}: ${randomNumber}`, false); +} else { + new x_snc_slackerbot.Slacker().send_chat(current, 'Please use the format: !random [min] [max]', true); +} From 49a33f4dcba8f74148103abf6f592325ca24275f Mon Sep 17 00:00:00 2001 From: Rashed Gudal Date: Mon, 7 Oct 2024 20:33:02 +0100 Subject: [PATCH 011/103] Update Random fact generator.js (#378) Removed line 6 - Unnecessary regex check --- Parsers/Random fact generator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Parsers/Random fact generator.js b/Parsers/Random fact generator.js index b9af543..426f0b6 100644 --- a/Parsers/Random fact generator.js +++ b/Parsers/Random fact generator.js @@ -3,7 +3,6 @@ activation_example:!fact regex:!fact flags:gmi */ -var prompt = current.text.replace(/!chatgpt/gmi, "").trim().substring(0, 1000); var chatReq = new sn_ws.RESTMessageV2(); chatReq.setEndpoint('http://numbersapi.com/random'); chatReq.setHttpMethod("GET"); From 3a14a7981436b0b0161c13ca8a088a208b8d3d46 Mon Sep 17 00:00:00 2001 From: Earl Duque <31702109+earlduque@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:42:03 -0700 Subject: [PATCH 012/103] Deactivate broken parser --- Parsers/Random Number generator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Parsers/Random Number generator.js b/Parsers/Random Number generator.js index d29c210..1573c9b 100644 --- a/Parsers/Random Number generator.js +++ b/Parsers/Random Number generator.js @@ -4,6 +4,7 @@ regex: !random (\d+) (\d+) flags: gmi order: 100 stop_processing: true +active:false */ var matches = current.text.match(/!random (\d+) (\d+)/); From 4d21565abbd0047c60d7703394b554503daf7b6f Mon Sep 17 00:00:00 2001 From: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> Date: Tue, 8 Oct 2024 06:07:52 +1000 Subject: [PATCH 013/103] Add GitHub !issue parser (#369) * Add issue parser * Correct property names --- Parsers/Create a GitHub issue.js | 203 +++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 Parsers/Create a GitHub issue.js diff --git a/Parsers/Create a GitHub issue.js b/Parsers/Create a GitHub issue.js new file mode 100644 index 0000000..dbda984 --- /dev/null +++ b/Parsers/Create a GitHub issue.js @@ -0,0 +1,203 @@ +/* +activation_example: !issue Slacker Donut is moldy, !issue -h +regex:^!issue\u0020? +flags:i +*/ + +// Prepare variables +var clientId = gs.getProperty('slackerbot.issueapp.id','invalid_id'); +var providerId = gs.getProperty('slackerbot.issueapp.provider','invalid_id'); +var installId = gs.getProperty('slackerbot.issueapp.install_id','invalid_id'); +var repositoryOwner = gs.getProperty('slackerbot.issueapp.owner','ServiceNowDevProgram'); +var supportedRepos = getSupportedRepos(); +var message = ''; +var selectedRepository = ''; +var body, blockMsg; +var titleLength = 60; // Lets be brief since we'll reflect the description in the body too + +// Get message +var issueCall = current.text.replace(/^!issue\u0020?/i,'').trim(); +var callArr = issueCall.split(' '); + +// Validate message +if(callArr.length == 0){ + message = '!issue must be called with the name of a repo, followed by the issue description. For example: `!issue Slacker My donut has no hole`\n\nThe full list of repos and accepted triggers can be found by sending !issue -help'; +} + +if(callArr.length == 1){ + if(callArr[0] == '-help'){ + message = 'SNDevs Slacker Issue Reporter\nA parser for creating issues against supported repositories\n\nUsage: `!issue repo-name description`\nExample: `!issue syntax_macros Capture syntax for calculating distance with GlideGeoPoint`\n\nSupported Repositories:'; + for(var repo in supportedRepos){ + message += '\n\t`' + repo + '` - Accepted triggers:\n\t\t`' + supportedRepos[repo].join('`, `') + '`'; + } + } else { + message = '!issue must be called with the name of a repo, *followed by the issue description*. For example: `!issue Slacker My donut has no hole`\n\nThe full list of repos and accepted triggers can be found by sending !issue -help'; + } +} + +if(callArr.length >= 2){ + var repoPar = callArr[0].toLowerCase(); + for(var repo in supportedRepos){ + if(supportedRepos[repo].indexOf(repoPar) > -1){ + selectedRepository = repo; + callArr.shift(); + } + } +} + +// Validate if we should progress +if(message.length > 0 || selectedRepository.length == 0 || clientId == 'invalid_id' || providerId == 'invalid_id' || installId == 'invalid_id'){ + if(selectedRepository.length == 0){ + message = 'The provided repository is not supported by the SNDevs Slacker Issue Reporter at this time. New repos can be added by submitting a pull request.'; + } else if(message.length == 0 && (clientId == 'invalid_id' || providerId == 'invalid_id' || installId == 'invalid_id')){ + message = 'A required property has not been configured. Please advise users in <#CKJ2TE0AK> so this can be addressed.'; + } + new x_snc_slackerbot.Slacker().send_chat(current, message, false); +} else { + body = {}; + body.title = callArr.join(' ').substring(0,titleLength); + body.body = callArr.join(' '); + + var token = getJWT(clientId, providerId); + var accessToken = getAccessToken(installId, token); + + if(!accessToken){ + message = 'An issue occurred while generating the access token for GitHub. Please advise users in <#CKJ2TE0AK> so they can investigate.'; + new x_snc_slackerbot.Slacker().send_chat(current, message, false); + } else { + var output = createIssue(repositoryOwner, selectedRepository, body, accessToken); + if(!output){ + message = 'An issue occured while creating an issue over the API. Please wait a few seconds and try again. If the issue persists, please advise users in <#CKJ2TE0AK> so they can investigate.'; + new x_snc_slackerbot.Slacker().send_chat(current, message, false); + } else { + blockMsg = buildBlockMessage(output.number, output.html_url); + new x_snc_slackerbot.Slacker().send_chat(current, message, false); + } + } +} + +/** + * Get list of supported repos + * @returns {Object.} Object of repos as keys and accepted triggers as array values + */ +function getSupportedRepos() { + // Make triggers lowercase so that we can do case-insensitive matching + var repoMap = { + 'code-snippets': ['code-snippets','snippets'], + 'SlackerBot': ['slacker','slackbot'], + 'UI-Builder-Conference-Notes-App': ['ui-builder-conference-notes-app','conference-notes','notes-app'], + 'Points-Thing': ['points-thing','pt','points'], + 'Plants': ['plants'], + 'example-instancescan-checks': ['example-instancescan-checks','checks','instancescan'], + 'syntax_macros': ['syntax_macros','macros'], + 'ServiceNow-GenAi-Prompt-Library': ['serviceNow-genai-prompt-library','genai','prompts','prompt','library','prompt-library'], + 'Hacktoberfest': ['Hacktoberfest'] + } + + return repoMap; +} + +/** + * Generate JSON Web Token (JWT) for GitHub + * @param client {string} GitHub App Client ID + * @param provider {string} Sys_ID of JWT Provider + * @returns {string} Signed JWT + */ +function getJWT(client, provider){ + var jwtAPI = new sn_auth.GlideJWTAPI(); + var header = JSON.stringify({typ: 'JWT', alg: 'RSA256'}); + var exp = new GlideDateTime(); + exp.addSeconds(600); + var now = new GlideDateTime(); + now.addSeconds(-60); + var payloadObj = { + iat: Math.floor(now.getNumericValue() / 1000), + iss: client, + exp: Math.floor(exp.getNumericValue() / 1000) + }; + var payload = JSON.stringify(payloadObj); + + var jwt = jwtAPI.generateJWT(provider, header, payload); + return jwt; +} + +/** + * Get Installation Access Token to act on behalf of App within installed scope + * @param install {string} Installation ID for Organisation/User + * @param jwt {string} Signed JWT + * @returns {string|false} Installation Access Token + */ +function getAccessToken(install,jwt){ + var tokenRequest = new sn_ws.RESTMessageV2(); + tokenRequest.setEndpoint('https://api.github.com/app/installations/' + install + '/access_tokens'); + tokenRequest.setHttpMethod('POST'); + tokenRequest.setRequestHeader('Accept','application/vnd.github+json'); + tokenRequest.setRequestHeader('Authorization','Bearer ' + jwt); + + var tokenResp = tokenRequest.execute(); + if(tokenResp.getStatusCode() == 201){ + return (JSON.parse(tokenResp.getBody())).token; + } + return false; +} + +/** + * Create an issue in GitHub + * @param owner {string} Name of repo owner + * @param repo {string} Name of repo + * @param body {Object.} Issue payload + * @param token {string} Installation access token + * @returns Created issue payload + */ +function createIssue(owner, repo, body, token){ + var issueRequest = new sn_ws.RESTMessageV2(); + issueRequest.setEndpoint('https://api.github.com/repos/' + owner + '/' + repo + '/issues'); + issueRequest.setHttpMethod('POST'); + issueRequest.setRequestHeader('Accept','application/vnd.github+json'); + issueRequest.setRequestHeader('Authorization','Bearer ' + token); + issueRequest.setRequestBody(JSON.stringify(body)); + + var issueResp = issueRequest.execute(); + if(issueResp.getStatusCode() == 201){ + return JSON.parse(issueResp.getBody()); + } + return false; +} + +/** + * Build a block message for created issues + * @param number {integer} Issue number + * @param url {string} Issue URL + * @returns Slack Block message + */ +function buildBlockMessage(number, url){ + var blocks = { + 'blocks': [ + { + 'type': 'section', + 'text': { + 'type': 'mrkdwn', + 'text': '*Issue #' + number + ' created* :tada:' + } + }, + { + 'type': 'section', + 'text': { + 'type': 'mrkdwn', + 'text': 'Click this button to view your issue' + }, + 'accessory': { + 'type': 'button', + 'text': { + 'type': 'plain_text', + 'text': 'Open GitHub', + 'emoji': true + }, + 'style': 'primary', + 'url': url + } + } + ] + }; + return blocks; +} From 322df1360fe683a3d207b17396c50d2e1396fdaa Mon Sep 17 00:00:00 2001 From: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> Date: Tue, 8 Oct 2024 10:03:08 +1000 Subject: [PATCH 014/103] fix: If logic and Block Message fix: Overly broad if logic overwriting responses fix: Block message missing `text` tag fix: activation_example had additional space fix: consolidate Slacker invocation --- Parsers/Create a GitHub issue.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Parsers/Create a GitHub issue.js b/Parsers/Create a GitHub issue.js index dbda984..25abe23 100644 --- a/Parsers/Create a GitHub issue.js +++ b/Parsers/Create a GitHub issue.js @@ -1,5 +1,5 @@ /* -activation_example: !issue Slacker Donut is moldy, !issue -h +activation_example:!issue Slacker Moldy donut, !issue -help regex:^!issue\u0020? flags:i */ @@ -14,6 +14,7 @@ var message = ''; var selectedRepository = ''; var body, blockMsg; var titleLength = 60; // Lets be brief since we'll reflect the description in the body too +var slacker = new x_snc_slackerbot.Slacker(); // Get message var issueCall = current.text.replace(/^!issue\u0020?/i,'').trim(); @@ -31,7 +32,7 @@ if(callArr.length == 1){ message += '\n\t`' + repo + '` - Accepted triggers:\n\t\t`' + supportedRepos[repo].join('`, `') + '`'; } } else { - message = '!issue must be called with the name of a repo, *followed by the issue description*. For example: `!issue Slacker My donut has no hole`\n\nThe full list of repos and accepted triggers can be found by sending !issue -help'; + message = '!issue must be called with the name of a repo, followed by the issue description. For example: `!issue Slacker My donut has no hole`\n\nThe full list of repos and accepted triggers can be found by sending !issue -help'; } } @@ -47,12 +48,12 @@ if(callArr.length >= 2){ // Validate if we should progress if(message.length > 0 || selectedRepository.length == 0 || clientId == 'invalid_id' || providerId == 'invalid_id' || installId == 'invalid_id'){ - if(selectedRepository.length == 0){ + if(selectedRepository.length == 0 && callArr.length > 1 && callArr[0] != '-help'){ message = 'The provided repository is not supported by the SNDevs Slacker Issue Reporter at this time. New repos can be added by submitting a pull request.'; } else if(message.length == 0 && (clientId == 'invalid_id' || providerId == 'invalid_id' || installId == 'invalid_id')){ message = 'A required property has not been configured. Please advise users in <#CKJ2TE0AK> so this can be addressed.'; } - new x_snc_slackerbot.Slacker().send_chat(current, message, false); + slacker.send_chat(current, message, false); } else { body = {}; body.title = callArr.join(' ').substring(0,titleLength); @@ -63,15 +64,15 @@ if(message.length > 0 || selectedRepository.length == 0 || clientId == 'invalid_ if(!accessToken){ message = 'An issue occurred while generating the access token for GitHub. Please advise users in <#CKJ2TE0AK> so they can investigate.'; - new x_snc_slackerbot.Slacker().send_chat(current, message, false); + slacker.send_chat(current, message, false); } else { var output = createIssue(repositoryOwner, selectedRepository, body, accessToken); if(!output){ message = 'An issue occured while creating an issue over the API. Please wait a few seconds and try again. If the issue persists, please advise users in <#CKJ2TE0AK> so they can investigate.'; - new x_snc_slackerbot.Slacker().send_chat(current, message, false); + slacker.send_chat(current, message, false); } else { blockMsg = buildBlockMessage(output.number, output.html_url); - new x_snc_slackerbot.Slacker().send_chat(current, message, false); + slacker.send_chat(current, message, false); } } } @@ -84,14 +85,14 @@ function getSupportedRepos() { // Make triggers lowercase so that we can do case-insensitive matching var repoMap = { 'code-snippets': ['code-snippets','snippets'], - 'SlackerBot': ['slacker','slackbot'], + 'SlackerBot': ['slackerbot','slacker','slackbot'], 'UI-Builder-Conference-Notes-App': ['ui-builder-conference-notes-app','conference-notes','notes-app'], 'Points-Thing': ['points-thing','pt','points'], 'Plants': ['plants'], 'example-instancescan-checks': ['example-instancescan-checks','checks','instancescan'], 'syntax_macros': ['syntax_macros','macros'], 'ServiceNow-GenAi-Prompt-Library': ['serviceNow-genai-prompt-library','genai','prompts','prompt','library','prompt-library'], - 'Hacktoberfest': ['Hacktoberfest'] + 'Hacktoberfest': ['hacktoberfest'] } return repoMap; @@ -199,5 +200,6 @@ function buildBlockMessage(number, url){ } ] }; + blocks.text = 'Issue #' + number + ' created!'; return blocks; } From f2d9a14ae1b45282d952f61421148c41e609a81b Mon Sep 17 00:00:00 2001 From: Earl Duque <31702109+earlduque@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:35:39 -0700 Subject: [PATCH 015/103] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0095156..1744e2c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,6 +18,8 @@ Eg. Run a script when a user says ____ +**Notice that lines that have key:value pairs have no leading spaces before the value**. Eg. `regex:!test` is correct, while `regex: !test` is very incorrect and could cause errors + - Line 1 must always be `/*` - Line 2 must always be `activation_example:` followed by a short description of how this parser would be activate - Line 3 must always be `regex:` followed by a regex expression that validates if the parser should run. Do not include the opening and closing `/` From 54d5b0b59f0ac5ecd23fde45e24236657e0ddf62 Mon Sep 17 00:00:00 2001 From: Ashoo Jindal <94731401+ashoo-jindal@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:09:21 +0530 Subject: [PATCH 016/103] Create Calculator.js (#386) --- Parsers/Calculator.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Parsers/Calculator.js diff --git a/Parsers/Calculator.js b/Parsers/Calculator.js new file mode 100644 index 0000000..054a320 --- /dev/null +++ b/Parsers/Calculator.js @@ -0,0 +1,38 @@ +/* +activation_example:!calculate +regex:!calculate (.+) +flags:gmi +*/ + +var input = current.text.trim(); + +// Extract the mathematical expression from the input +var match = input.match(/!calculate (.+)/); +var expression = match ? match[1] : ""; + +function evaluateExpression(expr) { + // Remove whitespace + expr = expr.replace(/\s+/g, ''); + + // Basic validation to allow only numbers and operators + if (!/^[\d+\-*/().]+$/.test(expr)) { + throw new Error("Invalid expression"); + } + + // Use Function constructor to evaluate the expression safely + return new Function('return ' + expr)(); +} + +try { + var result = evaluateExpression(expression); + + // Round the result to 2 decimal places + var roundedResult = result.toFixed(2); + + // Send the calculated result back to the user + new x_snc_slackerbot.Slacker().send_chat(current, `The result is: ${roundedResult}`, false); + +} catch (error) { + // Handle errors if the expression is invalid + new x_snc_slackerbot.Slacker().send_chat(current, "Oops! I couldn't understand that. Please provide a valid mathematical expression.", false); +} From 93d2eaabaa44305a578f8668a6e78909b08b4a04 Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 8 Oct 2024 07:34:13 -0500 Subject: [PATCH 017/103] Update Convert Fahrenheit to Celsius.js (#361) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Convert Fahrenheit to Celsius.js Modified parser to convert all Fahrenheit temperatures in the input string to Celsius instead of only the first temp in the string. E.x. "it went from 45F to 25F overnight and then back to 55F the next day" Produces 45°F is 7.22 degrees in sane units (Celsius). 25°F is -3.89 degrees in sane units (Celsius). 55°F is 12.78 degrees in sane units (Celsius). * Update Convert Fahrenheit to Celsius.js Update F to C temperature parser to convert all temperatures in the input string, instead of just 1. Updated parser for ECMAScript 2021 compatibility. --- Parsers/Convert Fahrenheit to Celsius.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Parsers/Convert Fahrenheit to Celsius.js b/Parsers/Convert Fahrenheit to Celsius.js index 334e18d..a2af281 100644 --- a/Parsers/Convert Fahrenheit to Celsius.js +++ b/Parsers/Convert Fahrenheit to Celsius.js @@ -4,10 +4,18 @@ regex:(?:^|\s)(-?\d{1,3}\.?\d{0,2})°?\s?(?:degrees)?\s?f(?:ahrenheit)?\b flags:gmi */ -var regextest = /(?:^|\s)(-?\d{1,3}\.?\d{0,2})°?\s?(?:degrees)?\s?f(?:ahrenheit)?\b/gmi; -var match = regextest.exec(current.text); -var numbertest = /-?\d{1,}\.?\d{0,}/; -var numbermatch = numbertest.exec(match[0]); -var ftoc = (parseFloat(numbermatch[0]) - 32) * 5/9; -var originalnumber = parseFloat(numbermatch[0]).toFixed(2).toString().slice(-3) == '.00' ? parseFloat(numbermatch[0]).toFixed(2).toString().slice(0, -3) : parseFloat(numbermatch[0]).toFixed(2); -var send_chat = new x_snc_slackerbot.Slacker().send_chat(current, originalnumber + '°F is ' + ftoc.toFixed(2) + ' degrees in sane units (Celsius).'); +const regexTest = /(-?\d{1,3}(?:\.\d{1,2})?)°?\s?(?:degrees?)?\s?f(?:ahrenheit)?\b/gi; +const fahrenheitToCelsius = f => ((f - 32) * 5 / 9).toFixed(2); +const formatNumber = num => Number(num).toFixed(2).replace(/\.00$/, ''); +const conversions = []; + +current.text = current.text.replace(regexTest, (match, f) => { + const celsius = fahrenheitToCelsius(f); + const formattedF = formatNumber(f); + conversions.push(`${formattedF}°F is ${celsius} degrees in sane units (Celsius).`); + return `${celsius}°C`; +}); + +const conversionMessage = conversions.join('\n'); + +new x_snc_slackerbot.Slacker().send_chat(current, conversionMessage); From d55e44ae62a3c0189f068bb9572592d9e1d80152 Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 8 Oct 2024 07:41:13 -0500 Subject: [PATCH 018/103] Update Convert Celsius to Fahrenheit.js (#362) * Update Convert Celsius to Fahrenheit.js Modified parser to convert all Celsius temperatures in the input string to Fahrenheit instead of only the first temp in the string. * Update Convert Celsius to Fahrenheit.js Update C to F temperature parser to return all temperatures when there is more than 1 in the input string. Update parser for ECMAScript 2021 compatibility. --- Parsers/Convert Celsius to Fahrenheit.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Parsers/Convert Celsius to Fahrenheit.js b/Parsers/Convert Celsius to Fahrenheit.js index ee9f9ac..1be6b44 100644 --- a/Parsers/Convert Celsius to Fahrenheit.js +++ b/Parsers/Convert Celsius to Fahrenheit.js @@ -4,10 +4,18 @@ regex:(?:^|\s)(-?\d{1,3}\.?\d{0,2})°?\s?(?:degrees)?\s?c(?:elsius|elcius)?\b flags:gmi */ -var regextest = /(?:^|\s)(-?\d{1,3}\.?\d{0,2})°?\s?(?:degrees)?\s?c(?:elsius|elcius)?\b/gmi; -var match = regextest.exec(current.text); -var numbertest = /-?\d{1,}\.?\d{0,}/; -var numbermatch = numbertest.exec(match[0]); -var ctof = (parseFloat(numbermatch[0]) * 9/5) + 32; -var originalnumber = parseFloat(numbermatch[0]).toFixed(2).toString().slice(-3) == '.00' ? parseFloat(numbermatch[0]).toFixed(2).toString().slice(0, -3) : parseFloat(numbermatch[0]).toFixed(2); -var send_chat = new x_snc_slackerbot.Slacker().send_chat(current, originalnumber + '°C is ' + ctof.toFixed(2) + ' degrees in freedom units (Fahrenheit).'); +const regexTest = /(-?\d{1,3}(?:\.\d{1,2})?)°?\s?(?:degrees?)?\s?c(?:elsius)?\b/gi; +const celsiusToFahrenheit = c => ((c * 9 / 5) + 32).toFixed(2); +const formatNumber = num => Number(num).toFixed(2).replace(/\.00$/, ''); +const conversions = []; + +current.text = current.text.replace(regexTest, (match, c) => { + const fahrenheit = celsiusToFahrenheit(c); + const formattedC = formatNumber(c); + conversions.push(`${formattedC}°C is ${fahrenheit} degrees in freedom units (Fahrenheit).`); + return `${fahrenheit}°F`; +}); + +const conversionMessage = conversions.join('\n'); + +new x_snc_slackerbot.Slacker().send_chat(current, conversionMessage); From 1ec4cd9afcc73a02502997bb50918026636341c8 Mon Sep 17 00:00:00 2001 From: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:11:55 +1000 Subject: [PATCH 019/103] Improve !verify-admin and patch !issue (#387) * fix: Block Message acknowledgements It's so strange how providing the right parameter to send allows slackerbot to send the right thing * feat: Support verify toggle and message in one function call --- Parsers/Admin tool - Verify.js | 96 +++++++++++++++++++++++--------- Parsers/Create a GitHub issue.js | 2 +- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/Parsers/Admin tool - Verify.js b/Parsers/Admin tool - Verify.js index 3cba95b..a289219 100644 --- a/Parsers/Admin tool - Verify.js +++ b/Parsers/Admin tool - Verify.js @@ -1,35 +1,77 @@ /* -activation_example:!verify-admin @Astrid -regex:^!verify-admin\b +activation_example:!verify-admin @Astrid, !verify-admin -help +regex:^!verify-admin\u0020? flags:gi */ -if (current.channel == "GD51HTR46" || current.channel == "G9LAJG7G8" || current.channel == "G7M4AP6U8") { //admin channels on sndevs - var message_body = ''; - var verification_status = false; - - // Grab user ID and then prep invocation if User-visible info provided - var invocation = current.text; - var user_id = invocation.replace('!verify-admin <@', ''); - user_id = user_id.replace(/>.*/, '').trim(); - invocation = invocation.replace('!verify-admin <@' + user_id + '>','').trim(); +if (current.channel == 'GD51HTR46' || current.channel == 'G9LAJG7G8' || current.channel == 'G7M4AP6U8') { //admin channels on sndevs + var messageBody = ''; + var userId = ''; + var description = ''; + var verificationStatus = null; + var slacker = new x_snc_slackerbot.Slacker(); - var grUser = new GlideRecord('x_snc_slackerbot_user'); - if(grUser.get('user_id',user_id) && Object.keys(grUser).indexOf('verified') != -1){ - if(invocation.length == 0){ - verification_status = !(grUser.getValue('verified') == 1 ? true : false); // Get verified and toggle - grUser.setValue('verified',verification_status); - message_body += 'Updated <@' + user_id + '>\'s verification status. They are now ' + (verification_status ? 'verified.' : 'unverified. To add a user-visible note instead of toggling verification, add text after `!verify-admin @User `. Example: `!verify-admin @Astrid Is upside down`'); + // Grab user ID and then prep invocation if User-visible info provided + var invocation = current.text.replace(/^!verify-admin\u0020?/gi,'').trim(); + var paramArr = invocation.split(' '); + + if(paramArr.length == 0){ + messageBody = '!verify-admin must be called with a user tag, followed by an optional parameter and optional description. For example: `!verify-admin @Astrid -unv Is an Impasta`\n\nThe full list of accepted triggers can be found by sending `!verify-admin -help`'; + } + + if(paramArr.length == 1){ + if(paramArr[0] == '-help'){ + messageBody = 'Admin Tool - Verify user\nA parser for setting user verification and descriptions. *Note:* This parser can only be triggered from admin channels specified.\n\nUsage: `!verify-admin @username [-v|-unv] [message]`\nExamples:\n`!verify-admin @Astrid -unv Is an Impasta`\n`!verify-admin @Astrid Some Role, Some Company`\n`!verify-admin @Astrid -v`\n\nSupported flags:\n-v: Verify the user\n-unv: Remove verification from user\n-help: Show this message'; + } else { + messageBody = '!verify-admin must be called with a user tag, followed by an optional parameter and optional description. For example: `!verify-admin @Astrid -unv Is an Impasta`\n\nThe full list of accepted triggers can be found by sending `!verify-admin -help`'; + } + } + + if(paramArr.length >= 2){ + if(/^<@.*?>$/.test(paramArr[0])){ + userId = paramArr[0].replace(/[<>@]/g,''); + paramArr.shift(); + } else { + messageBody = '!verify-admin must be called with a user tag, followed by an optional parameter and optional description. For example: `!verify-admin @Astrid -unv Is an Impasta`\n\nThe full list of accepted triggers can be found by sending `!verify-admin -help`'; + } + } + + if(messageBody.length > 0 || userId.length == 0){ + if(messageBody.length == 0 && userId.length == 0){ + messageBody = 'The provided user details are malformed, meaning the user cannot be verified.'; + } + slacker.send_chat(current, messageBody, true); } else { - grUser.setValue('user_info', invocation); - grUser.update(); - message_body += 'Updated <@' + user_id + '>\'s user info message.'; + if(paramArr.indexOf('-v') > -1 && paramArr.indexOf('-unv') > -1){ + messageBody = 'Please only provide one verify parameter in your message. Verification message ignored.'; + slacker.send_chat(current, messageBody, true); + } else { + if(paramArr.indexOf('-v') > -1){ + verificationStatus = true; + } + + if(paramArr.indexOf('-unv') > -1){ + verificationStatus = false; + } + + if(verificationStatus != null){ + paramArr = paramArr.filter(function(val){ + return (val != '-v' && val != '-unv'); + }) + } + + description = paramArr.join(' '); + var grUser = new GlideRecord('x_snc_slackerbot_user'); + if(grUser.get('user_id',userId)){ + verificationStatus != null ? grUser.setValue('verified',verificationStatus) : null; + description.length > 0 ? grUser.setValue('user_info',description) : null; + grUser.update(); + + messageBody = 'Updated <@' + userId + '>\'s verification information. Run `!verify` or `!whois` to verify output.'; + } else { + messageBody += 'I\'m afraid I can\'t do that as the user does not exist.'; + } + slacker.send_chat(current, messageBody, true); + } } - grUser.update(); - } - else { - message_body += 'I\'m afraid I can\'t do that. Either the user does not exist, or the logic to support this functionality is not yet on the instance.'; } - - var send_chat = new x_snc_slackerbot.Slacker().send_chat(current, message_body, true); -} diff --git a/Parsers/Create a GitHub issue.js b/Parsers/Create a GitHub issue.js index 25abe23..e6e2fc1 100644 --- a/Parsers/Create a GitHub issue.js +++ b/Parsers/Create a GitHub issue.js @@ -72,7 +72,7 @@ if(message.length > 0 || selectedRepository.length == 0 || clientId == 'invalid_ slacker.send_chat(current, message, false); } else { blockMsg = buildBlockMessage(output.number, output.html_url); - slacker.send_chat(current, message, false); + slacker.send_chat(current, blockMsg, false); } } } From 3214d6facbcb9afc12b1d5ef20e6a47e5455e55b Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 8 Oct 2024 19:23:53 -0500 Subject: [PATCH 020/103] Update Generate an AI chat.js Update chatgpt prompt to include system role instructions for formatting responses. --- Parsers/Generate an AI chat.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/Parsers/Generate an AI chat.js b/Parsers/Generate an AI chat.js index ebd644b..fa8fa51 100644 --- a/Parsers/Generate an AI chat.js +++ b/Parsers/Generate an AI chat.js @@ -11,11 +11,36 @@ chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key chatReq.setRequestHeader('Content-Type', "application/json"); chatReq.setRequestHeader('User-Agent', "ServiceNow"); chatReq.setRequestHeader("Accept", "*/*"); + var body = { "model": "gpt-4o-mini", - "messages": [{"role": "user", "content": prompt +". You cannot ask for follow-up responses, your response will be the end of this conversation."}], -// "max_tokens": 250 + "messages": [ + { + "role": "system", + "content": ` + You are a Slack bot that enhances the formatting of messages to make them more engaging and visually appealing. + Utilize Slack's markdown language mrkdwn for various formatting elements. + Follow these instructions: + 1. Enclose important words or phrases with *asterisks* for bold emphasis. + 2. Enclose code and numbers and percentages using backticks, like \`this\`. + 3. Use emojis when necessary to add expressiveness. + 4. Organize text with numbered or bullet lists, using "-" for bullet points. + 5. Combine bold and lists as needed: *Bold text*: normal text. + 6. Italicize words like _this_. + 7. Use blockquotes with ">" for quotes. + 8. For URLs, use . + 9. Keep user (@user) and channel (#channel) tags unchanged. + Keep close to the original message tone and formatting. + ` + }, + { + "role": "user", + "content": prompt + ". You cannot ask for follow-up responses, your response will be the end of this conversation." + } + ] + // "max_tokens": 250 }; + chatReq.setRequestBody(JSON.stringify(body)); var chatResponse = chatReq.execute(); gs.info(chatResponse.getBody()); From be528d69b4d40bbeb9679a90c58dee57e15c7659 Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 8 Oct 2024 19:24:26 -0500 Subject: [PATCH 021/103] Update Generate an AI chat react.js Update chatgpt prompt to include system role instructions for formatting responses. --- Parsers/Generate an AI chat react.js | 66 ++++++++++++++++++---------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/Parsers/Generate an AI chat react.js b/Parsers/Generate an AI chat react.js index 9853516..e5b71e7 100644 --- a/Parsers/Generate an AI chat react.js +++ b/Parsers/Generate an AI chat react.js @@ -11,26 +11,48 @@ count.addQuery('payload', 'CONTAINS', '"channel": "' + payload.event.item.channe count.query(); if (count.getRowCount() < 2) { - var prompt = current.text; - var chatReq = new sn_ws.RESTMessageV2(); - chatReq.setEndpoint('https://api.openai.com/v1/chat/completions'); - chatReq.setHttpMethod("POST"); - chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key")); - chatReq.setRequestHeader('Content-Type', "application/json"); - chatReq.setRequestHeader('User-Agent', "ServiceNow"); - chatReq.setRequestHeader("Accept", "*/*"); - var body = { - "model": "gpt-4o-mini", - "messages": [{"role": "user", "content": prompt +". You cannot ask for follow-up responses, your response will be the end of this conversation."}], - // "max_tokens": 250 - }; - chatReq.setRequestBody(JSON.stringify(body)); - var chatResponse = chatReq.execute(); - gs.info(chatResponse.getBody()); - var chatResponseBody = JSON.parse(chatResponse.getBody()); - var chatResponseContent = chatResponseBody.choices[0].message.content; - - var show_tokens = false; - var token_cost = show_tokens ? "> tokens: " + chatResponseBody.usage.total_tokens + " ($" + (parseInt(chatResponseBody.usage.total_tokens) * 0.000002).toFixed(6) + ")\n" : ""; - new x_snc_slackerbot.Slacker().send_chat(current, "> " + prompt.replace(/\n/gmi, ". ") + "\n" + token_cost + "\n" + chatResponseContent, chatResponseContent.length > 500 ? true : false); + var prompt = current.text; + var chatReq = new sn_ws.RESTMessageV2(); + chatReq.setEndpoint('https://api.openai.com/v1/chat/completions'); + chatReq.setHttpMethod("POST"); + chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key")); + chatReq.setRequestHeader('Content-Type', "application/json"); + chatReq.setRequestHeader('User-Agent', "ServiceNow"); + chatReq.setRequestHeader("Accept", "*/*"); + var body = { + "model": "gpt-4o-mini", + "messages": [ + { + "role": "system", + "content": ` + You are a Slack bot that enhances the formatting of messages to make them more engaging and visually appealing. + Utilize Slack's markdown language mrkdwn for various formatting elements. + Follow these instructions: + 1. Enclose important words or phrases with *asterisks* for bold emphasis. + 2. Enclose code and numbers and percentages using backticks, like \`this\`. + 3. Use emojis when necessary to add expressiveness. + 4. Organize text with numbered or bullet lists, using "-" for bullet points. + 5. Combine bold and lists as needed: *Bold text*: normal text. + 6. Italicize words like _this_. + 7. Use blockquotes with ">" for quotes. + 8. For URLs, use . + 9. Keep user (@user) and channel (#channel) tags unchanged. + Keep close to the original message tone and formatting.` + }, + { + "role": "user", + "content": prompt + ". You cannot ask for follow-up responses, your response will be the end of this conversation." + } + ], + // "max_tokens": 250 + }; + chatReq.setRequestBody(JSON.stringify(body)); + var chatResponse = chatReq.execute(); + gs.info(chatResponse.getBody()); + var chatResponseBody = JSON.parse(chatResponse.getBody()); + var chatResponseContent = chatResponseBody.choices[0].message.content; + + var show_tokens = false; + var token_cost = show_tokens ? "> tokens: " + chatResponseBody.usage.total_tokens + " ($" + (parseInt(chatResponseBody.usage.total_tokens) * 0.000002).toFixed(6) + ")\n" : ""; + new x_snc_slackerbot.Slacker().send_chat(current, "> " + prompt.replace(/\n/gmi, ". ") + "\n" + token_cost + "\n" + chatResponseContent, chatResponseContent.length > 500 ? true : false); } From a77b26c8f1e6db1526bb59c8d5e0cf5db66a854f Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 8 Oct 2024 19:25:08 -0500 Subject: [PATCH 022/103] Update Summarize the thread so far.js Update chatgpt prompt to include system role instructions for formatting responses to include properly formatted markdown. --- Parsers/Summarize the thread so far.js | 152 ++++++++++++++----------- 1 file changed, 87 insertions(+), 65 deletions(-) diff --git a/Parsers/Summarize the thread so far.js b/Parsers/Summarize the thread so far.js index 10ad9aa..d9679d5 100644 --- a/Parsers/Summarize the thread so far.js +++ b/Parsers/Summarize the thread so far.js @@ -1,74 +1,96 @@ /* -activation_example:!catchmeup or !summary -regex:!(catchmeup|summary|catchup) -flags:gmi +activation_example: !catchmeup or !summary +regex: !(catchmeup|summary|catchup) +flags: gmi */ -( function( current ){ - var si = new Slacker(); - var thread_ts = current.getValue( 'thread_ts' ); +(function(current) { + var si = new Slacker(); + var thread_ts = current.getValue('thread_ts'); - // if( !thread_ts ){ - // message = 'This command is only usable in a thread.'; - // si.send_chat( current, message, false ); - // return null; - // } + // Commented out code block + // if (!thread_ts) { + // message = 'This command is only usable in a thread.'; + // si.send_chat(current, message, false); + // return null; + // } - function findWordAfterDashDash(str) { - var match = str.match(/--\s*(.+)/); - return match ? " in the style of " + match[1] : ""; - } - var style = findWordAfterDashDash(current.text); - - var chats = []; - var nda = false; - var chatGr = new GlideRecord('x_snc_pointsthing_chat'); - if (thread_ts){ - chatGr.addEncodedQuery('thread_ts=' + thread_ts + '^ORts=' + thread_ts + '^textNOT LIKE!catchmeup^textNOT LIKE!summary^textNOT LIKE!catchup'); - } else { - chatGr.addEncodedQuery('channel=' + current.getValue('channel') + '^sys_created_onONLast 30 minutes@javascript:gs.beginningOfLast30Minutes()@javascript:gs.endOfLast30Minutes()^thread_ts=NULL^textNOT LIKE!catchmeup^textNOT LIKE!summary^textNOT LIKE!catchup') - } - chatGr.orderBy('sys_created_on'); - chatGr.query(); - while (chatGr.next()){ - var chat = chatGr.getDisplayValue('user') + ': ' + chatGr.getValue('text'); - if (chat.indexOf('!nda') > -1 || chat.indexOf('!confidential') > -1) { - nda = true; - break; - } - chats.push(chat); - } + function findWordAfterDashDash(str) { + var match = str.match(/--\s*(.+)/); + return match ? " in the style of " + match[1] : ""; + } + var style = findWordAfterDashDash(current.text); - if(nda){ - if (thread_ts){ - new x_snc_slackerbot.Slacker().send_chat(current, "This thread has been marked confidential and cannot be summarized.", false); - } else { - new x_snc_slackerbot.Slacker().send_chat(current, "This recent conversation has been marked confidential and cannot be summarized.", false); - } - return; - } + var chats = []; + var nda = false; + var chatGr = new GlideRecord('x_snc_pointsthing_chat'); + if (thread_ts) { + chatGr.addEncodedQuery('thread_ts=' + thread_ts + '^ORts=' + thread_ts + '^textNOT LIKE!catchmeup^textNOT LIKE!summary^textNOT LIKE!catchup'); + } else { + chatGr.addEncodedQuery('channel=' + current.getValue('channel') + '^sys_created_onONLast 30 minutes@javascript:gs.beginningOfLast30Minutes()@javascript:gs.endOfLast30Minutes()^thread_ts=NULL^textNOT LIKE!catchmeup^textNOT LIKE!summary^textNOT LIKE!catchup'); + } + chatGr.orderBy('sys_created_on'); + chatGr.query(); + while (chatGr.next()) { + var chat = chatGr.getDisplayValue('user') + ': ' + chatGr.getValue('text'); + if (chat.indexOf('!nda') > -1 || chat.indexOf('!confidential') > -1) { + nda = true; + break; + } + chats.push(chat); + } - var prompt = current.text.replace(/!chatgpt/gmi, "").trim().substring(0, 1000); - var chatReq = new sn_ws.RESTMessageV2(); - chatReq.setEndpoint('https://api.openai.com/v1/chat/completions'); - chatReq.setHttpMethod("POST"); - chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key")); - chatReq.setRequestHeader('Content-Type', "application/json"); - chatReq.setRequestHeader('User-Agent', "ServiceNow"); - chatReq.setRequestHeader("Accept", "*/*"); - var body = { - "model": "gpt-4o", - "messages": [{"role": "user", "content": "summarize the following conversation" + style + ". You cannot ask for follow-up responses. Ignore the user named Slackbot.\n\n" + chats.join("\n")}], - // "max_tokens": 250 - }; - chatReq.setRequestBody(JSON.stringify(body)); - var chatResponse = chatReq.execute(); - gs.info(chatResponse.getBody()); - var chatResponseBody = JSON.parse(chatResponse.getBody()); + if (nda) { + if (thread_ts) { + new x_snc_slackerbot.Slacker().send_chat(current, "This thread has been marked confidential and cannot be summarized.", false); + } else { + new x_snc_slackerbot.Slacker().send_chat(current, "This recent conversation has been marked confidential and cannot be summarized.", false); + } + return; + } - var show_tokens = false; - var token_cost = show_tokens ? "> tokens: " + chatResponseBody.usage.total_tokens + " ($" + (parseInt(chatResponseBody.usage.total_tokens) * 0.000002).toFixed(6) + ")\n" : ""; + var prompt = current.text.replace(/!chatgpt/gmi, "").trim().substring(0, 1000); + var chatReq = new sn_ws.RESTMessageV2(); + chatReq.setEndpoint('https://api.openai.com/v1/chat/completions'); + chatReq.setHttpMethod("POST"); + chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key")); + chatReq.setRequestHeader('Content-Type', "application/json"); + chatReq.setRequestHeader('User-Agent', "ServiceNow"); + chatReq.setRequestHeader("Accept", "*/*"); + var body = { + "model": "gpt-4o", + "messages": [{ + "role": "system", + "content": ` + You are a Slack bot that enhances the formatting of messages to make them more engaging and visually appealing. + Utilize Slack's markdown language mrkdwn for various formatting elements. + Follow these instructions: + 1. Enclose important words or phrases with *asterisks* for bold emphasis. + 2. Enclose code and numbers and percentages using backticks, like \`this\`. + 3. Use emojis when necessary to add expressiveness. + 4. Organize text with numbered or bullet lists, using "-" for bullet points. + 5. Combine bold and lists as needed: *Bold text*: normal text. + 6. Italicize words like _this_. + 7. Use blockquotes with ">" for quotes. + 8. For URLs, use . + 9. Keep user (@user) and channel (#channel) tags unchanged. + Keep close to the original message tone and formatting.` + }, + { + "role": "user", + "content": "summarize the following conversation" + style + ". You cannot ask for follow-up responses. Ignore the user named Slackbot.\n\n" + chats.join("\n") + } + ], + // "max_tokens": 250 + }; + chatReq.setRequestBody(JSON.stringify(body)); + var chatResponse = chatReq.execute(); + gs.info(chatResponse.getBody()); + var chatResponseBody = JSON.parse(chatResponse.getBody()); - var intro = thread_ts ? "> This thread so far:\n" : "> Last 30 minutes summarized:\n"; - new x_snc_slackerbot.Slacker().send_chat(current, intro + token_cost + "\n" + chatResponseBody.choices[0].message.content, false); -} )( current ); + var show_tokens = false; + var token_cost = show_tokens ? "> tokens: " + chatResponseBody.usage.total_tokens + " ($" + (parseInt(chatResponseBody.usage.total_tokens) * 0.000002).toFixed(6) + ")\n" : ""; + + var intro = thread_ts ? "> This thread so far:\n" : "> Last 30 minutes summarized:\n"; + new x_snc_slackerbot.Slacker().send_chat(current, intro + token_cost + "\n" + chatResponseBody.choices[0].message.content, false); +})(current); From f497942fc6a280ec25e26b68a4162b691c30bfa7 Mon Sep 17 00:00:00 2001 From: Earl Duque <31702109+earlduque@users.noreply.github.com> Date: Wed, 9 Oct 2024 14:14:10 +0100 Subject: [PATCH 023/103] Hacktoberfest Leaderboard parser (#388) * Hacktoberfest Leaderboard parser !hackleaders will pull up the same leaderboard that is displayed on the main hacktoberfest repo * formatting --- Parsers/Hacktoberfest Leaderboard.js | 78 ++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Parsers/Hacktoberfest Leaderboard.js diff --git a/Parsers/Hacktoberfest Leaderboard.js b/Parsers/Hacktoberfest Leaderboard.js new file mode 100644 index 0000000..1b56340 --- /dev/null +++ b/Parsers/Hacktoberfest Leaderboard.js @@ -0,0 +1,78 @@ +/* +activation_example:!hackleaders +regex:!hackleaders?|!hacktoberfestleaderboard|!leaderboardhacktoberfest +flags:gmi +stop_processing:false +*/ + +var count = new GlideAggregate("x_snc_hacktrack_event"); +count.addEncodedQuery( + "userISNOTEMPTY^pointISNOTEMPTY^point!=0^sys_created_onDATEPARTSeptember@javascript:gs.datePart('month','sep','EE')^ORsys_created_onDATEPARTOctober@javascript:gs.datePart('month','oct','EE')^ORsys_created_onDATEPARTNovember@javascript:gs.datePart('month','nov','EE')^sys_created_onONThis year@javascript:gs.beginningOfThisYear()@javascript:gs.endOfThisYear()^payload!=ignore" +); +count.groupBy("user"); +count.addAggregate("SUM", "point"); +count.orderByAggregate("SUM", "point"); +count.query(); +var items = []; +while (count.next()) { + var item = {}; + item.username = count.user.toString(); + item.points = parseInt(count.getAggregate("SUM", "point").split(".")[0]); + items.push(item); +} +var leaderboard = []; +var leaderboard_index = 0; +var count = 0; +if (Math.floor(items.length * 0.05) > 0) { + leaderboard.push("*Top 5% contributors:*"); + count = Math.floor(items.length * 0.05); + var this_section = []; + for (var i05 = 0; i05 < count; i05++) { + this_section.push(items[leaderboard_index].username); + leaderboard_index++; + } + leaderboard.push(this_section.join(", ")); + leaderboard.push(""); +} +if (Math.floor(items.length * 0.1) > 0) { + leaderboard.push("*Top 10% contributors:*"); + count = Math.floor(items.length * 0.1) - Math.floor(items.length * 0.05); + this_section = []; + for (var i10 = 0; i10 < count; i10++) { + this_section.push(items[leaderboard_index].username); + leaderboard_index++; + } + leaderboard.push(this_section.join(", ")); + leaderboard.push(""); +} +if (Math.floor(items.length * 0.25) > 0) { + leaderboard.push("*Top 25% contributors:*"); + count = + Math.floor(items.length * 0.25) - + Math.floor(items.length * 0.1) - + Math.floor(items.length * 0.05); + this_section = []; + for (var i25 = 0; i25 < count; i25++) { + this_section.push(items[leaderboard_index].username); + leaderboard_index++; + } + leaderboard.push(this_section.join(", ")); + leaderboard.push(""); +} +if (Math.floor(items.length * 0.5) > 0) { + leaderboard.push("*Top 50% contributors:*"); + count = + Math.floor(items.length * 0.5) - + Math.floor(items.length * 0.25) - + Math.floor(items.length * 0.1) - + Math.floor(items.length * 0.05); + this_section = []; + for (var i50 = 0; i50 < count; i50++) { + this_section.push(items[leaderboard_index].username); + leaderboard_index++; + } + leaderboard.push(this_section.join(", ")); + leaderboard.push(""); +} + +new x_snc_slackerbot.Slacker().send_chat(current, leaderboard.join("\n"), true); From 242f867e0687b818db62d1cfc50d536415e1dd71 Mon Sep 17 00:00:00 2001 From: wiz0floyd Date: Wed, 9 Oct 2024 22:58:48 -0400 Subject: [PATCH 024/103] Fix leading spaceUpdate Summarize the thread so far.js Fixes leading space in metadata for this parser. Missed it during review. --- Parsers/Summarize the thread so far.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Parsers/Summarize the thread so far.js b/Parsers/Summarize the thread so far.js index d9679d5..c77bb4d 100644 --- a/Parsers/Summarize the thread so far.js +++ b/Parsers/Summarize the thread so far.js @@ -1,7 +1,7 @@ /* -activation_example: !catchmeup or !summary -regex: !(catchmeup|summary|catchup) -flags: gmi +activation_example:!catchmeup or !summary +regex:!(catchmeup|summary|catchup) +flags:gmi */ (function(current) { From c993453d98704873aefe6a5c529c189980551199 Mon Sep 17 00:00:00 2001 From: Pradeep Thippani Date: Fri, 11 Oct 2024 11:00:38 +0530 Subject: [PATCH 025/103] Daily motivation (#365) * Create Daily Motivation * Rename Daily Motivation to Daily Motivation,js * Rename Daily Motivation,js to Daily Motivation.js * Rename Daily Motivation,.js to Daily Motivation.js * Update Daily Motivation.js --- Parsers/Daily Motivation.js | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Parsers/Daily Motivation.js diff --git a/Parsers/Daily Motivation.js b/Parsers/Daily Motivation.js new file mode 100644 index 0000000..df97ba4 --- /dev/null +++ b/Parsers/Daily Motivation.js @@ -0,0 +1,40 @@ +/* +activation_example:!motivate +regex:!motivate +flags:gmi +order:100 +stop_processing:false +*/ + +try { + var request = new sn_ws.RESTMessageV2(); + request.setEndpoint('https://api.quotable.io/random'); // Replace with your preferred API URL + request.setHttpMethod('GET'); + + var response = request.execute(); + var responseBody = response.getBody(); + var responseData = JSON.parse(responseBody); + + var quote = `"${responseData.content}" – ${responseData.author}`; +} catch (error) { + // Fallback to a static quote in case of an error + var quotes = [ + "The only way to do great work is to love what you do. – Steve Jobs", + "Success is not the key to happiness. Happiness is the key to success. – Albert Schweitzer", + "Believe you can and you're halfway there. – Theodore Roosevelt", + "The future belongs to those who believe in the beauty of their dreams. – Eleanor Roosevelt", + "Don’t watch the clock; do what it does. Keep going. – Sam Levenson", + "Act as if what you do makes a difference. It does. – William James", + "Success is not how high you have climbed, but how you make a positive difference to the world. – Roy T. Bennett", + "Success is not final, failure is not fatal: it is the courage to continue that counts. – Winston Churchill", + "It always seems impossible until it's done. – Nelson Mandela", + "Keep your face always toward the sunshine—and shadows will fall behind you. – Walt Whitman", + "You do not find the happy life. You make it. – Camilla Eyring Kimball", + "Success is getting what you want, happiness is wanting what you get. – W.P. Kinsella", + "You are never too old to set another goal or to dream a new dream. – C.S. Lewis", + "If you want to walk fast, walk alone. But if you want to walk far, walk together. – Ratan Tata" + ]; + quote = quotes[Math.floor(Math.random() * quotes.length)]; +} + +new x_snc_slackerbot.Slacker().send_chat(current.channel, `Motivation: "${quote}"`, false, '', current.thread_ts); From e5ef765c93fd9a60fde889b37b32a4f13b348837 Mon Sep 17 00:00:00 2001 From: Adeelah Mir <97887471+ariyadmir@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:34:10 +0530 Subject: [PATCH 026/103] Update Translator.js (#398) --- Parsers/Translator.js | 46 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/Parsers/Translator.js b/Parsers/Translator.js index 992c339..a41e8d7 100644 --- a/Parsers/Translator.js +++ b/Parsers/Translator.js @@ -1,54 +1,59 @@ /* activation_example:!translate Hello world to Spanish -regex:!translate\s+(.+)\s+to\s+(\w+) +regex:!translate\s+(.+?)\s+(?:to|into|in)\s+(\w+)$ flags:gi -order:500 -stop_processing:false */ -var regex = /!translate\s+(.+)\s+to\s+(\w+)/gi; +var regex = /!translate\s+(.+?)\s+(?:to|into|in)\s+(\w+)$/gi; var match = regex.exec(current.text); + if (match && match[1] && match[2]) { var phrase = match[1].trim(); var language = match[2].trim().toLowerCase(); + var languageMap = { - 'spanish': 'es', + 'afrikaans': 'af', + 'arabic': 'ar', + 'chinese': 'zh', + 'dutch': 'nl', 'french': 'fr', 'german': 'de', + 'hindi': 'hi', 'italian': 'it', - // Add more languages as needed + 'japanese': 'jpn', + 'korean': 'ko', + 'malay': 'my', + 'pakistani': 'ur', + 'portuguese': 'pt', + 'spanish': 'es', + 'turkish': 'tr' }; var targetLanguageCode = languageMap[language]; + if (!targetLanguageCode) { new x_snc_slackerbot.Slacker().send_chat(current, 'Sorry, I do not support the language "' + language + '".', false); return; } - var apiUrl = 'https://libretranslate.de/translate'; + var apiUrl = 'https://api.mymemory.translated.net/get'; var requestBody = { 'q': phrase, - 'source': 'en', - 'target': targetLanguageCode, - 'format': 'text' + 'langpair': 'en|' + targetLanguageCode }; - // Make an API call to the translation service var restMessage = new sn_ws.RESTMessageV2(); - restMessage.setHttpMethod('POST'); - restMessage.setEndpoint(apiUrl); - restMessage.setRequestHeader('Content-Type', 'application/json'); - restMessage.setRequestHeader('Accept', 'application/json'); - restMessage.setRequestBody(JSON.stringify(requestBody)); + restMessage.setHttpMethod('GET'); + restMessage.setEndpoint(apiUrl + '?q=' + encodeURIComponent(phrase) + '&langpair=en|' + targetLanguageCode); try { var httpResponse = restMessage.execute(); var httpResponseStatus = httpResponse.getStatusCode(); - + if (httpResponseStatus === 200) { var translationData = JSON.parse(httpResponse.getBody()); - var translatedText = translationData.translatedText; - var responseMessage = 'The translation of "' + phrase + '" to ' + language + ' is: ' + translatedText; + var translatedText = translationData.responseData.translatedText; + var responseMessage = phrase + 'translated into ' + language + ' is:\n\n ' + translatedText; new x_snc_slackerbot.Slacker().send_chat(current, responseMessage, false); } else { new x_snc_slackerbot.Slacker().send_chat(current, 'Sorry, I could not translate the phrase "' + phrase + '" to ' + language + '.', false); @@ -57,5 +62,6 @@ if (match && match[1] && match[2]) { new x_snc_slackerbot.Slacker().send_chat(current, 'There was an error with the translation service. Please try again later.', false); } } else { - new x_snc_slackerbot.Slacker().send_chat(current, 'Please use the format `!translate [phrase] to [language]` to translate text.', false); + new x_snc_slackerbot.Slacker().send_chat(current, 'Please use the format `!translate [phrase] to/into/in [language]` to translate text.', false); } + From a745b13e691feba912af7e9115d98b489fae7fee Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Sun, 13 Oct 2024 09:14:21 -0500 Subject: [PATCH 027/103] Update Weather Report Generator.js (#401) Updated Weather Report Generator parser to regex the location data from the API response. This clarifies which location is being used when there are multiple cities/locations with the same name. --- Parsers/Weather Report Generator.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Parsers/Weather Report Generator.js b/Parsers/Weather Report Generator.js index d586162..25647cf 100644 --- a/Parsers/Weather Report Generator.js +++ b/Parsers/Weather Report Generator.js @@ -3,6 +3,7 @@ activation_example:!weather london regex:!weather flags:gmi */ + var wordCount = current.text.replace('!weather', '').trim().split(' '); if (wordCount[0] != '') { @@ -12,7 +13,19 @@ if (wordCount[0] != '') { rm.setLogLevel('all'); rm.setEndpoint('https://wttr.in/' + wordCount[0] + '?format=4'); var response = rm.execute(); - new x_snc_slackerbot.Slacker().send_chat(current, response.getBody()); + var weatherBody = response.getBody(); + + var locrm = new sn_ws.RESTMessageV2(); + locrm.setHttpMethod('GET'); + locrm.setLogLevel('all'); + locrm.setEndpoint('https://wttr.in/' + wordCount[0]); + var locResponse = locrm.execute(); + var locBody = locResponse.getBody(); + var matches = locBody.match(/Location: ([^[]+)\s/); + + if (matches[1]) weatherBody = weatherBody.replace(/[^:]+/, matches[1]); + + new x_snc_slackerbot.Slacker().send_chat(current, weatherBody); } else { new x_snc_slackerbot.Slacker().send_chat(current, 'Please Provide Location Ex: "!weather london"'); } From a18c80deb5aad0bc233b510ca1304d0aae5bdcd3 Mon Sep 17 00:00:00 2001 From: Ashoo Jindal <94731401+ashoo-jindal@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:27:19 +0530 Subject: [PATCH 028/103] Update Calculator.js Removed the Function evaluator and added free API available for simple calculations. --- Parsers/Calculator.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Parsers/Calculator.js b/Parsers/Calculator.js index 054a320..560947b 100644 --- a/Parsers/Calculator.js +++ b/Parsers/Calculator.js @@ -19,8 +19,19 @@ function evaluateExpression(expr) { throw new Error("Invalid expression"); } - // Use Function constructor to evaluate the expression safely - return new Function('return ' + expr)(); + // Use Free API to calculate + var calc = new sn_ws.RESTMessageV2(); + var url = 'http://api.mathjs.org/v4/?expr=' + encodeURIComponent(expr); + calc.setEndpoint(url); + calc.setHttpMethod("GET"); + var chatResponse = calc.execute(); + var result = JSON.parse(chatResponse.getBody()); + + result = parseFloat(result); + + // Return the evaluated result + return result; + } try { @@ -30,8 +41,8 @@ try { var roundedResult = result.toFixed(2); // Send the calculated result back to the user - new x_snc_slackerbot.Slacker().send_chat(current, `The result is: ${roundedResult}`, false); - + new x_snc_slackerbot.Slacker().send_chat(current, "The result is: " + roundedResult, false); + } catch (error) { // Handle errors if the expression is invalid new x_snc_slackerbot.Slacker().send_chat(current, "Oops! I couldn't understand that. Please provide a valid mathematical expression.", false); From 9f0ca9135380c183e105bdce6b7f3b3e6b60557b Mon Sep 17 00:00:00 2001 From: Ashoo Jindal <94731401+ashoo-jindal@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:28:06 +0530 Subject: [PATCH 029/103] Update Calculator.js --- Parsers/Calculator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Parsers/Calculator.js b/Parsers/Calculator.js index 560947b..358984e 100644 --- a/Parsers/Calculator.js +++ b/Parsers/Calculator.js @@ -21,7 +21,7 @@ function evaluateExpression(expr) { // Use Free API to calculate var calc = new sn_ws.RESTMessageV2(); - var url = 'http://api.mathjs.org/v4/?expr=' + encodeURIComponent(expr); + var url = 'http://api.mathjs.org/v4/?expr=' + encodeURIComponent(expr); calc.setEndpoint(url); calc.setHttpMethod("GET"); var chatResponse = calc.execute(); From d2b26d316ec5acac4ae3107a067711cf60a4d960 Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 15 Oct 2024 08:04:23 -0500 Subject: [PATCH 030/103] Update hello from parser (#402) * Added sys_property for IP Geolocation API key https://ipgeolocation.io/ * Update Hello from.js Updated Hellofrom Parser to get the date/time of the location. Added -help command to provide use instructions. * Delete b02cf9e61b861d10d806dc23b24bcb3f/update/sys_properties_37b27358c3d152102b22921ed40131be.xml Remove scoped system property * Update Hello from.js Modified gs.getProperty call to use a globally scoped system property. --------- Co-authored-by: admin --- Parsers/Hello from.js | 74 ++++++++++++++----- b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt | 2 +- 2 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Parsers/Hello from.js b/Parsers/Hello from.js index 6ff0ea0..89766f5 100644 --- a/Parsers/Hello from.js +++ b/Parsers/Hello from.js @@ -1,22 +1,60 @@ /* -activation_example:hellofrom -regex:(!?hellofrom) +activation_example:!hellofrom Miami, FL +regex:(!hellofrom) flags:gmi */ -var responses = [ - ["IST","Delhi, India"], - ["PST","San Diego, USA"], - ["GMT","London, UK"], - ["JST","Tokyo, Japan"], - ["CET","Budapest, Hungary"] -]; -var randNumber=parseInt(Math.random() * responses.length); -var currentDateTime=new GlideDateTime(); -var strConvertedDateTime= new GlideScheduleDateTime(currentDateTime).convertTimeZone("UTC", responses[randNumber][0]); -var gdtConvertedDateTime = new GlideDateTime(strConvertedDateTime); - -var response="Hello from " + responses[randNumber][1] + ". Our current time is " + gdtConvertedDateTime; -//gs.info(response); - -var send_chat = new x_snc_slackerbot.Slacker().send_chat(current, response, true); +var rawInput = current.text; +// Check if the user is requesting help +if (rawInput.trim().toLowerCase() === "!hellofrom -help") { + provideHelpText(); +} else { + processHelloFromCommand(rawInput); +} + +function provideHelpText() { + var helpText = "SNDevs Slacker Hello From\n" + + "A command to get the current date and time for a specified location.\n\n" + + "Usage: `!hellofrom [location]`\n" + + "Examples:\n" + + " `!hellofrom New York, NY`\n" + + " `!hellofrom Paris, France`\n" + + " `!hellofrom Tokyo`\n\n" + + "Notes:\n" + + "• You can specify a city by itself, or include a state or country for more precision.\n" + + "• The command will return the current date and time for the specified location."; + + new x_snc_slackerbot.Slacker().send_chat(current, helpText, true); +} + +function processHelloFromCommand(input) { + var location = processLocationString(input); + // You will need to create a global system property called 'timezone.token' and obtain an API key from https://ipgeolocation.io/ to use this parser. + var apiKey = gs.getProperty("timezone.token"); + + // Build the full endpoint + var baseUrl = 'https://api.ipgeolocation.io/timezone'; + var searchUrl = baseUrl + '?location=' + encodedLocation + '&apiKey=' + apiKey; + + // Make the API request + var chatReq = new sn_ws.RESTMessageV2(); + chatReq.setEndpoint(searchUrl); + chatReq.setHttpMethod("GET"); + var chatResponse = chatReq.execute(); + var chatResponseBody = JSON.parse(chatResponse.getBody()); + var dateTimeTxt = chatResponseBody.date_time_txt; + + var response = "Hello from " + location + ". Our current date and time is " + dateTimeTxt; + + new x_snc_slackerbot.Slacker().send_chat(current, response, true); +} + +function processLocationString(input) { + // Remove "!hellofrom" and trim + var cleaned = input.replace(/^!hellofrom\s*/, '').trim(); + + // Limit to first location (up to first comma if present) + var limited = cleaned.split(',')[0].trim(); + + return limited; +} diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt index 6c283f6..f7494aa 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt +++ b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt @@ -1 +1 @@ -TxUn7YBBzC4y4yBIwhOZOYoM2cD_taHAd9fX1TpmfahkXhCExmWH7RSJrClFWpNmGsR0euG2IfjhD9Acnry5qzhv5ZQ3PC1YhbRBHHB6vZQoUPhMPrl1wEaYf0Vsw1yfaZxJOXFKflo4fi7esV0qZCjmPKTQhfQVoaUjDit1ojAKbQRPBwTIEIYTrR_XqmKf3mHetIbRioJsxPYjemSb5RVyQiD2sBkLl3Gx7qzpArG1fxreb2794G23RvMfpOhK3jz9xipYa7IaYeA29E1gTi5-_6xPF_uMzCw3NGMssDvqV2UBj4cAfG4cPQhQcHy0_D6Qo6AFvfR2d9ADjm0lq4ujS6u1vRX2lcVTdkjZAWU1F05AhdymVeNbKj0fTceGbjk4z_92tCKi8k6pPvQTHzsD8n4qdZlbb_AEItWqOrSpGlSlnOA6g7UpuWSq-e2-R2K_fMsILwm8AJqLdnnO6YWodvito7u1JGaHeH6bxHqw3hm9ykU9yRiw8rPpdononPNW80emjGAGw9IkuRsgFdyewxrbk_B5yA3R6dwccQgGMLd9eydajIHkLNAflIqyTdsBqKnbkHJWYwvflnD_pdSM2r4Jcp5rWlmn9c_He4O0B5FW-KpSZhPKyU2AaV4-osOezFMv9ca8O0s5eZIv5L0MPkW-CK58oeICX6wycgc \ No newline at end of file +OXfnAqsApch05cMfRB7DnJnPrhgcNBWxHmqCEtplh9J-0tLkq_ahRkN6ATYblVZEi2dpPa-gS8aTEn4YpeMwCQGYt9UEZjvZbU7yGt79Fm8sKCUTxnt5kPioAP4h13NbBnbSGJAhf796X8mkDhRpthIKIVKAhAkv5qYjRbohRG5HJ8mB4l3pvDIPxsIFEYph5eHyX9ej49Meb1ngqjTdRF7_e8vzqM8gjx2892GdF7gynrmIOpZDjcmJ9miakQWjIFpRGlS1UkhaiA6EeaiDukz6V0iP81OlXlbXghRxamvDwaiXjfemlDHY_R0xmSxb7uJ9eBCvgXmJkFQriOM1Uqu7SvcnfE3jvRcAw22U-snz-VTZxOBhvdsdf2ULyz_5OqsxAiGF3f39xg42lc3jqi8wGubgMvFUvdKCnpoMywoC6tGYX7eXLaAqIdQkAmuK3nXuWYbsl5Q-dM_iRs0sXQ9DK0uEUSBLz8wBjlQXXihsT8Z96NpSz6xg6YPA6ZENNuyUSak2dsOZsoCsQo7Mo-ZbBbbDBScyyU3b42OZ3O0HUx6qpIQxl8CNw0mjJyk30yzThMxOvV5-hgdfcFLWDV3VbNmv65HElwxU4Hc4J6uKHuLyBUzcnx5pXIgM4o0fktAygrdHTP0rToqxGCDsuhLlQnqfNtM0NfrrgFDQAws \ No newline at end of file From c76be30e8cf2e81f0fde9a4c36a30e4e9e23ff01 Mon Sep 17 00:00:00 2001 From: Kyle Burns Date: Tue, 15 Oct 2024 17:27:26 -0500 Subject: [PATCH 031/103] Update Hello from.js (#408) Fixed line 37. Variable was mislabeled. --- Parsers/Hello from.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Parsers/Hello from.js b/Parsers/Hello from.js index 89766f5..273a447 100644 --- a/Parsers/Hello from.js +++ b/Parsers/Hello from.js @@ -34,7 +34,7 @@ function processHelloFromCommand(input) { // Build the full endpoint var baseUrl = 'https://api.ipgeolocation.io/timezone'; - var searchUrl = baseUrl + '?location=' + encodedLocation + '&apiKey=' + apiKey; + var searchUrl = baseUrl + '?location=' + location + '&apiKey=' + apiKey; // Make the API request var chatReq = new sn_ws.RESTMessageV2(); From 0fac3f7b7f33d15d3c1713ea106ba67718ae9d58 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 15 Oct 2024 22:46:34 -0700 Subject: [PATCH 032/103] Create Reverse.js (#409) A new parser to reverse a string or to display an ascii art feature --- Parsers/Reverse.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Parsers/Reverse.js diff --git a/Parsers/Reverse.js b/Parsers/Reverse.js new file mode 100644 index 0000000..7a1c002 --- /dev/null +++ b/Parsers/Reverse.js @@ -0,0 +1,33 @@ +/* +activation_example:!reverse your string or not +regex:!reverse +flags:gmi +order:250 +stop_processing:false +*/ + +var uno = "⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀ +⡈⠀⢀⣴⣦⢶⣴⣴⣦⢶⣴⢦⣶⡴⣦⡶⣴⣦⢶⣴⣤⡀⠀⠠⡀ +⠀⠀⣿⣟⣾⠗⢀⢸⣾⢿⣽⣻⣾⠻⠝⠛⢉⡈⠛⠻⢾⣿⠀⠀⠀ +⠀⠀⣿⣾⠷⠞⣹⡿⣯⢿⡞⠋⣡⣴⣾⢿⣟⡿⣟⣷⣄⠹⠀⠀⠀ +⠀⠀⣿⣯⣤⣼⡿⣽⡛⢁⣴⣿⣻⣽⡾⣯⡿⣽⣟⣷⣻⡆⠀⠀⠀ +⠀⠀⣿⣽⣻⢯⡟⠃⣴⣿⣻⢾⣽⣳⡿⣽⣻⣽⡾⣯⣷⢿⠀⠀⠀ +⠀⠀⣿⣳⡿⠏⣠⣿⣟⣷⣻⣯⣟⣷⣿⣻⣽⣷⣻⢷⣯⣿⠀⠀⠀ +⠀⠀⣿⣽⠃⣴⣿⣳⢿⣞⡿⣿⠆⠀⠀⢠⣿⣞⣯⣿⣳⡏⠀⠀⠀ +⠀⠀⣿⠃⣼⣻⢾⣽⣯⣿⠟⠁⠀⣠⣄⣸⣿⢾⣽⣞⣯⠅⠀⠀⠀ +⠀⠀⡇⣸⣷⣻⣯⣷⣻⣿⡀⣠⠞⠹⣿⣿⢯⣿⣞⣯⠏⢸⠀⠀⠀ +⠀⠀⢁⣿⣽⣯⢿⣽⡟⢿⠗⠉⠀⢠⣿⣽⢾⣯⣟⡿⢀⣾⠀⠀⠀ +⠀⠀⢸⣟⣾⡽⣯⣿⠀⠀⠀⣠⣶⣿⣻⢾⣟⣾⡽⢀⣾⣻⠀⠀⠀ +⠀⠀⣿⣟⡷⣿⣻⣿⣤⣤⣤⣬⣿⣷⣻⣯⢿⠞⢠⣾⢯⣿⠀⠀⠀ +⠀⠀⣿⣽⣻⢷⣟⣿⣻⣟⣿⣻⣟⡾⣷⡻⠋⣰⣿⢯⣿⣽⠀⠀⠀ +⠀⠀⢻⣷⣻⢿⣾⣳⡿⣾⡽⣷⣻⡽⠛⣠⣾⢿⡽⠿⢾⣽⠀⠀⠀ +⠀⠐⡌⢳⣿⣻⡾⣽⣻⢷⣟⠏⢃⣤⣾⢿⡽⡟⣁⣤⣾⣿⠀⠀⠀ +⠀⠀⣿⢦⣈⣑⠛⠛⣋⣁⣤⡾⣿⡽⣾⣻⡏⠛⣡⣾⣟⣾⠀⠀⠀ +⠃⠀⠙⢿⣯⣟⣿⣻⣯⣿⣽⣻⣷⣟⣯⣷⣷⣶⣿⣳⡯⠋⠀⠀⠀"; + +var string = current.text.replace(/!reverse/gmi, "").split('').reverse().join(''); +if (string == '') { + new x_snc_slackerbot.Slacker().send_chat(current, uno, true); +} else { + new x_snc_slackerbot.Slacker().send_chat(current, string, true); +} From 4de45673613573e8f345dc294fa996cdb38446be Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 16 Oct 2024 00:15:22 -0700 Subject: [PATCH 033/103] Updated Reverse.js with template literals (#411) * Create Reverse.js A new parser to reverse a string or to display an ascii art feature * Update Reverse.js Updated with template literal A new parser to reverse a string or to display an ascii art feature --- Parsers/Reverse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Parsers/Reverse.js b/Parsers/Reverse.js index 7a1c002..52f7e10 100644 --- a/Parsers/Reverse.js +++ b/Parsers/Reverse.js @@ -6,7 +6,7 @@ order:250 stop_processing:false */ -var uno = "⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀ +var uno = `⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀ ⡈⠀⢀⣴⣦⢶⣴⣴⣦⢶⣴⢦⣶⡴⣦⡶⣴⣦⢶⣴⣤⡀⠀⠠⡀ ⠀⠀⣿⣟⣾⠗⢀⢸⣾⢿⣽⣻⣾⠻⠝⠛⢉⡈⠛⠻⢾⣿⠀⠀⠀ ⠀⠀⣿⣾⠷⠞⣹⡿⣯⢿⡞⠋⣡⣴⣾⢿⣟⡿⣟⣷⣄⠹⠀⠀⠀ @@ -23,7 +23,7 @@ var uno = "⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀ ⠀⠀⢻⣷⣻⢿⣾⣳⡿⣾⡽⣷⣻⡽⠛⣠⣾⢿⡽⠿⢾⣽⠀⠀⠀ ⠀⠐⡌⢳⣿⣻⡾⣽⣻⢷⣟⠏⢃⣤⣾⢿⡽⡟⣁⣤⣾⣿⠀⠀⠀ ⠀⠀⣿⢦⣈⣑⠛⠛⣋⣁⣤⡾⣿⡽⣾⣻⡏⠛⣡⣾⣟⣾⠀⠀⠀ -⠃⠀⠙⢿⣯⣟⣿⣻⣯⣿⣽⣻⣷⣟⣯⣷⣷⣶⣿⣳⡯⠋⠀⠀⠀"; +⠃⠀⠙⢿⣯⣟⣿⣻⣯⣿⣽⣻⣷⣟⣯⣷⣷⣶⣿⣳⡯⠋⠀⠀⠀`; var string = current.text.replace(/!reverse/gmi, "").split('').reverse().join(''); if (string == '') { From 32c00053b83e7828f541bea79099967fe887593f Mon Sep 17 00:00:00 2001 From: Ashoo Jindal <94731401+ashoo-jindal@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:50:34 +0530 Subject: [PATCH 034/103] Update Random Number generator.js (#412) This pull request fixes the issue no.- #380 --- Parsers/Random Number generator.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Parsers/Random Number generator.js b/Parsers/Random Number generator.js index 1573c9b..0b58d26 100644 --- a/Parsers/Random Number generator.js +++ b/Parsers/Random Number generator.js @@ -1,10 +1,10 @@ /* -activation_example: !random 1 10 -regex: !random (\d+) (\d+) -flags: gmi -order: 100 -stop_processing: true -active:false +activation_example:!random 1 10 +regex:!random (\d+) (\d+) +flags:gmi +order:100 +stop_processing:false +active:true */ var matches = current.text.match(/!random (\d+) (\d+)/); From 64407b54939859758b8f7f482094f7040254de63 Mon Sep 17 00:00:00 2001 From: UTSAV SINGHAL <119779889+UTSAVS26@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:03:15 +0530 Subject: [PATCH 035/103] Update CONTRIBUTING.md (#415) **Changes Made to `CONTRIBUTING.md`:** - Improved clarity and readability by enhancing the formatting and structure of the document. - Added detailed steps for contributing, including clear instructions for forking, branching, and submitting pull requests. - Emphasized the importance of descriptive pull request titles and adherence to quality standards. - Provided a structured overview of the repository layout and organization of code snippets. --- CONTRIBUTING.md | 72 +++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1744e2c..0e30482 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,37 +1,39 @@ # Contributing -## General requirements - -- API usage should follow the information found in the [readme](README.md#available-apisvariables-in-parsers) -- Pull request descriptions must be explicit and descriptive to what is being changed. - - Changes that are not within the scope of the description will result in the entire PR being rejected -- No updates should be made directly to the automatically generated ServiceNow folders. Updates to these files should directly to the app after being imported into a ServiceNow instance. -- Parser additions/updates must follow the [Parser template](#required-parser-template) below. -- Low effort/spam Pull Requests will be marked as spam accordingly. -- Filenames should not have special characters that are not allowed on normal file systems (eg. do not put ! in the file name). -- Parsers should not be spammy or activated unintentionally by a user in a way that would be deemed spammy. For example, a parser that is activated by a common word would likely be rejected. Instead, use a `!` notation as this is widely accepted as an activation character (eg. `!question` instead of just `question` as an activation phrase) -- We want the SlackerBot to be as close to base functionality as possible. The app (in ServiceNow) should not be updated with script includes that pertain to individual parsers, and such functionality should be entirely within a parser file so that users can choose which parsers they want to use without having extra script includes included. The only script includes that should be added to the app is if it's adding direct functionality to the bot itself (eg. the ability for the bot to parse emojis, or to send ephemeral messages, or accept blocks messages, etc.). +We appreciate your interest in contributing to the project! Please adhere to the following guidelines to ensure a smooth contribution process. + +## General Requirements + +- **API Usage**: Follow the guidelines outlined in the [README](README.md#available-apisvariables-in-parsers) regarding available APIs and variables in parsers. +- **Descriptive Pull Requests**: Ensure your pull request descriptions are explicit and clearly articulate the changes made. + - Pull requests that deviate from the scope outlined in the description may be rejected. +- **Automated Folders**: Do not make updates directly to the automatically generated ServiceNow folders. Any changes to these files should be made directly in the application after importing it into a ServiceNow instance. +- **Parser Guidelines**: Additions or updates to parsers must conform to the [required parser template](#required-parser-template) outlined below. +- **Quality Control**: Low-effort or spam pull requests will be marked as spam. +- **File Naming Conventions**: Avoid using special characters that are not allowed in standard file systems (e.g., do not include `!` in filenames). +- **Activation Phrase**: Parsers should not be inadvertently triggered in a spammy manner. For example, using common words as activation phrases may lead to rejection. Instead, use a `!` notation as an activation character (e.g., `!question` instead of just `question`). +- **Modular Functionality**: We aim to keep SlackerBot's functionality as streamlined as possible. Do not include script includes pertaining to individual parsers within the app. Any such functionality should reside entirely within the parser file, allowing users to choose which parsers to activate without unnecessary script includes. The only script includes that should be added to the app are those providing direct functionality to the bot (e.g., parsing emojis, sending ephemeral messages, or handling block messages). ## Required Parser Template -### For chat parsers +### For Chat Parsers -Eg. Run a script when a user says ____ +Example: Run a script when a user says ____ -**Notice that lines that have key:value pairs have no leading spaces before the value**. Eg. `regex:!test` is correct, while `regex: !test` is very incorrect and could cause errors +**Note**: Lines containing key-value pairs should have no leading spaces before the value. For example, `regex:!test` is correct, while `regex: !test` is incorrect and may cause errors. - Line 1 must always be `/*` -- Line 2 must always be `activation_example:` followed by a short description of how this parser would be activate -- Line 3 must always be `regex:` followed by a regex expression that validates if the parser should run. Do not include the opening and closing `/` -- Line 4 must always be `flags:` followed by the regex flags needed for line 3. If no flags are needed then leave the line as `flags:` -- *Optional*: `order:` that the parser should run (lower orders run first, null/empty orders run last). -- *Optional*: `stop_processing:` if set to `true`, will stop the parser from running any other parsers after this one. -- The file header must always end with `*/` -- The rest of the file should be the JavaScript (ES5) that does your desired parsing. +- Line 2 must always be `activation_example:` followed by a short description of how this parser would be activated. +- Line 3 must always be `regex:` followed by a regex expression that validates when the parser should run. Do not include the opening and closing `/`. +- Line 4 must always be `flags:` followed by the regex flags needed for Line 3. If no flags are required, leave the line as `flags:`. +- *Optional*: `order:` that specifies the order in which the parser should run (lower orders run first; null or empty orders run last). +- *Optional*: `stop_processing:` if set to `true`, will prevent any subsequent parsers from executing after this one. +- The file header must always end with `*/`. +- The remaining content of the file should be valid JavaScript (ES5) that implements the desired parsing logic. -Example acceptable chat parser file (From [Clap back.js](Parsers/Clap%20back.js)): +**Example of an Acceptable Chat Parser File (from [Clap back.js](Parsers/Clap%20back.js))**: -```js +```javascript /* activation_example:!clap your sentence regex:!clap @@ -42,29 +44,29 @@ stop_processing:false var sentence = current.text.replace(/!clap/gmi, "").trim().toUpperCase(); if (sentence == '') { - new x_snc_slackerbot.Slacker().send_chat(current, ':upside_down_face: gimme something to clap!', true); + new x_snc_slackerbot.Slacker().send_chat(current, ':upside_down_face: gimme something to clap!', true); } else { - new x_snc_slackerbot.Slacker().send_chat(current, sentence.split(' ').join(' :clap: '), false); + new x_snc_slackerbot.Slacker().send_chat(current, sentence.split(' ').join(' :clap: '), false); } ``` -### For reaction-added parsers +### For Reaction-Added Parsers -Eg. Run a script when a user adds a specific emoji as a reaction +Example: Run a script when a user adds a specific emoji as a reaction. -- Line 1 must always be /* -- Line 2 must always be `emoji:` followed by a comma separated list of emojis that will activate this parser -- Line 3 must always be */ -- The rest of the file should be the JavaScript (ES5) that does your desired parsing. +- Line 1 must always be `/*` +- Line 2 must always be `emoji:` followed by a comma-separated list of emojis that will activate this parser. +- Line 3 must always be `*/` +- The remaining content of the file should be valid JavaScript (ES5) that implements the desired parsing logic. -Example acceptable react parser file (From [Parrot wave starter.js](Parsers/Parrot%20wave%20starter.js) +**Example of an Acceptable Reaction Parser File (from [Parrot wave starter.js](Parsers/Parrot%20wave%20starter.js))**: -```js +```javascript /* emoji:parrotwave1 */ -for (var i = 2; i <= 7; i++){ - new x_snc_slackerbot.Slacker().send_reaction(current, 'parrotwave' + i); +for (var i = 2; i <= 7; i++) { + new x_snc_slackerbot.Slacker().send_reaction(current, 'parrotwave' + i); } ``` From 600867025d69d86442111259d8d9343c3e4946bf Mon Sep 17 00:00:00 2001 From: Isaac Vicentini Date: Fri, 18 Oct 2024 23:33:32 -0300 Subject: [PATCH 036/103] Add !quiz command (#360) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SlackerBot Event Handler: - Added logic to handle Slack interactive message responses for the quiz feature. - Implemented content-type based logic to differentiate between Default messages, Challenge requests and Quiz interactions. - Captured and processed the user selected quiz answer, comparing it against the correct answer. - Updated the bot to send a response message back to the user indicating whether the answer was correct or not. * Create a new SN Quiz.js - Implemented functionality to capture the quiz topic from the Slack command using regex. - Integrated OpenAI API to generate multiple-choice quiz questions dynamically based on the quiz topic provided. - Processed and formatted the AI response into structured JSON, containing the question, options, correct answer, and explanation. - Enhanced Slack integration using Block Kit to present the quiz question with interactive buttons for each option. * Scripted Rest API: - Updated the interaction script to validate user selections and provide feedback based on the correctness of the response. - Added dynamic button styling (primary/danger) to visually indicate correct and incorrect answers. - Improved feedback messages with detailed explanations for correct answers. - Integrated the update_chat method to ensure real-time message updates in Slack with button styling and quiz results. Slacker Script Include: - Enhanced maintainability by centralizing the Slack message update logic in a dedicated Script Include function. * Update - Create a new SN Quiz.js - Added error handling to manage unexpected responses from the OpenAI API. - Improved user interaction by formatting the question and answers using Slack Block Kit. - Ensured that correct answers are validated and passed along with the user selection for feedback. * Update Create a new SN Quiz.js Initial comments inserted * The API - Event Handler has been updated with some adjustments and improvements: - Fix: The Script Include Slacker() is no longer instantiated twice. - The block only accepts interaction if the user interacting with the block is the same user who sent the command. - All other blocks automatically turn red after the user selects the correct option. - Now the bot briefly explains why the option is correct. - A note has been added so the user knows that only the person who sent the command can answer the question. * Update Create a new SN Quiz.js The script has been updated with some adjustments and improvements: - The model used in the OpenAI integration has been changed to gpt-4o. - The ID of the user who asked the question is being retrieved and sent for interaction validation. - A greeting was added to the quiz so that the person who asked the question knows it is directed at them. - A note has been added to inform the user that only the person who sent the command can answer the quiz. * A new function has been created to validate whether the bot can interact in the channel. The function checks if the original message was sent by a user and if the interaction is of the type “block_actions” - Necessary for setting up the quiz. The function checks if the interaction contains a bot_id, and if it does, two things are validated: 1. If the type of interaction is “message_changed” - Necessary for the bot to update the styles of the blocks (colors). 2. If the thread was started by a user - Necessary for the bot to respond to the correct question. This way, it does not get stuck in a loop responding to itself. If the interaction does not have a bot_id, then the message can be sent. --------- Co-authored-by: admin Co-authored-by: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> --- Parsers/Create a new SN Quiz.js | 114 +++++++++++++++ b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt | 2 +- ...clude_b2c246ae1b861d10d806dc23b24bcbac.xml | 42 ++++-- ...ation_bbcb42a61bc61d10d806dc23b24bcbd2.xml | 135 +++++++++++++++--- 4 files changed, 268 insertions(+), 25 deletions(-) create mode 100644 Parsers/Create a new SN Quiz.js diff --git a/Parsers/Create a new SN Quiz.js b/Parsers/Create a new SN Quiz.js new file mode 100644 index 0000000..f4ee974 --- /dev/null +++ b/Parsers/Create a new SN Quiz.js @@ -0,0 +1,114 @@ +/* +activation_example:!quiz itsm +regex:!quiz\s+(.+) +flags:gmi +*/ + +(function(current) { + var slacker = new x_snc_slackerbot.Slacker(); + + // Capture the text and extract the quiz topic using regex + var text = current.text; + var match = text.match(/!quiz\s+(.+)/i); + + if (!match) { + slacker.send_chat(current, "Please provide a valid ServiceNow quiz topic, e.g., !quiz ITSM.", false); + return; + } + + var quizTopic = match[1].trim(); + var originalUserId = current.user.user_id; + + try { + // Openai Integration - Generate Quiz + var apiKey = gs.getProperty("openai.key"); + + var restMessage = new sn_ws.RESTMessageV2(); + restMessage.setEndpoint('https://api.openai.com/v1/chat/completions'); + restMessage.setHttpMethod('POST'); + restMessage.setRequestHeader('Authorization', 'Bearer ' + apiKey); + restMessage.setRequestHeader('Content-Type', 'application/json'); + + var requestBody = { + "model": "gpt-4o", + "messages": [{ + "role": "system", + "content": "You are an assistant that creates structured multiple-choice quiz questions about ServiceNow topics. Return the question and answers in JSON format." + }, + { + "role": "user", + "content": "Please generate one multiple-choice quiz question on the topic of " + quizTopic + ". The answers should not include any prefixes like 'A)', '1.', etc. Just provide the plain answer text. Return the result in the following JSON format:\n{\n \"question\": \"\",\n \"answers\": [\"option 1\", \"option 2\", \"option 3\", \"option 4\"],\n \"correct\": \"\",\n \"explanation\": \"\"\n}" + } + ], + "max_tokens": 200 + }; + + + restMessage.setRequestBody(JSON.stringify(requestBody)); + var response = restMessage.execute(); + + if (response.getStatusCode() !== 200) { + throw new Error('Received non-200 response from OpenAI: ' + response.getStatusCode()); + } + + var responseBody = response.getBody(); + var jsonResponse = JSON.parse(responseBody); + + if (!jsonResponse.choices || !jsonResponse.choices[0].message || !jsonResponse.choices[0].message.content) { + throw new Error('Unexpected response format from OpenAI'); + } + + var quizData = jsonResponse.choices[0].message.content; + var quizQuestion = JSON.parse(quizData); + + // Find the correct answer + var correctOptionIndex = ""; + quizQuestion.answers.forEach(function(answer, index) { + if (answer === quizQuestion.correct) { + correctOptionIndex = "option_" + (index + 1); + } + }); + + // Prepare Slack Block Kit for the quiz question and answers + var optionLetters = ['A', 'B', 'C', 'D']; + var blocks = [{ + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Hello, " + current.user.name + "! Test your ServiceNow skills and have fun! \n\n" + + "*Question:* " + quizQuestion.question + "\n\n" + + optionLetters[0] + ") " + quizQuestion.answers[0] + "\n" + + optionLetters[1] + ") " + quizQuestion.answers[1] + "\n" + + optionLetters[2] + ") " + quizQuestion.answers[2] + "\n" + + optionLetters[3] + ") " + quizQuestion.answers[3] + "\n\n" + + "_*Note:* Only the person who initiated the quiz can answer._" + } + }, + { + "type": "actions", + "elements": quizQuestion.answers.map(function(answer, index) { + return { + "type": "button", + "text": { + "type": "plain_text", + "text": optionLetters[index] + }, + + "value": "option_" + (index + 1) + "|" + correctOptionIndex + "|" + originalUserId + "|" + quizQuestion.explanation, + "action_id": "quiz_answer_" + (index + 1) + }; + }) + } + ]; + + // Send Slack message - Quiz + slacker.send_chat(current, { + "blocks": blocks + }, false); + + } catch (error) { + gs.error('[SLACKER - QUIZ] Error generating quiz: ' + error.message); + slacker.send_chat(current, "Sorry, there was an issue generating the quiz. Please try again later.", false); + } + +})(current); diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt index f7494aa..3fae1ce 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt +++ b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt @@ -1 +1 @@ -OXfnAqsApch05cMfRB7DnJnPrhgcNBWxHmqCEtplh9J-0tLkq_ahRkN6ATYblVZEi2dpPa-gS8aTEn4YpeMwCQGYt9UEZjvZbU7yGt79Fm8sKCUTxnt5kPioAP4h13NbBnbSGJAhf796X8mkDhRpthIKIVKAhAkv5qYjRbohRG5HJ8mB4l3pvDIPxsIFEYph5eHyX9ej49Meb1ngqjTdRF7_e8vzqM8gjx2892GdF7gynrmIOpZDjcmJ9miakQWjIFpRGlS1UkhaiA6EeaiDukz6V0iP81OlXlbXghRxamvDwaiXjfemlDHY_R0xmSxb7uJ9eBCvgXmJkFQriOM1Uqu7SvcnfE3jvRcAw22U-snz-VTZxOBhvdsdf2ULyz_5OqsxAiGF3f39xg42lc3jqi8wGubgMvFUvdKCnpoMywoC6tGYX7eXLaAqIdQkAmuK3nXuWYbsl5Q-dM_iRs0sXQ9DK0uEUSBLz8wBjlQXXihsT8Z96NpSz6xg6YPA6ZENNuyUSak2dsOZsoCsQo7Mo-ZbBbbDBScyyU3b42OZ3O0HUx6qpIQxl8CNw0mjJyk30yzThMxOvV5-hgdfcFLWDV3VbNmv65HElwxU4Hc4J6uKHuLyBUzcnx5pXIgM4o0fktAygrdHTP0rToqxGCDsuhLlQnqfNtM0NfrrgFDQAws \ No newline at end of file +1Xbk9WxmheTaW0AgaPLvwbV3zWsmHQtuzDv3BzXUTOXkkeTOT3dWqOrS7c8vRhhL57_VWPRyJeeP5HfoSHF21CYx49uZ6ejBWpfI8oo79_rSECBBj-o5imozu6nwjoIoqchvEwga8PlPmyZBkslRcpawEqlirCLUNQh0gPJdYMPsSOCAJbjOIWXl8qdsyR_c5fhsNb0VxlciIVbYn6KBZnC_-QzBu1Z7E0lSqeISpirHNr-Y_Et56ZIL-fIAl5Oh-L-WARn_-Ei8lgvy-zs1mIvLyy9rOsKirmI5jzRYCAfO5lvltsjGDfJnCRAr4aRHE5w5-lSmLSgX6mR4EBTc8FkryIbfOHZXsp3HSSJGLVpNYn7n77O2V-F9cNrOidCpmWlXVANq9GpgCmJoeO3TrCmJVwmyuF_3qok2zuxsKR2dCSHVjr2THKK_CmyuQIeaMtUGIxSbw5ngkRVcz3pCIfMvCnfjNLHwPf2EOQgNC8bHkYBOylKsnvnOG9cPiquKE_aS_9lkCR0H_JLQsOGDndDBNOVRqcONO8p1JsFrkP5ihhqAmNjAz8jrRi-cUfyynNVH4FticFbBrNm7pw5aYOq1nwok0EN7SCwNX-LfoUh8uk4HNrPzQvY1Pu9IXZnFpAaTtcK-fg_sAOMVs55itBxzQOVZQjbSC2sORre2P5U \ No newline at end of file diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_include_b2c246ae1b861d10d806dc23b24bcbac.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_include_b2c246ae1b861d10d806dc23b24bcbac.xml index 2a1b773..50d2215 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_include_b2c246ae1b861d10d806dc23b24bcbac.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_include_b2c246ae1b861d10d806dc23b24bcbac.xml @@ -26,10 +26,10 @@ Slacker.prototype = { } } - if (slackoff_user.getValue('name_updated') < gs.daysAgoStart(0)) { - this.get_user_info(payload_user, userSysID); //Update user info once per day, in case of name change. - } - + if (slackoff_user.getValue('name_updated') < gs.daysAgoStart(0)) { + this.get_user_info(payload_user, userSysID); //Update user info once per day, in case of name change. + } + return userSysID; }, @@ -73,6 +73,32 @@ Slacker.prototype = { return rm.execute(); }, + /** + * Updates a message on Slack + * @example + * var payload = { + * "channel": "D0XXXT13XXX", // Channel ID + * "ts": 1728146070.000000, // Message timestamp + * "blocks": blocks, // Optional if the message is block + * "text": message // If the message is text + * }; + * new x_snc_slackerbot.Slacker().update_chat(payload); + * @param {object} payload Object containing the payload to be sent to the Slack API + * @returns {RESTResponseV2} RESTResponseV2 object containing response payload, and headers + */ + update_chat: function(payload) { + var rmUpdateMessage = new sn_ws.RESTMessageV2(); + rmUpdateMessage.setEndpoint('https://slack.com/api/chat.update'); + rmUpdateMessage.setHttpMethod('POST'); + rmUpdateMessage.setRequestHeader('Authorization', 'Bearer ' + gs.getProperty('x_snc_slackerbot.SlackerBot.token')); + rmUpdateMessage.setRequestHeader('Content-Type', 'application/json'); + rmUpdateMessage.setRequestBody(JSON.stringify(payload)); + + var response = rmUpdateMessage.execute(); + var responseBody = response.getBody(); + return responseBody; + }, + send_delete: function(channel, ts) { var rm = new sn_ws.RESTMessageV2(); rm.setHttpMethod('POST'); @@ -109,7 +135,7 @@ Slacker.prototype = { var grupdate = new GlideRecord('x_snc_slackerbot_user'); grupdate.get(record_id); grupdate.setValue('name', response_body.user.real_name); - grupdate.setValue('name_updated', new GlideDateTime()); + grupdate.setValue('name_updated', new GlideDateTime()); grupdate.update(); return true; } else { @@ -160,13 +186,13 @@ Slacker.prototype = { earl.duque 2022-09-23 06:06:00 b2c246ae1b861d10d806dc23b24bcbac - 3 + 7 Slacker b02cf9e61b861d10d806dc23b24bcb3f read b02cf9e61b861d10d806dc23b24bcb3f sys_script_include_b2c246ae1b861d10d806dc23b24bcbac - SapphicFire - 2023-11-04 10:48:44 + admin + 2024-10-05 17:42:35 diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ws_operation_bbcb42a61bc61d10d806dc23b24bcbd2.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ws_operation_bbcb42a61bc61d10d806dc23b24bcbd2.xml index d7dd28b..65fcd60 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ws_operation_bbcb42a61bc61d10d806dc23b24bcbd2.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ws_operation_bbcb42a61bc61d10d806dc23b24bcbd2.xml @@ -1,26 +1,126 @@ true - application/json,application/xml,text/xml - false + application/json,application/xml,text/xml,application/x-www-form-urlencoded + true cf9d01d3e73003009d6247e603f6a990 POST Event - /api/x_snc_slackerbot/slackerbot_event_handler @@ -36,11 +136,14 @@ earl.duque 2022-09-23 06:36:30 bbcb42a61bc61d10d806dc23b24bcbd2 + 105 Event b02cf9e61b861d10d806dc23b24bcb3f b02cf9e61b861d10d806dc23b24bcb3f sys_ws_operation_bbcb42a61bc61d10d806dc23b24bcbd2 + admin + 2024-10-11 00:48:14 1fabce661bc61d10d806dc23b24bcbd6 From b42ae6245a1b47747aa60212a8ce1a1f6e49fa66 Mon Sep 17 00:00:00 2001 From: wiz0floyd Date: Fri, 18 Oct 2024 23:04:23 -0400 Subject: [PATCH 037/103] Adds trim_value=true dictionary attribute to Flags, Regex, and Emoji fields on the Parser table to prevent errors. (#397) Co-authored-by: admin Co-authored-by: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> --- b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt | 2 +- .../dictionary/x_snc_slackerbot_parser.xml | 12 ++++++------ ...ys_dictionary_x_snc_slackerbot_parser_emoji.xml | 14 ++++++-------- ...ys_dictionary_x_snc_slackerbot_parser_flags.xml | 4 +++- ...ys_dictionary_x_snc_slackerbot_parser_regex.xml | 4 +++- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt index 3fae1ce..e8f0354 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt +++ b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt @@ -1 +1 @@ -1Xbk9WxmheTaW0AgaPLvwbV3zWsmHQtuzDv3BzXUTOXkkeTOT3dWqOrS7c8vRhhL57_VWPRyJeeP5HfoSHF21CYx49uZ6ejBWpfI8oo79_rSECBBj-o5imozu6nwjoIoqchvEwga8PlPmyZBkslRcpawEqlirCLUNQh0gPJdYMPsSOCAJbjOIWXl8qdsyR_c5fhsNb0VxlciIVbYn6KBZnC_-QzBu1Z7E0lSqeISpirHNr-Y_Et56ZIL-fIAl5Oh-L-WARn_-Ei8lgvy-zs1mIvLyy9rOsKirmI5jzRYCAfO5lvltsjGDfJnCRAr4aRHE5w5-lSmLSgX6mR4EBTc8FkryIbfOHZXsp3HSSJGLVpNYn7n77O2V-F9cNrOidCpmWlXVANq9GpgCmJoeO3TrCmJVwmyuF_3qok2zuxsKR2dCSHVjr2THKK_CmyuQIeaMtUGIxSbw5ngkRVcz3pCIfMvCnfjNLHwPf2EOQgNC8bHkYBOylKsnvnOG9cPiquKE_aS_9lkCR0H_JLQsOGDndDBNOVRqcONO8p1JsFrkP5ihhqAmNjAz8jrRi-cUfyynNVH4FticFbBrNm7pw5aYOq1nwok0EN7SCwNX-LfoUh8uk4HNrPzQvY1Pu9IXZnFpAaTtcK-fg_sAOMVs55itBxzQOVZQjbSC2sORre2P5U \ No newline at end of file +xq9ZwXwxj-LQZscVtqBmLSrZuGf_Q2oGZeXqw9RlyMvbCJKoCxdk9bya90x3WFbGbMisVjO2PuDoCZtBzEVfOQWWEMynig8CKFb5Ntmxo_8QHpxll6_mbnHi7r1hK4YAENeehyK39yQw2kw3lTF2Sa6EJV-5XlLbKTLhzJJO2-x1CDCu_7pRZ_wY7aMyZeq6WS74Ki4YhVXnsGHngFiEbix6quageR5toLquzGYVvmO2ZxW4WQhlK3IToa0lswOkFKCI3FAN53GDZZC9Q7O3qROvsa8hrUzwp-Mt7ETSL24_LhRWZPq23Mr3K7Hzf8_RjJ9SaQ7CHJ2r4JHRkp_0JBnWaICy7y41zeeDvCxojEnARkNS-E-JAnGRrg4Kbnoj9oDHYIuXoSf2UV7T3tDHf6kLlVBTWvihZroiatst86ZkpLAFUKRN-8he2wOlC-6gb_dslbAKWS2vRSRqL8WE7azdM5WimPzFKCKAQQCKGMSw3e99beVxFmSur5UVgQ3nAGFUr24pG6Si1OYp2pIyg1dkBriRyycmQG1tKRDL7w8YADy401FJky7i8dhTloHgxZLBHM09oJeFetyC0-MpZAcXO5Uklr7QX3bJYeGF6IAZ3JFRNDkBV9du_-I1AeWXZU3lngkB3YjzQ9VynoD7ZQSaDarjI_CEI3olULrZZ3U \ No newline at end of file diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_parser.xml b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_parser.xml index 3eda189..f0ea188 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_parser.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_parser.xml @@ -1,14 +1,14 @@ - + + - - - - + + + + - diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_emoji.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_emoji.xml index db46120..34911b7 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_emoji.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_emoji.xml @@ -2,11 +2,10 @@ true false - false - edge_encryption_enabled=true + edge_encryption_enabled=true,trim_value=true false - 0 + Emoji @@ -25,6 +24,7 @@ emoji false + false string @@ -42,21 +42,18 @@ - false false sys_dictionary earl.duque 2022-10-01 06:29:44 - c2379b45db565510791d8f8d1396195b - 0 Emoji b02cf9e61b861d10d806dc23b24bcb3f b02cf9e61b861d10d806dc23b24bcb3f sys_dictionary_x_snc_slackerbot_parser_emoji - earl.duque - 2022-10-01 06:29:44 + admin + 2024-10-10 19:02:14 false false false @@ -64,6 +61,7 @@ false simple false + script false diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_flags.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_flags.xml index 5bb4c18..f9bc68d 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_flags.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_flags.xml @@ -2,7 +2,7 @@ true false - + trim_value=true false b02cf9e61b861d10d806dc23b24bcb3f sys_dictionary_x_snc_slackerbot_parser_flags + admin + 2024-10-10 19:02:27 false false false diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_regex.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_regex.xml index e7e54c2..0efce05 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_regex.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_parser_regex.xml @@ -2,7 +2,7 @@ true false - + trim_value=true false b02cf9e61b861d10d806dc23b24bcb3f sys_dictionary_x_snc_slackerbot_parser_regex + admin + 2024-10-10 19:02:23 false false false From dbb9c3f59002ff5118e6496f3c87fddfeece7866 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Date: Sun, 20 Oct 2024 22:09:12 +0530 Subject: [PATCH 038/103] update 3rd parameter to false (#419) --- Parsers/Reverse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Parsers/Reverse.js b/Parsers/Reverse.js index 52f7e10..2bce7c7 100644 --- a/Parsers/Reverse.js +++ b/Parsers/Reverse.js @@ -27,7 +27,7 @@ var uno = `⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀ var string = current.text.replace(/!reverse/gmi, "").split('').reverse().join(''); if (string == '') { - new x_snc_slackerbot.Slacker().send_chat(current, uno, true); + new x_snc_slackerbot.Slacker().send_chat(current, uno, false); } else { - new x_snc_slackerbot.Slacker().send_chat(current, string, true); + new x_snc_slackerbot.Slacker().send_chat(current, string, false); } From 385a5db2215fd84efe2d3b0e15f151687880afb7 Mon Sep 17 00:00:00 2001 From: Sai Charan Koratala Date: Sun, 20 Oct 2024 22:09:57 +0530 Subject: [PATCH 039/103] Create Highlight Maintatiners.js (#420) Highlight maintainers is a tribute to the maintainers for their valuable time. !maintainers will give a link to the Hacktoberfest page to where the maintainers section is present so that everyone can take a look at the maintainers who have been spending their valuable time to review the pull requests. --- Parsers/Highlight Maintatiners.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Parsers/Highlight Maintatiners.js diff --git a/Parsers/Highlight Maintatiners.js b/Parsers/Highlight Maintatiners.js new file mode 100644 index 0000000..59efa38 --- /dev/null +++ b/Parsers/Highlight Maintatiners.js @@ -0,0 +1,12 @@ +/* +activation_example:!maintainers +regex:!hackmaintainers|!hacktobermaintainers|!maintainershacktoberfest +flags:gmi +*/ + +(function(){ + + var strMessage = 'Navigate to `https://github.com/ServiceNowDevProgram/Hacktoberfest?tab=readme-ov-file#reviewers` to checkout the Hacktoberfest crew who are maintaining the hacktoberfest projects ' + var send_chat = new x_snc_slackerbot.Slacker().send_chat(current, strMessage, false); + +})(); From 8d787071cf3acc06d8f25724767fb94a5d3737f7 Mon Sep 17 00:00:00 2001 From: Thejas R <97252005+thejasr110@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:03:27 +0530 Subject: [PATCH 040/103] Add Word Dictionary (#424) This parser provides definition for the first word. ->provides meaningful message when null, numeric or special character's are entered. ->provides message when there is no definition found for the given word. ->it only considers first word from the entered sentences and ignores the rest. --- Parsers/Word Dictionary.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Parsers/Word Dictionary.js diff --git a/Parsers/Word Dictionary.js b/Parsers/Word Dictionary.js new file mode 100644 index 0000000..4ca4e30 --- /dev/null +++ b/Parsers/Word Dictionary.js @@ -0,0 +1,37 @@ +/* +activation_example:!dictionary type a word +regex:!dictionary +flags:gmi +order:200 +stop_processing:false +*/ + +var word = current.text.replace(/!dictionary/gmi, "").trim(); +if (word == '') { + new x_snc_slackerbot.Slacker().send_chat(current, 'Please type a word', false); +} else { + var regex = /[0-9!@#$%^&*(),.?":{}|<>]/; + if (regex.test(word)) { + new x_snc_slackerbot.Slacker().send_chat(current, 'Please type a word with only characters', false); + } else { + var wordsArray = word.split(" "); + var firstWord = wordsArray[0]; + + var dictionary = new sn_ws.RESTMessageV2(); + dictionary.setEndpoint('https://api.dictionaryapi.dev/api/v2/entries/en/' + firstWord); + dictionary.setHttpMethod("GET"); + dictionary.setRequestHeader("Accept", "application/json"); + var response = dictionary.execute(); + var responseBody = response.getBody(); + var statuscode = response.getStatusCode(); + var responseJson = JSON.parse(responseBody); + var sendsentence = ""; + if (statuscode == 200) { + var meaning = responseJson[0].meanings[0].definitions[0].definition; + sendsentence = firstWord + ': ' + meaning; + } else { + sendsentence = "Sorry pal, we couldn't find definitions for the word you were looking for."; + } + new x_snc_slackerbot.Slacker().send_chat(current, sendsentence, false); + } +} \ No newline at end of file From 06cfe5d67c70d5c178950180f237f2ec3a7d9f85 Mon Sep 17 00:00:00 2001 From: Astrid Sapphire <59789839+SapphicFire@users.noreply.github.com> Date: Sat, 26 Oct 2024 02:35:26 +1000 Subject: [PATCH 041/103] Introduce Interaction support to Slacker (#432) * feat: introduce interactivity support added: Interaction table added: Payload type to Payload to discern events and Interactivity added: New endpoint to insert Interactions updated: Filters on payload table BRs updated: Updated repo event endpoint to handle Interactions * Add Interactions path for workflow change: Add interactions path test: Change Deployment repository * feat: Migrate the quiz functionality to an Interaction added: first interaction handler and path * Interaction support (#11) (#12) * feat: introduce interactivity support added: Interaction table added: Payload type to Payload to discern events and Interactivity added: New endpoint to insert Interactions updated: Filters on payload table BRs updated: Updated repo event endpoint to handle Interactions * Add Interactions path for workflow change: Add interactions path test: Change Deployment repository * feat: Migrate the quiz functionality to an Interaction added: first interaction handler and path * tweak: Update path * tweak: Change directory name * fix: Update variable name * fix: url variable * Delete Interactions/Handle an SN quiz.js * tweak: Repoint to correct repo --- .github/workflows/main.yml | 1 + Interaction/Handle an SN quiz.js | 69 ++++++++ ..._x_snc_slackerbot_payload_payload_type.xml | 57 ++++++ b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt | 2 +- .../x_snc_slackerbot_interaction.xml | 9 + .../dictionary/x_snc_slackerbot_payload.xml | 8 +- ...odule_82da0f3bc3d15a5055bdd523e40131ae.xml | 43 +++++ ...bject_ee0be417c3dd165055bdd523e401314f.xml | 37 ++++ ...slackerbot_interaction_action_id_regex.xml | 74 ++++++++ ...ry_x_snc_slackerbot_interaction_active.xml | 74 ++++++++ ...snc_slackerbot_interaction_description.xml | 74 ++++++++ ...nary_x_snc_slackerbot_interaction_null.xml | 69 ++++++++ ...slackerbot_interaction_related_parsers.xml | 74 ++++++++ ...ry_x_snc_slackerbot_interaction_script.xml | 74 ++++++++ ..._x_snc_slackerbot_payload_payload_type.xml | 74 ++++++++ ...ckerbot_interaction_action_id_regex_en.xml | 26 +++ ...x_snc_slackerbot_interaction_active_en.xml | 26 +++ ..._slackerbot_interaction_description_en.xml | 26 +++ ...ckerbot_interaction_related_parsers_en.xml | 26 +++ ...x_snc_slackerbot_interaction_script_en.xml | 26 +++ ...snc_slackerbot_payload_payload_type_en.xml | 26 +++ ...cript_36471c93c35d165055bdd523e40131ab.xml | 86 +++++++++ ...cript_5a6efbf22f9ad11081e256f62799b69f.xml | 18 +- ...cript_dbdd422a1bc61d10d806dc23b24bcb47.xml | 23 ++- ...cript_e6781b85db565510791d8f8d13961907.xml | 21 ++- ...clude_b2c246ae1b861d10d806dc23b24bcbac.xml | 21 ++- ...y_acl_1acb8bbbc3d15a5055bdd523e40131c9.xml | 29 +++ ...y_acl_28ab47bbc3d15a5055bdd523e4013159.xml | 29 +++ ...y_acl_3b5b8f7bc3d15a5055bdd523e4013148.xml | 29 +++ ...y_acl_eceb4fbbc3d15a5055bdd523e40131d0.xml | 29 +++ ..._role_16cb8bbbc3d15a5055bdd523e40131ca.xml | 18 ++ ..._role_24ab47bbc3d15a5055bdd523e401315a.xml | 18 ++ ..._role_64eb4fbbc3d15a5055bdd523e40131d1.xml | 18 ++ ..._role_686b0f7bc3d15a5055bdd523e40131f7.xml | 18 ++ ..._ui_list_x_snc_slackerbot_payload_null.xml | 79 +++++---- ...ction_1a9515821b5251105218fcc6cc4bcba6.xml | 59 ++++++- ...ction_7e0b2417c3dd165055bdd523e401316f.xml | 127 +++++++++++++ ...ction_ae3517c1db565510791d8f8d13961949.xml | 71 -------- ...ation_51ff0b8c1b1e1510d806dc23b24bcb5c.xml | 167 ++++++++++++++---- ...ation_bbcb42a61bc61d10d806dc23b24bcbd2.xml | 151 ++++------------ ...ation_d7f9d1dec3d99e1055bdd523e4013194.xml | 61 +++++++ 41 files changed, 1686 insertions(+), 281 deletions(-) create mode 100644 Interaction/Handle an SN quiz.js create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/author_elective_update/sys_choice_x_snc_slackerbot_payload_payload_type.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_interaction.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_app_module_82da0f3bc3d15a5055bdd523e40131ae.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_db_object_ee0be417c3dd165055bdd523e401314f.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_action_id_regex.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_active.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_description.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_null.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_related_parsers.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_script.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_payload_payload_type.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_action_id_regex_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_active_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_description_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_related_parsers_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_script_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_payload_payload_type_en.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_36471c93c35d165055bdd523e40131ab.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_1acb8bbbc3d15a5055bdd523e40131c9.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_28ab47bbc3d15a5055bdd523e4013159.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_3b5b8f7bc3d15a5055bdd523e4013148.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_eceb4fbbc3d15a5055bdd523e40131d0.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_role_16cb8bbbc3d15a5055bdd523e40131ca.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_role_24ab47bbc3d15a5055bdd523e401315a.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_role_64eb4fbbc3d15a5055bdd523e40131d1.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_security_acl_role_686b0f7bc3d15a5055bdd523e40131f7.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ui_section_7e0b2417c3dd165055bdd523e401316f.xml delete mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ui_section_ae3517c1db565510791d8f8d13961949.xml create mode 100644 b02cf9e61b861d10d806dc23b24bcb3f/update/sys_ws_operation_d7f9d1dec3d99e1055bdd523e4013194.xml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e5c25d..f66979a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,6 +8,7 @@ on: push: paths: - Parsers/** + - Interaction/** # branches: [ "main" ] # pull_request: # branches: [ "main" ] diff --git a/Interaction/Handle an SN quiz.js b/Interaction/Handle an SN quiz.js new file mode 100644 index 0000000..e3300bd --- /dev/null +++ b/Interaction/Handle an SN quiz.js @@ -0,0 +1,69 @@ +/* +action_id_regex:quiz_answer_ +parsers:Create a new SN Quiz +*/ + +(function (current) { + var slackerProvider = new x_snc_slackerbot.Slacker(); + var interactionPayload = JSON.parse(current.getValue('payload')); + + // Get selected option, correct option, the user ID that initiated the quiz, and explanation + var action = interactionPayload.actions[0]; + var selectedOption = action.value; + var parts = selectedOption.split("|"); + var userSelection = parts[0]; + var correctOption = parts[1]; + var originalUserId = parts[2]; + var explanation = parts[3]; + + // Verify if the interacting user is the same as the original user + if (interactionPayload.user.id !== originalUserId) return; + + // Apply styles to each button based on whether it was selected and whether it's correct + var blocks = interactionPayload.message.blocks; + var correctIndex = parseInt(correctOption.split('_')[1]) - 1; + + blocks[1].elements.forEach(function (button, index) { + if (userSelection === correctOption) { + button.style = (index === correctIndex) ? "primary" : "danger"; + } else { + if (button.value === selectedOption) { + button.style = "danger"; + } + } + }); + + var updateMessagePayload = { + "channel": interactionPayload.channel.id, + "ts": interactionPayload.message.ts, + "blocks": blocks, + "text": "UpdatingQuiz" + }; + + var responseMessageUpdated = slackerProvider.update_chat(updateMessagePayload); + + // Validate User Answer and send appropriate feedback + var current = { + "text": interactionPayload.message.blocks[0].text.text, + "ts": interactionPayload.message.ts, + "thread_ts": interactionPayload.container.message_ts, + "channel": interactionPayload.channel.id, + "user": { + "user_id": interactionPayload.user.id, + "name": interactionPayload.user.name + } + }; + + var questionText = interactionPayload.message.blocks[0].text.text; + var textLines = questionText.split("\n"); + var correctAnswerText = textLines[correctIndex + 4].trim(); + var correctAnswer = correctAnswerText.replace(/^[A-D]\)\s*/, ''); + + if (userSelection === correctOption) { + var correctMessage = "Well done! The correct answer is:\n*" + correctAnswer + "*\n\n" + explanation; + slackerProvider.send_chat(current, correctMessage, false); + } else { + var incorrectMessage = "Oops, not quite! Try Again."; + slackerProvider.send_chat(current, incorrectMessage, false); + } +})(current); diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/author_elective_update/sys_choice_x_snc_slackerbot_payload_payload_type.xml b/b02cf9e61b861d10d806dc23b24bcb3f/author_elective_update/sys_choice_x_snc_slackerbot_payload_payload_type.xml new file mode 100644 index 0000000..89714ad --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/author_elective_update/sys_choice_x_snc_slackerbot_payload_payload_type.xml @@ -0,0 +1,57 @@ + + + + payload_type + x_snc_slackerbot_payload + sys_choice_set + asteroid + 2024-10-20 08:14:42 + 0 + payload_type + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_choice_x_snc_slackerbot_payload_payload_type + asteroid + 2024-10-20 08:14:42 + + + + payload_type + + false + + en + x_snc_slackerbot_payload + 1 + + asteroid + 2024-10-20 08:14:42 + global + / + 0 + asteroid + 2024-10-20 08:14:42 + event + + + + payload_type + + false + + en + x_snc_slackerbot_payload + 2 + + asteroid + 2024-10-20 08:15:43 + global + / + 0 + asteroid + 2024-10-20 08:15:43 + interaction + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt index e8f0354..08e028b 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt +++ b/b02cf9e61b861d10d806dc23b24bcb3f/checksum.txt @@ -1 +1 @@ -xq9ZwXwxj-LQZscVtqBmLSrZuGf_Q2oGZeXqw9RlyMvbCJKoCxdk9bya90x3WFbGbMisVjO2PuDoCZtBzEVfOQWWEMynig8CKFb5Ntmxo_8QHpxll6_mbnHi7r1hK4YAENeehyK39yQw2kw3lTF2Sa6EJV-5XlLbKTLhzJJO2-x1CDCu_7pRZ_wY7aMyZeq6WS74Ki4YhVXnsGHngFiEbix6quageR5toLquzGYVvmO2ZxW4WQhlK3IToa0lswOkFKCI3FAN53GDZZC9Q7O3qROvsa8hrUzwp-Mt7ETSL24_LhRWZPq23Mr3K7Hzf8_RjJ9SaQ7CHJ2r4JHRkp_0JBnWaICy7y41zeeDvCxojEnARkNS-E-JAnGRrg4Kbnoj9oDHYIuXoSf2UV7T3tDHf6kLlVBTWvihZroiatst86ZkpLAFUKRN-8he2wOlC-6gb_dslbAKWS2vRSRqL8WE7azdM5WimPzFKCKAQQCKGMSw3e99beVxFmSur5UVgQ3nAGFUr24pG6Si1OYp2pIyg1dkBriRyycmQG1tKRDL7w8YADy401FJky7i8dhTloHgxZLBHM09oJeFetyC0-MpZAcXO5Uklr7QX3bJYeGF6IAZ3JFRNDkBV9du_-I1AeWXZU3lngkB3YjzQ9VynoD7ZQSaDarjI_CEI3olULrZZ3U \ No newline at end of file +X1NRvjwxs0od9dl7o8x8TJKGDW-1XcvrtaWNPJtN8j7xtRw17VMdAn_h3-53esZH05QfV-tD9S6cbLBezbHzOlkyDDGmvWoJGQNi571Y6tIII0MBhyjKBxCeIq-cpx0jXyNZ_yer-jbs4VsLDuUc45qJj0XS8w4T7KpHUpaZhAgenqgQDeBkP-i_tnFT8zBWk3Bx0MNmfca4yhS8NnDkn-CiJ-KFA44guyfnLDQc3f2AIMmK5L_tfkJskeAzhHlVWVXXfV59MWByMS6XWjxmKRjkr8OhEi-agClzlza1Ka8PHpAOTqSgTkm4tMw29ND7Fr4jr8bGYtpuSpLd6WiurWHSDo8pCCpm65_EQTHCezqgokX0mWU4pHhMSJcIWc5J-CLDCf93gQnlM6qlfKw8LyyExPpQjGlfJrCHarh5YxjZbd_qFNsFt4AcRy0DQNbd9m1AGspNl1QuH7SDjw3oCysmaNZa3Tk1hQ2T4uzL4wDqOaVMHf1EHVqI-YQIv-5MPtOlP1DvK6daMjxhJ7lip1cTOxMG5J-AQEDWQIHsbTwEwK67su9-V1m9HIgv1fxNBNsnUuUG3QErGx36xxIfn90vUHN3vfa8u5n83SsKKcs8Pl6Md2zthr9LYUACKH-yzjXwctv-JyG5n6Ap1tSwiI_CeV_bWYrJt-Ok4wEroDs \ No newline at end of file diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_interaction.xml b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_interaction.xml new file mode 100644 index 0000000..652a2c2 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_interaction.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_payload.xml b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_payload.xml index 430e94a..d2897ac 100644 --- a/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_payload.xml +++ b/b02cf9e61b861d10d806dc23b24bcb3f/dictionary/x_snc_slackerbot_payload.xml @@ -1,7 +1,13 @@ - + + + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_app_module_82da0f3bc3d15a5055bdd523e40131ae.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_app_module_82da0f3bc3d15a5055bdd523e40131ae.xml new file mode 100644 index 0000000..d0ba263 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_app_module_82da0f3bc3d15a5055bdd523e40131ae.xml @@ -0,0 +1,43 @@ + + + true + b56dfd2a1b861d10d806dc23b24bcb52 + + + + + + + LIST + + Interactions + Mobile + x_snc_slackerbot_interaction + + false + + + true + + sys_app_module + asteroid + 2024-10-24 10:21:28 + global + / + 82da0f3bc3d15a5055bdd523e40131ae + 0 + Interactions + + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_app_module_82da0f3bc3d15a5055bdd523e40131ae + asteroid + 2024-10-24 10:21:28 + + Interactions + false + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_db_object_ee0be417c3dd165055bdd523e401314f.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_db_object_ee0be417c3dd165055bdd523e401314f.xml new file mode 100644 index 0000000..6f7af0e --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_db_object_ee0be417c3dd165055bdd523e401314f.xml @@ -0,0 +1,37 @@ + + + + true + true + + true + false + true + false + false + false + + false + x_snc_slackerbot_interaction + + + true + false + + sys_db_object + asteroid + 2024-10-22 09:25:37 + ee0be417c3dd165055bdd523e401314f + 0 + Slackerbot Interaction + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_db_object_ee0be417c3dd165055bdd523e401314f + asteroid + 2024-10-22 09:25:37 + true + + true + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_action_id_regex.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_action_id_regex.xml new file mode 100644 index 0000000..0c2daeb --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_action_id_regex.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + + + + Action ID regex + + + + + + + + false + false + + + + action_id_regex + false + + + + false + string + false + 128 + x_snc_slackerbot_interaction + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:33:05 + Action ID regex + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_action_id_regex + asteroid + 2024-10-22 09:36:34 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_active.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_active.xml new file mode 100644 index 0000000..0d334ac --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_active.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + + + + Active + + + true + + + + + false + false + + + + active + false + + + true + false + boolean + false + 40 + x_snc_slackerbot_interaction + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:29:59 + Active + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_active + asteroid + 2024-10-22 09:29:59 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_description.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_description.xml new file mode 100644 index 0000000..0e89514 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_description.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + + + + Description + + + + + + + + true + false + + + + description + false + + + + false + string + false + 128 + x_snc_slackerbot_interaction + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:30:26 + Description + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_description + asteroid + 2024-10-22 09:36:57 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_null.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_null.xml new file mode 100644 index 0000000..d656051 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_null.xml @@ -0,0 +1,69 @@ + + + true + false + + false + + 0 + + + + + + + + + + + false + false + + + + + false + + + + false + collection + false + 40 + x_snc_slackerbot_interaction + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:25:37 + x_snc_slackerbot_interaction + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_null + asteroid + 2024-10-22 09:25:37 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_related_parsers.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_related_parsers.xml new file mode 100644 index 0000000..9645bd2 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_related_parsers.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + + + + Related parsers + + + + + + + + false + false + + + + related_parsers + false + + + + false + glide_list + false + 4000 + x_snc_slackerbot_interaction + + false + false + + x_snc_slackerbot_parser + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:35:15 + Related parsers + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_related_parsers + asteroid + 2024-10-22 09:35:15 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_script.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_script.xml new file mode 100644 index 0000000..20a3076 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_interaction_script.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + + + + Script + + + + + + + + false + false + + + + script + false + + + + false + script + false + 8000 + x_snc_slackerbot_interaction + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-22 09:31:41 + Script + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_interaction_script + asteroid + 2024-10-22 09:31:41 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_payload_payload_type.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_payload_payload_type.xml new file mode 100644 index 0000000..e7e4da9 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_dictionary_x_snc_slackerbot_payload_payload_type.xml @@ -0,0 +1,74 @@ + + + true + false + + false + + 1 + + + Payload type + + + event + + + + + false + false + + + + payload_type + false + + + + false + choice + false + 40 + x_snc_slackerbot_payload + + false + false + + + + false + + + + + false + false + sys_dictionary + asteroid + 2024-10-20 08:14:03 + Payload type + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_dictionary_x_snc_slackerbot_payload_payload_type + asteroid + 2024-10-20 08:16:18 + false + false + false + false + false + simple + false + script + + + false + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_action_id_regex_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_action_id_regex_en.xml new file mode 100644 index 0000000..7569950 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_action_id_regex_en.xml @@ -0,0 +1,26 @@ + + + + action_id_regex + + + + en + x_snc_slackerbot_interaction + + sys_documentation + asteroid + 2024-10-22 09:33:05 + 5 + Action ID regex + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_interaction_action_id_regex_en + asteroid + 2024-10-22 09:36:34 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_active_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_active_en.xml new file mode 100644 index 0000000..b415310 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_active_en.xml @@ -0,0 +1,26 @@ + + + + active + + + + en + x_snc_slackerbot_interaction + + sys_documentation + asteroid + 2024-10-22 09:29:59 + 3 + Active + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_interaction_active_en + asteroid + 2024-10-22 09:29:59 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_description_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_description_en.xml new file mode 100644 index 0000000..51e8962 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_description_en.xml @@ -0,0 +1,26 @@ + + + + description + + + + en + x_snc_slackerbot_interaction + + sys_documentation + asteroid + 2024-10-22 09:30:26 + 7 + Description + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_interaction_description_en + asteroid + 2024-10-22 09:36:57 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_related_parsers_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_related_parsers_en.xml new file mode 100644 index 0000000..1ba8fbf --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_related_parsers_en.xml @@ -0,0 +1,26 @@ + + + + related_parsers + + + + en + x_snc_slackerbot_interaction + + sys_documentation + asteroid + 2024-10-22 09:35:16 + 3 + Related parsers + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_interaction_related_parsers_en + asteroid + 2024-10-22 09:35:16 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_script_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_script_en.xml new file mode 100644 index 0000000..2bc5f72 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_interaction_script_en.xml @@ -0,0 +1,26 @@ + + + + script + + + + en + x_snc_slackerbot_interaction + + sys_documentation + asteroid + 2024-10-22 09:31:41 + 3 + Script + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_interaction_script_en + asteroid + 2024-10-22 09:31:41 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_payload_payload_type_en.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_payload_payload_type_en.xml new file mode 100644 index 0000000..6126737 --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_documentation_x_snc_slackerbot_payload_payload_type_en.xml @@ -0,0 +1,26 @@ + + + + payload_type + + + + en + x_snc_slackerbot_payload + Payload types + sys_documentation + asteroid + 2024-10-20 08:14:04 + 0 + Payload type + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_documentation_x_snc_slackerbot_payload_payload_type_en + asteroid + 2024-10-20 08:14:04 + + + + + diff --git a/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_36471c93c35d165055bdd523e40131ab.xml b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_36471c93c35d165055bdd523e40131ab.xml new file mode 100644 index 0000000..22ec5cd --- /dev/null +++ b/b02cf9e61b861d10d806dc23b24bcb3f/update/sys_script_36471c93c35d165055bdd523e40131ab.xml @@ -0,0 +1,86 @@ + + + false + package_private + false + true + false + false + true + false + true + false + false + x_snc_slackerbot_payload + + + false + payload_type=interaction^EQ + + + false + + Parse interactivity + 100 + 100 + + + + + + + + sys_script + asteroid + 2024-10-22 09:22:47 + global + / + 36471c93c35d165055bdd523e40131ab + 2 + Parse interactivity + + b02cf9e61b861d10d806dc23b24bcb3f + + b02cf9e61b861d10d806dc23b24bcb3f + sys_script_36471c93c35d165055bdd523e40131ab + asteroid + 2024-10-23 09:50:01 +