new script: X autoblock by keywords
This commit is contained in:
@@ -3,3 +3,7 @@ Scripts are in the script folder. Please use a userscript manager like [greasemo
|
|||||||
## X-adblock
|
## X-adblock
|
||||||
|
|
||||||
Script to automatically block accounts posting ads on x.com. [Ublock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/) is a much better option. But this script was written thinking "If I block every single account posting ads would I stop seeing ads on twitter? How much time would it take?", still unanswered for now.
|
Script to automatically block accounts posting ads on x.com. [Ublock Origin](https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/) is a much better option. But this script was written thinking "If I block every single account posting ads would I stop seeing ads on twitter? How much time would it take?", still unanswered for now.
|
||||||
|
|
||||||
|
## X-autoblock-keywords
|
||||||
|
|
||||||
|
Script to automatically block accounts tweeting banned words/phrases or banned patterns. Manually modify the arrays bannedKeywords and bannedRegexes in the userscript to add your own banned words and patterns.
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
// ==UserScript==
|
||||||
|
// @name X Auto-Block by Keyword
|
||||||
|
// @version 0.3
|
||||||
|
// @description Automatically block accounts whose tweets contain banned words
|
||||||
|
// @match https://x.com/*
|
||||||
|
// @grant none
|
||||||
|
// @run-at document-end
|
||||||
|
// ==/UserScript==
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// 1) Banned words/phrases (case-insensitive)
|
||||||
|
const bannedKeywords = [
|
||||||
|
'like to see my',
|
||||||
|
'wanna see my'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 2) Banned patterns (RegEx)
|
||||||
|
const bannedRegexes = [
|
||||||
|
/(?:^|\s)https?:\/\/t\.me\/[^\s]+/i,
|
||||||
|
/(?:^|\s)t\.me\/[^\s]+/i
|
||||||
|
];
|
||||||
|
|
||||||
|
function escapeRegex(str) {
|
||||||
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build keyword regex
|
||||||
|
const keywordRegex = new RegExp(
|
||||||
|
`\\b(?:${bannedKeywords.map(escapeRegex).join('|')})\\b`,
|
||||||
|
'i'
|
||||||
|
);
|
||||||
|
|
||||||
|
function containsBannedRegex(text) {
|
||||||
|
return bannedRegexes.some(regex => regex.test(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid reprocessing the same tweet/container
|
||||||
|
const processed = new WeakSet();
|
||||||
|
|
||||||
|
function waitForSelector(selector, timeout = 3000) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const el = document.querySelector(selector);
|
||||||
|
if (el) return resolve(el);
|
||||||
|
|
||||||
|
const obs = new MutationObserver((_, ob) => {
|
||||||
|
const found = document.querySelector(selector);
|
||||||
|
if (found) {
|
||||||
|
ob.disconnect();
|
||||||
|
resolve(found);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
obs.observe(document.body, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
obs.disconnect();
|
||||||
|
reject(new Error(`Timeout waiting for selector: ${selector}`));
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function inspectAndBlock(textEl) {
|
||||||
|
if (processed.has(textEl)) return;
|
||||||
|
processed.add(textEl);
|
||||||
|
|
||||||
|
const text = textEl.innerText || textEl.textContent;
|
||||||
|
if (!keywordRegex.test(text) && !containsBannedRegex(text)) return;
|
||||||
|
|
||||||
|
let container = textEl;
|
||||||
|
while (container && container.getAttribute('data-testid') !== 'tweet') {
|
||||||
|
container = container.parentElement;
|
||||||
|
}
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const moreBtn = container.querySelector('button[data-testid="caret"]');
|
||||||
|
if (!moreBtn) return;
|
||||||
|
moreBtn.click();
|
||||||
|
|
||||||
|
const blockItem = await waitForSelector('div[data-testid="block"]');
|
||||||
|
if (/^\s*Block\s+@.+/i.test(blockItem.innerText)) {
|
||||||
|
blockItem.click();
|
||||||
|
} else {
|
||||||
|
const closeBtn = await waitForSelector('button[aria-label="Close"]');
|
||||||
|
closeBtn.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmBtn = await waitForSelector('button[data-testid="confirmationSheetConfirm"]');
|
||||||
|
confirmBtn.click();
|
||||||
|
|
||||||
|
let matchedBanTerm = null;
|
||||||
|
|
||||||
|
const wordMatch = text.match(keywordRegex);
|
||||||
|
if (wordMatch) {
|
||||||
|
matchedBanTerm = wordMatch[0];
|
||||||
|
} else {
|
||||||
|
matchedBanTerm = bannedRegexes
|
||||||
|
.map(rx => {
|
||||||
|
const m = text.match(rx);
|
||||||
|
return m ? m[0].trim() : null;
|
||||||
|
})
|
||||||
|
.find(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Blocked account for tweet containing banned term: "${matchedBanTerm}"`);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error during block flow:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new MutationObserver(mutations => {
|
||||||
|
for (const mut of mutations) {
|
||||||
|
mut.addedNodes.forEach(node => {
|
||||||
|
if (node.nodeType !== 1) return;
|
||||||
|
const texts = node.matches && (
|
||||||
|
node.matches('[data-testid="tweetText"]') ||
|
||||||
|
node.matches('[data-testid="card.layoutSmall.detail"]') ||
|
||||||
|
node.matches('[data-testid="User-Name"]')
|
||||||
|
)
|
||||||
|
? [node]
|
||||||
|
: Array.from(node.querySelectorAll(
|
||||||
|
'[data-testid="tweetText"], [data-testid="card.layoutSmall.detail"], [data-testid="User-Name"]'
|
||||||
|
));
|
||||||
|
|
||||||
|
texts.forEach(el => inspectAndBlock(el));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
document.querySelectorAll(
|
||||||
|
'[data-testid="tweetText"], [data-testid="card.layoutSmall.detail"], [data-testid="User-Name"]'
|
||||||
|
).forEach(el => inspectAndBlock(el));
|
||||||
|
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user