Greasy Fork is available in English.
Hides posts from suspected bot accounts (e.g., Name12345) or users with specific flags (e.g., 🇮🇱) in their name.
当前为
// ==UserScript==
// @name Twitter/X Bot and Flag Post Hider
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Hides posts from suspected bot accounts (e.g., Name12345) or users with specific flags (e.g., 🇮🇱) in their name.
// @author CL
// @match *://x.com/*
// @match *://twitter.com/*
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// --- Configuration ---
// This regex pattern identifies usernames that have letters followed by two or more numbers at the end.
const BOT_USERNAME_PATTERN = /[a-zA-Z].*\d{2,}$/;
// This array contains strings or emojis to look for in the user's display name. Add more items to this list to hide more users.
const HIDE_IF_NAME_INCLUDES = ['🇮🇱'];
// How often the script checks for new posts on the page (in milliseconds).
const CHECK_INTERVAL = 1000;
// --- End Configuration ---
let hiddenPostCount = 0;
const processedPosts = new Set();
/**
* Creates and injects a counter element onto the page to display the number of hidden posts.
* @returns {HTMLElement} The created counter element.
*/
function createCounterElement() {
const counterDiv = document.createElement('div');
counterDiv.id = 'bot-hider-counter';
// Apply styles to make the counter visible but not intrusive.
Object.assign(counterDiv.style, {
position: 'fixed',
top: '15px',
left: '15px',
backgroundColor: 'rgba(29, 155, 240, 0.9)', // A semi-transparent Twitter blue
color: 'white',
padding: '5px 12px',
borderRadius: '15px',
zIndex: '10000',
fontSize: '14px',
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif',
boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
userSelect: 'none',
transition: 'opacity 0.3s ease-in-out'
});
document.body.appendChild(counterDiv);
return counterDiv;
}
const counterElement = createCounterElement();
/**
* Checks if a user's display name contains any of the strings specified in the configuration.
* @param {string} displayName - The user's display name.
* @returns {boolean} - True if the name contains a forbidden string, false otherwise.
*/
function nameContainsHiddenString(displayName) {
return HIDE_IF_NAME_INCLUDES.some(str => displayName.includes(str));
}
/**
* The main function that finds and hides posts based on configured rules.
* It iterates through all tweet articles, checks the author's username and display name,
* and hides the post if it matches any rule.
*/
function hidePosts() {
// Select all tweet articles on the page. `data-testid` is a more stable selector than CSS classes.
const articles = document.querySelectorAll('article[data-testid="tweet"]');
articles.forEach(article => {
// A unique identifier for the tweet, often found in 'aria-labelledby', is used to track processed posts.
// This prevents the script from re-evaluating the same post repeatedly.
const articleId = article.getAttribute('aria-labelledby');
if (!articleId || processedPosts.has(articleId)) {
return; // Skip if it has no ID or has already been processed.
}
processedPosts.add(articleId);
// Find the user's profile link and display name element.
const userLink = article.querySelector('a[href^="/"]:not([href*="/status/"])');
const userDisplayNameElement = article.querySelector('[data-testid="User-Name"]');
if (userLink && userDisplayNameElement) {
const href = userLink.getAttribute('href');
const username = href.substring(1); // Remove the leading '/' to get the username.
const displayName = userDisplayNameElement.textContent || '';
// Check if the post should be hidden based on either the username pattern or the display name content.
const shouldHide = BOT_USERNAME_PATTERN.test(username) || nameContainsHiddenString(displayName);
if (shouldHide) {
// Traverse up the DOM to find the main container of the post.
// Hiding this container removes the entire post from view.
const postContainer = article.closest('[data-testid="cellInnerDiv"]');
if (postContainer) {
postContainer.style.display = 'none';
hiddenPostCount++;
}
}
}
});
// Update the counter display with the latest count.
counterElement.textContent = `Hiding ${hiddenPostCount} posts`;
}
// --- Script Execution ---
console.log('Twitter/X Bot & Flag Hider script is now active.');
// Because Twitter is a single-page application that loads content dynamically,
// we need to run our function periodically to catch new tweets as they appear.
setInterval(hidePosts, CHECK_INTERVAL);
})();