-
-
Notifications
You must be signed in to change notification settings - Fork 87
Expand file tree
/
Copy pathreportSpam.js
More file actions
144 lines (123 loc) · 4.69 KB
/
Copy pathreportSpam.js
File metadata and controls
144 lines (123 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) 2024-2026 nich (@nichxbt). Licensed under the Apache License, Version 2.0.
// scripts/reportSpam.js
// Browser console script for reporting spam accounts on X/Twitter
// Paste in DevTools console on x.com (any page)
// by nichxbt
(() => {
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
// =============================================
// CONFIGURATION
// =============================================
const CONFIG = {
usersToReport: [
// 'spammer1',
// 'spammer2',
],
reason: 'spam', // 'spam', 'abuse', 'fake'
blockAfterReport: true, // Also block the user after reporting
dryRun: true, // SET FALSE TO EXECUTE
delay: 5000, // ms between reports (keep high to avoid issues)
};
// =============================================
const results = { reported: [], failed: [] };
const reportUser = async (username) => {
try {
window.location.href = `https://x.com/${username}`;
await sleep(3500);
// Wait for profile to load
let attempts = 0;
while (!document.querySelector('[data-testid="userActions"]') && attempts < 10) {
await sleep(500);
attempts++;
}
const moreBtn = document.querySelector('[data-testid="userActions"]');
if (!moreBtn) {
console.warn(`⚠️ @${username}: Profile not found`);
results.failed.push(username);
return;
}
moreBtn.click();
await sleep(1000);
// Find "Report" in menu
const menuItems = document.querySelectorAll('[role="menuitem"]');
let reportItem = null;
for (const item of menuItems) {
if (/report/i.test(item.textContent)) { reportItem = item; break; }
}
if (!reportItem) {
document.body.click();
await sleep(300);
results.failed.push(username);
console.warn(`⚠️ @${username}: Report option not found`);
return;
}
reportItem.click();
await sleep(1500);
// Select reason in report flow
const reasonOptions = document.querySelectorAll('[role="radio"], [role="option"], button');
for (const opt of reasonOptions) {
const text = opt.textContent.toLowerCase();
if (
(CONFIG.reason === 'spam' && text.includes('spam')) ||
(CONFIG.reason === 'abuse' && (text.includes('abuse') || text.includes('harass'))) ||
(CONFIG.reason === 'fake' && (text.includes('fake') || text.includes('impersonat')))
) {
opt.click();
await sleep(800);
break;
}
}
// Click next/submit
const submitBtn = document.querySelector('[data-testid="ChoiceSelectionNextButton"]');
if (submitBtn) {
submitBtn.click();
await sleep(1000);
}
results.reported.push(username);
console.log(`🚩 Reported @${username} for ${CONFIG.reason}`);
// Optionally block after reporting
if (CONFIG.blockAfterReport) {
await sleep(1000);
// Check if there's a block option in the post-report flow
const blockOptions = document.querySelectorAll('button, [role="button"]');
for (const opt of blockOptions) {
if (/block/i.test(opt.textContent) && !/unblock/i.test(opt.textContent)) {
opt.click();
await sleep(600);
const confirmBtn = document.querySelector('[data-testid="confirmationSheetConfirm"]');
if (confirmBtn) {
confirmBtn.click();
await sleep(500);
}
console.log(`🚫 Also blocked @${username}`);
break;
}
}
}
} catch (e) {
results.failed.push(username);
console.warn(`⚠️ Error reporting @${username}`);
}
};
const run = async () => {
console.log('🚩 REPORT SPAM — XActions by nichxbt');
if (CONFIG.usersToReport.length === 0) {
console.error('❌ No users to report! Edit CONFIG.usersToReport array.');
return;
}
console.log(`📋 Users to report: ${CONFIG.usersToReport.length} | Reason: ${CONFIG.reason}`);
console.log(`⚙️ Block after: ${CONFIG.blockAfterReport} | Dry run: ${CONFIG.dryRun}`);
if (CONFIG.dryRun) {
console.log('\n⚠️ DRY RUN — Set CONFIG.dryRun = false to actually report.');
CONFIG.usersToReport.forEach((u, i) => console.log(` ${i + 1}. @${u} (${CONFIG.reason})`));
return;
}
for (const username of CONFIG.usersToReport) {
console.log(`\n⏳ Processing @${username}...`);
await reportUser(username);
await sleep(CONFIG.delay);
}
console.log(`\n✅ Done! Reported: ${results.reported.length} | Failed: ${results.failed.length}`);
};
run();
})();