-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontentScript.js
More file actions
199 lines (168 loc) · 6.2 KB
/
contentScript.js
File metadata and controls
199 lines (168 loc) · 6.2 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
(function() {
'use strict';
let totalInvitesSent = 0;
const MAX_INVITES = 5000;
const INVITE_DELAY = 1000; // 1 second
const SCROLL_AMOUNT = 500;
let isProcessing = false;
// Create UI Controls
function createControls() {
const controlPanel = document.createElement('div');
controlPanel.style.cssText = `
position: fixed;
top: 10px;
right: 10px;
z-index: 9999;
background: white;
padding: 10px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
gap: 10px;
`;
// Start Button
const startButton = document.createElement('button');
startButton.textContent = 'Start Inviting';
startButton.style.cssText = `
padding: 8px 16px;
background: #1877f2;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
`;
// Stop Button
const stopButton = document.createElement('button');
stopButton.textContent = 'Stop Inviting';
stopButton.style.cssText = `
padding: 8px 16px;
background: #dc3545;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
display: none;
`;
// Counter Display
const counterDisplay = document.createElement('div');
counterDisplay.style.cssText = `
text-align: center;
font-size: 14px;
font-weight: bold;
`;
startButton.onclick = () => {
isProcessing = true;
startButton.style.display = 'none';
stopButton.style.display = 'block';
processReactions();
};
stopButton.onclick = () => {
isProcessing = false;
startButton.style.display = 'block';
stopButton.style.display = 'none';
};
controlPanel.appendChild(startButton);
controlPanel.appendChild(stopButton);
controlPanel.appendChild(counterDisplay);
document.body.appendChild(controlPanel);
// Update counter
setInterval(() => {
counterDisplay.textContent = `Invites: ${totalInvitesSent}/${MAX_INVITES}`;
}, 1000);
return { startButton, stopButton, counterDisplay };
}
// Find scrollable container in popup
function findScrollableContainer(dialog) {
return Array.from(dialog.querySelectorAll('div')).find(div => {
return div.querySelector('[aria-label="Invite"]') &&
div.scrollHeight > div.clientHeight;
});
}
// Scroll popup and handle invites
async function handlePopupScroll(dialog) {
const container = findScrollableContainer(dialog);
if (!container) return false;
let canScroll = true;
let lastScrollTop = -1;
while (canScroll && isProcessing) {
// Find and click invite buttons
const inviteButtons = dialog.querySelectorAll('[aria-label="Invite"]');
for (let button of inviteButtons) {
if (!isProcessing || totalInvitesSent >= MAX_INVITES) {
return true; // Reached limit or stopped
}
try {
button.click();
totalInvitesSent++;
await new Promise(resolve => setTimeout(resolve, INVITE_DELAY));
} catch (e) {
console.error('Error clicking invite button:', e);
}
}
// Try scrolling
const currentScrollTop = container.scrollTop;
container.scrollTop += SCROLL_AMOUNT;
await new Promise(resolve => setTimeout(resolve, 1000));
// Check if we actually scrolled
canScroll = container.scrollTop !== currentScrollTop &&
container.scrollTop !== lastScrollTop;
lastScrollTop = container.scrollTop;
}
return false;
}
// Find and click reaction elements
function findReactionElements() {
return Array.from(document.querySelectorAll('span.x1e558r4')).filter(span => {
return /^\d+$/.test(span.textContent.trim());
});
}
// Process each post's reactions
async function processPost(reactionElement) {
try {
if (!isProcessing) return true;
// Click the reaction count
reactionElement.click();
await new Promise(resolve => setTimeout(resolve, 2000));
// Find popup dialog
const dialog = document.querySelector('[role="dialog"]');
if (!dialog) return false;
// Process the popup
const reachedLimit = await handlePopupScroll(dialog);
if (reachedLimit) return true;
// Close popup
const closeButton = document.querySelector('div[aria-label="Close"]');
if (closeButton) {
closeButton.click();
await new Promise(resolve => setTimeout(resolve, 1000));
}
return false;
} catch (e) {
console.error('Error processing post:', e);
return false;
}
}
// Main processing function
async function processReactions() {
while (isProcessing && totalInvitesSent < MAX_INVITES) {
const reactionElements = findReactionElements();
let foundNew = false;
for (let element of reactionElements) {
if (!isProcessing) return;
if (element.getAttribute('data-processed')) continue;
element.setAttribute('data-processed', 'true');
foundNew = true;
const reachedLimit = await processPost(element);
if (reachedLimit) return;
}
if (!foundNew) {
window.scrollBy(0, SCROLL_AMOUNT);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
}
// Initialize controls
createControls();
})();