Slack Anti-AFK - Stay Active

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})();
Slack Anti-AFK - Stay Active | Robomonkey