Hide Bot Comments

Removes comments made by bots on websites such as YouTube.

As of 2022-02-14. See the latest version.

  1. // ==UserScript==
  2. // @name Hide Bot Comments
  3. // @namespace https://theusaf.org
  4. // @version 1.2.0
  5. // @description Removes comments made by bots on websites such as YouTube.
  6. // @author theusaf
  7. // @match https://www.youtube.com/**
  8. // @copyright 2022 theusaf
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. const SITES = Object.freeze({
  14. YOUTUBE: [
  15. /^\s{2,}/, // starts with too much whitespace
  16. /^(\s*@.+)?\s*(https:\/\/[^\s]+|[\n.\s])+$/, // only links and other punctuation
  17. /^(\s*@.+)?[A-Z\s\r\n!]*https:\/\/[^\s]+[A-Z\s\r\n!]*$/, // all caps and a link
  18. /^(\s*@.+)?\s*https:\/\/[^\s]+(\n|.|\s)*(dont miss|Dont miss|Bots for u|Finally|💜|fax)/, // A link and a random message afterwards
  19. /^(\s*@.+)?\s*This\s*https:\/\/[^\s]+/, // This + link
  20. /^(\s*@.+)?\s*https:\/\/[^\s]+\s*[a-z]+\s*$/, // link + random "word"
  21. /PRIVATE S\*X/,
  22. /-{5,}/, // too many "-"
  23. /SPECIAL FOR YOU/, // common phrase
  24. (text) => {
  25. const smallLatinCaps = text.match(/[ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘᴏ̨ʀsᴛᴜᴠᴡxʏᴢ\s]/g)?.length ?? 0;
  26. return smallLatinCaps / text.length > 0.7 && text.length > 10;
  27. }
  28. ]
  29. }),
  30. site = getCurrentSite(),
  31. commentMutationListener = new MutationObserver((mutations) => {
  32. for (const mutation of mutations) {
  33. for (const node of mutation.addedNodes) {
  34. const text = getCommentText(node, site);
  35. if (text) {
  36. if (isCommentLikelyBotComment(text, site)) {
  37. node.style.display = "none";
  38. }
  39. }
  40. }
  41. }
  42. });
  43.  
  44. commentMutationListener.observe(document.body, {
  45. subtree: true,
  46. childList: true
  47. });
  48.  
  49. /**
  50. * Determines whether a comment is likely spam.
  51. *
  52. * @param {String} text The comment's content
  53. * @param {Object} site The website the comment is from
  54. * @return {Boolean}
  55. */
  56. function isCommentLikelyBotComment(text, siteChecks) {
  57. for (const check of siteChecks) {
  58. if (typeof check === "function") {
  59. if (check(text)) {
  60. return true;
  61. }
  62. } else {
  63. // assume regex
  64. if (check.test(text)) {
  65. return true;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71.  
  72. function getCommentText(node, site) {
  73. switch (site) {
  74. case SITES.YOUTUBE: {
  75. if (node.nodeName === "YTD-COMMENT-RENDERER") {
  76. return node.querySelector("#content-text").textContent;
  77. }
  78. }
  79. }
  80. return null;
  81. }
  82.  
  83. function getCurrentSite() {
  84. switch (location.hostname) {
  85. case "www.youtube.com": {
  86. return SITES.YOUTUBE;
  87. }
  88. }
  89. }