Discord Keyword Notification -updated

Displays a windows notification whenever a user mentions specific textual word(s) in a channel. The script must be manually edited to configure the keywords.

  1. // ==UserScript==
  2. // @name Discord Keyword Notification -updated
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0.0
  5. // @license GNU AGPLv3
  6. // @author noxtrip (original by jcunews)
  7. // @description Displays a windows notification whenever a user mentions specific textual word(s) in a channel. The script must be manually edited to configure the keywords.
  8. // @match *://discordapp.com/*
  9. // @match *://discord.com/*
  10. // @grant GM_notification
  11. // @require http://code.jquery.com/jquery-1.12.4.min.js
  12. // ==/UserScript==
  13.  
  14. (function() {
  15.  
  16. //=== CONFIGURATION BEGIN ===
  17.  
  18. //maximum duration to display notification
  19. var notificationDuration = 50000; //in milliseconds. 1000ms = 1 second. 0 or less = disable auto-dismiss notification.
  20.  
  21. //keywords are specified as regular expression. note: the "g" flag is required.
  22. //quick tutorial: https://www.codeproject.com/Articles/199382/Simple-and-Useful-JavaScript-Regular-Expression-Tu
  23. //full tutorial: https://www.regular-expressions.info/tutorial.html
  24. var keywordsRegexp = /leech|snip/gi;
  25.  
  26. //=== CONFIGURATION END ===
  27.  
  28. var observer, observing, selector = '[class^="scrollerInner-"]', matches = [];
  29. function notify(keywords, nt) {
  30. Notification.requestPermission().then(function (permission) {
  31. // If the user accepts, let's create a notification
  32. if (permission === "granted") {
  33. GM_notification ( {title: 'Discord match found', text: keywords[0] } );
  34. }
  35. });
  36. }
  37.  
  38. function getMatches(s, r, m) {
  39. r = [];
  40. while (m = keywordsRegexp.exec(s)){
  41. r.push(m[0]);
  42. break;
  43. }
  44. return r;
  45. }
  46.  
  47. function check(records) {
  48. records.forEach(function(record) {
  49. record.addedNodes.forEach(function(node, m, s) {
  50. if (
  51. node && (!node.previousElementSibling || !(/hasMore/).test(node.previousElementSibling.className)) &&
  52. !node.querySelector('[class*="isSending-"]') && (node = node.querySelector('[class^="markup-"]')) &&
  53. ((m = getMatches(node.textContent)).length)
  54. ) {
  55. notify(m);
  56. }
  57. });
  58. });
  59. }
  60.  
  61. function init(observerInit) {
  62. observerInit = {childList: true, subtree: true};
  63. setInterval(function(ele) {
  64. if (location.pathname.substr(0, 10) === "/channels/") {
  65. if (!observing && (ele = document.querySelector(selector))) {
  66. observing = true;
  67. if (!observer) observer = new MutationObserver(check);
  68. observer.observe(ele, observerInit);
  69. }
  70. } else if (observing) {
  71. observer.disconnect();
  72. observing = false;
  73. }
  74. }, 500);
  75. }
  76.  
  77. if (window.Notification) {
  78. Notification.requestPermission().then(function() {
  79. if (Notification.permission === "granted") {
  80. init();
  81. } else alert("Access to Browser Notification feature is not granted by user.\nKeyword notification can not be displayed.");
  82. });
  83. } else alert("Browser Notification feature is disabled or not supported.");
  84.  
  85. })();