NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name TwitchMassBan - Easily ban hate raid accounts // @description Easily ban hate raid accounts // @namespace https://github.com/victornpb/twitch-mass-ban // @version 0.7 // @match *://*.twitch.tv/* // @grant none // @run-at document-start // @homepageURL https://github.com/victornpb/twitch-mass-ban // @supportURL https://github.com/victornpb/twitch-mass-ban/issues // @contributionURL https://www.buymeacoffee.com/vitim // @grant none // @license MIT // ==/UserScript== (function() { var html = ` <div class="botban" style="position: fixed; bottom: 10px; right: 350px; z-index: 99999999; background-color:#311b92; color:white; border: 1px solid white; padding:5px;"> <div style="display: flex;"> <button class="clear">CLEAR</button> <button class="extract" title="Auto detect recent followers">DETECT</button> <button class="banAll" style="background: red;">BAN ALL</button> <span style="flex-grow: 1;"></span> <button class="closeBtn">X</button> </div> <br> <textarea placeholder="Usernames" style="font-family:monospace; width: 500px; height: 300px; white-space: nowrap;"></textarea> <style> .botban{ } .botban button{ border: 1px solid white; padding: .5em 1em; margin: 1px; } textarea{ background: var(--color-background-base); color: var(--color-text-base); padding: .5em; font-size: 12pt; } </style> </div>`; // modal const d = document.createElement("div"); d.innerHTML = html; const textarea = d.querySelector("textarea"); // activation button const activateBtn = document.createElement('button'); activateBtn.innerHTML = 'MassBan'; activateBtn.style.cssText = ` font-weight: var(--font-weight-semibold); border-radius: var(--border-radius-medium); font-size: var(--button-text-default); height: var(--button-size-default); background-color: #e91e63; color: var(--color-text-button-primary); `; activateBtn.onclick = ()=>{ d.style.display=''; textarea.focus(); detectUsers(); } function appendActivatorBtn(){ const modBtn = document.querySelector('[data-test-selector="mod-view-link"]'); if (modBtn) { const twitchBar = modBtn.parentElement.parentElement.parentElement; if (twitchBar && !twitchBar.contains(activateBtn)) { twitchBar.insertBefore(activateBtn, twitchBar.firstChild); document.body.appendChild(d); } } } setInterval(appendActivatorBtn, 1E3); d.style.display = 'none'; d.querySelector(".closeBtn").onclick = () => d.style.display='none'; d.querySelector(".clear").onclick = function(){ textarea.value = ''; }; d.querySelector(".extract").onclick = detectUsers; function detectUsers() { const chatArea = document.querySelector('[data-test-selector="chat-scrollable-area__message-container"]'); if (!chatArea) return; let usernames = []; chatArea.innerText.replace(/Thank you for following ([\w_]+) /g, (m, name)=>{ usernames.push(name); return ''; }); usernames = [... new Set(usernames)]; if(usernames) textarea.value = usernames.join('\n'); else textarea.value = 'No usernames found!' } const delay = t=>new Promise(r=>setTimeout(r,t)); function sendMessage(msg){ const textarea = document.querySelector("[data-a-target='chat-input']"); const nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set; nativeTextAreaValueSetter.call(textarea, msg); const event = new Event('input', { bubbles: true}); textarea.dispatchEvent(event); document.querySelector("[data-a-target='chat-send-button']").click(); } d.querySelector(".banAll").onclick = async function(){ var lines = textarea.value.split(/\n/).map(t=>t.trim()).filter(Boolean); for(let line of lines){ line = line.replace(/@/g,''); if (line.match(/^\w+$/)) sendMessage('/ban '+line); else alert(`This doesnt look like an user "${line}"`); await delay(250); } textarea.value = ''; }; })();