Keeps you active on Slack by simulating user activity to prevent away status
Size
14.3 KB
Version
1.0.1
Created
Nov 27, 2025
Updated
19 days ago
1// ==UserScript==
2// @name Slack Anti-AFK - Stay Active
3// @description Keeps you active on Slack by simulating user activity to prevent away status
4// @version 1.0.1
5// @match https://*.app.slack.com/*
6// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAACxLAAAsSwGlPZapAAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDg4LCAyMDIwLzA3LzEwLTIyOjA2OjUzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjIuMCAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMTItMTBUMTA6MzI6MzEtMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTEyLTEwVDEwOjMzOjM2LTA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTEyLTEwVDEwOjMzOjM2LTA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmExODkyZGRmLTQ4ZDIt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
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('Slack Anti-AFK extension loaded');
12
13 // Configuration
14 const CONFIG = {
15 activityInterval: 60000, // Trigger activity every 60 seconds
16 mouseMovementInterval: 30000, // Move mouse every 30 seconds
17 typingInterval: 120000, // Simulate typing every 2 minutes
18 enabled: true
19 };
20
21 let activityTimer = null;
22 let mouseTimer = null;
23 let typingTimer = null;
24
25 // Load saved state
26 async function loadState() {
27 const enabled = await GM.getValue('antiAfkEnabled', true);
28 CONFIG.enabled = enabled;
29 console.log('Anti-AFK enabled:', CONFIG.enabled);
30 }
31
32 // Save state
33 async function saveState() {
34 await GM.setValue('antiAfkEnabled', CONFIG.enabled);
35 }
36
37 // Simulate mouse movement
38 function simulateMouseMovement() {
39 if (!CONFIG.enabled) return;
40
41 const event = new MouseEvent('mousemove', {
42 view: window,
43 bubbles: true,
44 cancelable: true,
45 clientX: Math.random() * window.innerWidth,
46 clientY: Math.random() * window.innerHeight
47 });
48 document.dispatchEvent(event);
49 console.log('Anti-AFK: Mouse movement simulated');
50 }
51
52 // Simulate keyboard activity
53 function simulateKeyboardActivity() {
54 if (!CONFIG.enabled) return;
55
56 const event = new KeyboardEvent('keydown', {
57 key: 'Shift',
58 code: 'ShiftLeft',
59 bubbles: true,
60 cancelable: true
61 });
62 document.dispatchEvent(event);
63
64 const keyupEvent = new KeyboardEvent('keyup', {
65 key: 'Shift',
66 code: 'ShiftLeft',
67 bubbles: true,
68 cancelable: true
69 });
70 document.dispatchEvent(keyupEvent);
71 console.log('Anti-AFK: Keyboard activity simulated');
72 }
73
74 // Simulate user presence by triggering Slack's activity detection
75 function simulateUserPresence() {
76 if (!CONFIG.enabled) return;
77
78 // Trigger various events that Slack monitors for activity
79 window.dispatchEvent(new Event('focus'));
80 document.dispatchEvent(new Event('visibilitychange'));
81
82 // Simulate scroll activity
83 const scrollEvent = new Event('scroll', { bubbles: true });
84 window.dispatchEvent(scrollEvent);
85
86 console.log('Anti-AFK: User presence simulated');
87 }
88
89 // Main activity simulation
90 function triggerActivity() {
91 simulateUserPresence();
92 simulateKeyboardActivity();
93 }
94
95 // Start the anti-AFK system
96 function startAntiAFK() {
97 console.log('Starting Anti-AFK system...');
98
99 // Main activity timer
100 activityTimer = setInterval(() => {
101 triggerActivity();
102 }, CONFIG.activityInterval);
103
104 // Mouse movement timer
105 mouseTimer = setInterval(() => {
106 simulateMouseMovement();
107 }, CONFIG.mouseMovementInterval);
108
109 // Typing indicator timer
110 typingTimer = setInterval(() => {
111 simulateKeyboardActivity();
112 }, CONFIG.typingInterval);
113
114 console.log('Anti-AFK system started');
115 }
116
117 // Stop the anti-AFK system
118 function stopAntiAFK() {
119 console.log('Stopping Anti-AFK system...');
120
121 if (activityTimer) {
122 clearInterval(activityTimer);
123 activityTimer = null;
124 }
125 if (mouseTimer) {
126 clearInterval(mouseTimer);
127 mouseTimer = null;
128 }
129 if (typingTimer) {
130 clearInterval(typingTimer);
131 typingTimer = null;
132 }
133
134 console.log('Anti-AFK system stopped');
135 }
136
137 // Toggle anti-AFK on/off
138 async function toggleAntiAFK() {
139 CONFIG.enabled = !CONFIG.enabled;
140 await saveState();
141
142 if (CONFIG.enabled) {
143 startAntiAFK();
144 updateControlPanel();
145 console.log('Anti-AFK enabled');
146 } else {
147 stopAntiAFK();
148 updateControlPanel();
149 console.log('Anti-AFK disabled');
150 }
151 }
152
153 // Create control panel UI
154 function createControlPanel() {
155 const panel = document.createElement('div');
156 panel.id = 'anti-afk-panel';
157 panel.style.cssText = `
158 position: fixed;
159 bottom: 20px;
160 right: 20px;
161 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
162 color: white;
163 padding: 15px 20px;
164 border-radius: 12px;
165 box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
166 z-index: 999999;
167 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
168 font-size: 14px;
169 min-width: 200px;
170 cursor: move;
171 `;
172
173 panel.innerHTML = `
174 <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
175 <strong style="font-size: 16px;">🛡️ Anti-AFK</strong>
176 <button id="anti-afk-close" style="background: rgba(255,255,255,0.2); border: none; color: white; width: 24px; height: 24px; border-radius: 50%; cursor: pointer; font-size: 16px; line-height: 1;">×</button>
177 </div>
178 <div style="margin-bottom: 10px;">
179 <div style="font-size: 12px; opacity: 0.9; margin-bottom: 5px;">Status: <span id="anti-afk-status" style="font-weight: bold;">${CONFIG.enabled ? 'Active' : 'Inactive'}</span></div>
180 <div style="font-size: 11px; opacity: 0.7;">Keeping you active on Slack</div>
181 </div>
182 <button id="anti-afk-toggle" style="
183 width: 100%;
184 padding: 8px 15px;
185 background: white;
186 color: #667eea;
187 border: none;
188 border-radius: 6px;
189 font-weight: bold;
190 cursor: pointer;
191 font-size: 13px;
192 transition: all 0.2s;
193 ">${CONFIG.enabled ? 'Disable' : 'Enable'}</button>
194 `;
195
196 document.body.appendChild(panel);
197
198 // Make panel draggable
199 let isDragging = false;
200 let currentX;
201 let currentY;
202 let initialX;
203 let initialY;
204
205 panel.addEventListener('mousedown', (e) => {
206 if (e.target.tagName === 'BUTTON') return;
207 isDragging = true;
208 initialX = e.clientX - panel.offsetLeft;
209 initialY = e.clientY - panel.offsetTop;
210 });
211
212 document.addEventListener('mousemove', (e) => {
213 if (isDragging) {
214 e.preventDefault();
215 currentX = e.clientX - initialX;
216 currentY = e.clientY - initialY;
217 panel.style.left = currentX + 'px';
218 panel.style.top = currentY + 'px';
219 panel.style.right = 'auto';
220 panel.style.bottom = 'auto';
221 }
222 });
223
224 document.addEventListener('mouseup', () => {
225 isDragging = false;
226 });
227
228 // Toggle button
229 document.getElementById('anti-afk-toggle').addEventListener('click', toggleAntiAFK);
230
231 // Close button
232 document.getElementById('anti-afk-close').addEventListener('click', () => {
233 panel.style.display = 'none';
234 });
235
236 // Hover effect for toggle button
237 const toggleBtn = document.getElementById('anti-afk-toggle');
238 toggleBtn.addEventListener('mouseenter', () => {
239 toggleBtn.style.transform = 'scale(1.05)';
240 toggleBtn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';
241 });
242 toggleBtn.addEventListener('mouseleave', () => {
243 toggleBtn.style.transform = 'scale(1)';
244 toggleBtn.style.boxShadow = 'none';
245 });
246
247 console.log('Control panel created');
248 }
249
250 // Update control panel UI
251 function updateControlPanel() {
252 const statusElement = document.getElementById('anti-afk-status');
253 const toggleButton = document.getElementById('anti-afk-toggle');
254
255 if (statusElement && toggleButton) {
256 statusElement.textContent = CONFIG.enabled ? 'Active' : 'Inactive';
257 toggleButton.textContent = CONFIG.enabled ? 'Disable' : 'Enable';
258 }
259 }
260
261 // Initialize the extension
262 async function init() {
263 console.log('Initializing Slack Anti-AFK extension...');
264
265 // Load saved state
266 await loadState();
267
268 // Wait for page to be fully loaded
269 if (document.readyState === 'loading') {
270 document.addEventListener('DOMContentLoaded', () => {
271 setTimeout(() => {
272 createControlPanel();
273 if (CONFIG.enabled) {
274 startAntiAFK();
275 }
276 }, 2000);
277 });
278 } else {
279 setTimeout(() => {
280 createControlPanel();
281 if (CONFIG.enabled) {
282 startAntiAFK();
283 }
284 }, 2000);
285 }
286
287 console.log('Slack Anti-AFK extension initialized');
288 }
289
290 // Start the extension
291 init();
292})();