// ==UserScript==
// @name 电报网页版-屏蔽群组用户发言 Telegram Web - Block Specific Users
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 在Telegram网页版群组中屏蔽特定用户的发言(支持昵称和ID),修复误屏蔽自己发言的问题
// @author 南竹 & deepseek
// @match https://web.telegram.org/k/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
// 初始化屏蔽列表(支持昵称和ID)
let blockedUsers = GM_getValue('blockedUsers', []);
if (typeof blockedUsers === 'string') blockedUsers = JSON.parse(blockedUsers);
if (!Array.isArray(blockedUsers)) blockedUsers = [];
// 创建浮动窗口的样式
const style = document.createElement('style');
style.textContent = `
.block-users-window {
position: fixed;
top: 50px;
left: 50px;
width: 400px;
background: white;
border: 1px solid #ccc;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 10000;
padding: 15px;
font-family: Arial, sans-serif;
border-radius: 5px;
}
.block-users-window .header {
background: #f0f0f0;
padding: 5px 10px;
cursor: move;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
}
.block-users-window .close-btn {
cursor: pointer;
font-size: 18px;
color: #666;
}
.block-users-window .content {
max-height: 300px;
overflow-y: auto;
margin: 10px 0;
}
.block-users-window .list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 0;
border-bottom: 1px solid #eee;
}
.block-users-window .list-item button {
background: #ff4d4d;
color: white;
border: none;
padding: 2px 5px;
cursor: pointer;
border-radius: 3px;
}
.block-users-window .add-section {
display: flex;
gap: 10px;
margin-top: 10px;
}
.block-users-window select, .block-users-window input {
padding: 5px;
border: 1px solid #ccc;
border-radius: 3px;
}
.block-users-window button {
background: #4CAF50;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
border-radius: 3px;
}
`;
document.head.appendChild(style);
// 创建浮动窗口
function createBlockUsersWindow() {
const existingWindow = document.querySelector('.block-users-window');
if (existingWindow) existingWindow.remove();
const windowDiv = document.createElement('div');
windowDiv.className = 'block-users-window';
windowDiv.innerHTML = `
`;
document.body.appendChild(windowDiv);
// 使窗口可拖动
const header = windowDiv.querySelector('.header');
let isDragging = false, currentX, currentY, initialX, initialY;
header.addEventListener('mousedown', (e) => {
initialX = e.clientX - currentX;
initialY = e.clientY - currentY;
isDragging = true;
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
windowDiv.style.left = currentX + 'px';
windowDiv.style.top = currentY + 'px';
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
currentX = parseInt(windowDiv.style.left) || 50;
currentY = parseInt(windowDiv.style.top) || 50;
// 关闭窗口
windowDiv.querySelector('.close-btn').addEventListener('click', () => {
windowDiv.remove();
});
// 更新列表
function updateList() {
const content = windowDiv.querySelector('.content');
content.innerHTML = '';
blockedUsers.forEach((user, index) => {
const item = document.createElement('div');
item.className = 'list-item';
item.innerHTML = `
${user.type === 'nickname' ? '昵称' : 'ID'}: ${user.value}
`;
content.appendChild(item);
});
// 删除按钮事件
content.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
const index = btn.getAttribute('data-index');
blockedUsers.splice(index, 1);
GM_setValue('blockedUsers', JSON.stringify(blockedUsers));
updateList();
hideMessages();
});
});
}
// 添加按钮事件
windowDiv.querySelector('#add-btn').addEventListener('click', () => {
const type = windowDiv.querySelector('#block-type').value;
const value = windowDiv.querySelector('#block-value').value.trim();
if (value && !blockedUsers.some(user => user.type === type && user.value === value)) {
blockedUsers.push({ type, value });
GM_setValue('blockedUsers', JSON.stringify(blockedUsers));
updateList();
hideMessages();
windowDiv.querySelector('#block-value').value = '';
} else if (!value) {
alert('请输入有效的昵称或ID!');
} else {
alert('该昵称或ID已存在!');
}
});
updateList();
}
// 添加菜单命令:打开管理窗口
GM_registerMenuCommand('管理屏蔽用户', () => {
createBlockUsersWindow();
});
// 隐藏消息的函数(修复版)
function hideMessages() {
const messages = document.querySelectorAll('.bubble');
console.log(`找到 ${messages.length} 条消息`);
messages.forEach(message => {
// 每条消息独立获取用户信息
let currentUser = { nickname: null, id: null };
const usernameElement = message.querySelector('.peer-title');
if (usernameElement) {
const userId = usernameElement.getAttribute('data-peer-id');
const nickname = usernameElement.textContent.trim();
if (userId) currentUser.id = userId;
if (nickname) currentUser.nickname = nickname;
console.log(`找到用户: ${nickname} (ID: ${userId})`);
}
// 检查是否匹配屏蔽规则
const shouldBlock = blockedUsers.some(user => {
if (user.type === 'nickname' && currentUser.nickname) {
return user.value === currentUser.nickname;
} else if (user.type === 'id' && currentUser.id) {
return user.value === currentUser.id;
}
return false;
});
// 根据结果显示或隐藏消息
message.style.display = shouldBlock ? 'none' : '';
});
}
// 监听DOM变化
const observer = new MutationObserver(() => {
hideMessages();
});
// 观察聊天区域
const chatContainer = document.querySelector('#column-center') || document.body;
observer.observe(chatContainer, { childList: true, subtree: true });
// 页面加载后延迟执行
window.addEventListener('load', () => {
setTimeout(hideMessages, 2000);
});
// 手动触发初次检查
setTimeout(hideMessages, 2000);
})();