Binance Red Packet Auto Claimer

Automatically extracts red packet codes from Telegram and claims them on Binance

Size

21.1 KB

Version

1.0.1

Created

Nov 13, 2025

Updated

about 1 month ago

1// ==UserScript==
2// @name		Binance Red Packet Auto Claimer
3// @description		Automatically extracts red packet codes from Telegram and claims them on Binance
4// @version		1.0.1
5// @match		https://*.web.telegram.org/*
6// @match		https://www.binance.com/en/my/wallet/account/payment/cryptobox
7// @icon		https://web.telegram.org/a/favicon.ico
8// @grant		GM.getValue
9// @grant		GM.setValue
10// @grant		GM.deleteValue
11// ==/UserScript==
12(function() {
13    'use strict';
14
15    console.log('Binance Red Packet Auto Claimer - Extension loaded');
16
17    // Utility function to wait for element
18    function waitForElement(selector, timeout = 10000) {
19        return new Promise((resolve, reject) => {
20            const element = document.querySelector(selector);
21            if (element) {
22                return resolve(element);
23            }
24
25            const observer = new MutationObserver((mutations, obs) => {
26                const element = document.querySelector(selector);
27                if (element) {
28                    obs.disconnect();
29                    resolve(element);
30                }
31            });
32
33            observer.observe(document.body, {
34                childList: true,
35                subtree: true
36            });
37
38            setTimeout(() => {
39                observer.disconnect();
40                reject(new Error(`Element ${selector} not found within ${timeout}ms`));
41            }, timeout);
42        });
43    }
44
45    // Utility function to delay
46    function delay(ms) {
47        return new Promise(resolve => setTimeout(resolve, ms));
48    }
49
50    // ==================== TELEGRAM FUNCTIONALITY ====================
51    async function extractCodesFromTelegram() {
52        console.log('Starting code extraction from Telegram...');
53        
54        // Find all code elements in messages
55        const codeElements = document.querySelectorAll('code.text-entity-code[data-entity-type="MessageEntityCode"]');
56        console.log(`Found ${codeElements.length} code elements`);
57        
58        const codes = [];
59        codeElements.forEach(codeEl => {
60            const code = codeEl.textContent.trim();
61            if (code && code.length > 0) {
62                codes.push(code);
63            }
64        });
65
66        console.log(`Extracted ${codes.length} red packet codes:`, codes);
67        
68        // Store codes in GM storage
69        if (codes.length > 0) {
70            await GM.setValue('redPacketCodes', JSON.stringify(codes));
71            console.log('Codes saved to storage');
72        }
73        
74        return codes;
75    }
76
77    async function setupTelegramExtractor() {
78        console.log('Setting up Telegram code extractor...');
79        
80        // Create control panel
81        const controlPanel = document.createElement('div');
82        controlPanel.id = 'telegram-extractor-panel';
83        controlPanel.style.cssText = `
84            position: fixed;
85            top: 80px;
86            right: 20px;
87            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
88            color: white;
89            padding: 20px;
90            border-radius: 12px;
91            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
92            z-index: 10000;
93            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
94            min-width: 280px;
95            backdrop-filter: blur(10px);
96        `;
97        
98        controlPanel.innerHTML = `
99            <div style="font-size: 16px; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; gap: 8px;">
100                <span style="font-size: 20px;">🎁</span>
101                Red Packet Extractor
102            </div>
103            <div style="font-size: 13px; margin-bottom: 15px; opacity: 0.9; line-height: 1.4;">
104                Extract codes from this channel and claim them on Binance
105            </div>
106            <div id="codes-count" style="font-size: 14px; margin-bottom: 15px; padding: 10px; background: rgba(255,255,255,0.2); border-radius: 8px; text-align: center;">
107                <span style="font-size: 24px; font-weight: bold;" id="count-number">0</span>
108                <div style="font-size: 12px; margin-top: 4px; opacity: 0.9;">codes found</div>
109            </div>
110            <button id="extract-btn" style="
111                width: 100%;
112                padding: 12px;
113                background: white;
114                color: #667eea;
115                border: none;
116                border-radius: 8px;
117                font-weight: bold;
118                cursor: pointer;
119                font-size: 14px;
120                transition: all 0.3s;
121                margin-bottom: 10px;
122            ">Extract Codes</button>
123            <button id="clear-codes-btn" style="
124                width: 100%;
125                padding: 10px;
126                background: rgba(255,255,255,0.2);
127                color: white;
128                border: 1px solid rgba(255,255,255,0.3);
129                border-radius: 8px;
130                font-weight: 500;
131                cursor: pointer;
132                font-size: 13px;
133                transition: all 0.3s;
134            ">Clear Stored Codes</button>
135            <div id="status-message" style="font-size: 12px; margin-top: 12px; padding: 8px; background: rgba(255,255,255,0.15); border-radius: 6px; text-align: center; display: none;"></div>
136        `;
137        
138        document.body.appendChild(controlPanel);
139        
140        // Add hover effects
141        const extractBtn = document.getElementById('extract-btn');
142        const clearBtn = document.getElementById('clear-codes-btn');
143        
144        extractBtn.addEventListener('mouseenter', () => {
145            extractBtn.style.transform = 'translateY(-2px)';
146            extractBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
147        });
148        extractBtn.addEventListener('mouseleave', () => {
149            extractBtn.style.transform = 'translateY(0)';
150            extractBtn.style.boxShadow = 'none';
151        });
152        
153        clearBtn.addEventListener('mouseenter', () => {
154            clearBtn.style.background = 'rgba(255,255,255,0.3)';
155        });
156        clearBtn.addEventListener('mouseleave', () => {
157            clearBtn.style.background = 'rgba(255,255,255,0.2)';
158        });
159        
160        // Update count on load
161        const storedCodes = await GM.getValue('redPacketCodes', '[]');
162        const codes = JSON.parse(storedCodes);
163        document.getElementById('count-number').textContent = codes.length;
164        
165        // Extract button handler
166        extractBtn.addEventListener('click', async () => {
167            extractBtn.disabled = true;
168            extractBtn.textContent = 'Extracting...';
169            
170            try {
171                const codes = await extractCodesFromTelegram();
172                document.getElementById('count-number').textContent = codes.length;
173                
174                const statusMsg = document.getElementById('status-message');
175                statusMsg.style.display = 'block';
176                statusMsg.style.background = 'rgba(76, 175, 80, 0.3)';
177                statusMsg.textContent = `✓ Extracted ${codes.length} codes successfully!`;
178                
179                setTimeout(() => {
180                    statusMsg.style.display = 'none';
181                }, 3000);
182            } catch (error) {
183                console.error('Error extracting codes:', error);
184                const statusMsg = document.getElementById('status-message');
185                statusMsg.style.display = 'block';
186                statusMsg.style.background = 'rgba(244, 67, 54, 0.3)';
187                statusMsg.textContent = '✗ Error extracting codes';
188            } finally {
189                extractBtn.disabled = false;
190                extractBtn.textContent = 'Extract Codes';
191            }
192        });
193        
194        // Clear button handler
195        clearBtn.addEventListener('click', async () => {
196            await GM.setValue('redPacketCodes', '[]');
197            await GM.deleteValue('currentCodeIndex');
198            document.getElementById('count-number').textContent = '0';
199            
200            const statusMsg = document.getElementById('status-message');
201            statusMsg.style.display = 'block';
202            statusMsg.style.background = 'rgba(255, 152, 0, 0.3)';
203            statusMsg.textContent = '✓ All codes cleared';
204            
205            setTimeout(() => {
206                statusMsg.style.display = 'none';
207            }, 2000);
208        });
209        
210        // Auto-extract on page load
211        await delay(2000);
212        console.log('Auto-extracting codes on page load...');
213        const codes = await extractCodesFromTelegram();
214        document.getElementById('count-number').textContent = codes.length;
215    }
216
217    // ==================== BINANCE FUNCTIONALITY ====================
218    async function claimRedPacketOnBinance() {
219        console.log('Starting Binance red packet claiming process...');
220        
221        // Get stored codes
222        const storedCodes = await GM.getValue('redPacketCodes', '[]');
223        const codes = JSON.parse(storedCodes);
224        
225        if (codes.length === 0) {
226            console.log('No codes available to claim');
227            return { success: false, message: 'No codes available' };
228        }
229        
230        // Get current index
231        let currentIndex = await GM.getValue('currentCodeIndex', 0);
232        
233        if (currentIndex >= codes.length) {
234            console.log('All codes have been processed');
235            return { success: false, message: 'All codes claimed' };
236        }
237        
238        const currentCode = codes[currentIndex];
239        console.log(`Claiming code ${currentIndex + 1}/${codes.length}: ${currentCode}`);
240        
241        try {
242            // Find input field
243            const input = document.querySelector('input[placeholder="Enter red packet code"]');
244            if (!input) {
245                throw new Error('Input field not found');
246            }
247            
248            // Clear and enter code
249            input.value = '';
250            input.focus();
251            input.value = currentCode;
252            
253            // Trigger input event to enable the button
254            input.dispatchEvent(new Event('input', { bubbles: true }));
255            input.dispatchEvent(new Event('change', { bubbles: true }));
256            
257            console.log('Code entered into input field');
258            await delay(500);
259            
260            // Find and click Claim button
261            const claimButton = Array.from(document.querySelectorAll('button')).find(btn => 
262                btn.textContent.trim() === 'Claim' && 
263                !btn.classList.contains('inactive') &&
264                btn.getAttribute('aria-disabled') !== 'true'
265            );
266            
267            if (!claimButton) {
268                throw new Error('Claim button not found or not enabled');
269            }
270            
271            console.log('Clicking Claim button...');
272            claimButton.click();
273            
274            // Wait for popup to appear
275            await delay(2000);
276            
277            // Look for "Open" button in popup
278            const openButton = Array.from(document.querySelectorAll('button')).find(btn => 
279                btn.textContent.trim() === 'Open'
280            );
281            
282            if (openButton) {
283                console.log('Found Open button, clicking...');
284                openButton.click();
285                await delay(2000);
286                
287                // Look for close button (X button)
288                const closeButton = document.querySelector('button[aria-label="Close"], button.bn-modal-close, button[class*="close"]');
289                if (closeButton) {
290                    console.log('Found close button, clicking...');
291                    closeButton.click();
292                    await delay(1000);
293                }
294            }
295            
296            // Move to next code
297            currentIndex++;
298            await GM.setValue('currentCodeIndex', currentIndex);
299            
300            console.log(`Successfully processed code. Moving to next (${currentIndex}/${codes.length})`);
301            return { success: true, message: `Claimed ${currentIndex}/${codes.length}`, currentIndex, total: codes.length };
302            
303        } catch (error) {
304            console.error('Error claiming red packet:', error);
305            // Still move to next code even if there's an error
306            currentIndex++;
307            await GM.setValue('currentCodeIndex', currentIndex);
308            return { success: false, message: error.message, currentIndex, total: codes.length };
309        }
310    }
311
312    async function setupBinanceClaimer() {
313        console.log('Setting up Binance auto claimer...');
314        
315        // Create control panel
316        const controlPanel = document.createElement('div');
317        controlPanel.id = 'binance-claimer-panel';
318        controlPanel.style.cssText = `
319            position: fixed;
320            top: 80px;
321            right: 20px;
322            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
323            color: white;
324            padding: 20px;
325            border-radius: 12px;
326            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
327            z-index: 10000;
328            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
329            min-width: 300px;
330            backdrop-filter: blur(10px);
331        `;
332        
333        controlPanel.innerHTML = `
334            <div style="font-size: 16px; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; gap: 8px;">
335                <span style="font-size: 20px;">🎁</span>
336                Auto Claimer
337            </div>
338            <div style="font-size: 13px; margin-bottom: 15px; opacity: 0.9; line-height: 1.4;">
339                Automatically claim red packets one by one
340            </div>
341            <div id="progress-info" style="font-size: 14px; margin-bottom: 15px; padding: 12px; background: rgba(255,255,255,0.2); border-radius: 8px;">
342                <div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
343                    <span>Progress:</span>
344                    <span id="progress-text" style="font-weight: bold;">0/0</span>
345                </div>
346                <div style="width: 100%; height: 8px; background: rgba(255,255,255,0.3); border-radius: 4px; overflow: hidden;">
347                    <div id="progress-bar" style="width: 0%; height: 100%; background: white; transition: width 0.3s;"></div>
348                </div>
349            </div>
350            <button id="start-claiming-btn" style="
351                width: 100%;
352                padding: 12px;
353                background: white;
354                color: #f5576c;
355                border: none;
356                border-radius: 8px;
357                font-weight: bold;
358                cursor: pointer;
359                font-size: 14px;
360                transition: all 0.3s;
361                margin-bottom: 10px;
362            ">Start Auto Claiming</button>
363            <button id="stop-claiming-btn" style="
364                width: 100%;
365                padding: 10px;
366                background: rgba(255,255,255,0.2);
367                color: white;
368                border: 1px solid rgba(255,255,255,0.3);
369                border-radius: 8px;
370                font-weight: 500;
371                cursor: pointer;
372                font-size: 13px;
373                transition: all 0.3s;
374                display: none;
375            ">Stop Claiming</button>
376            <button id="reset-progress-btn" style="
377                width: 100%;
378                padding: 10px;
379                background: rgba(255,255,255,0.2);
380                color: white;
381                border: 1px solid rgba(255,255,255,0.3);
382                border-radius: 8px;
383                font-weight: 500;
384                cursor: pointer;
385                font-size: 13px;
386                transition: all 0.3s;
387            ">Reset Progress</button>
388            <div id="claim-status" style="font-size: 12px; margin-top: 12px; padding: 8px; background: rgba(255,255,255,0.15); border-radius: 6px; text-align: center; display: none;"></div>
389        `;
390        
391        document.body.appendChild(controlPanel);
392        
393        let isClaimingActive = false;
394        let claimingInterval = null;
395        
396        const startBtn = document.getElementById('start-claiming-btn');
397        const stopBtn = document.getElementById('stop-claiming-btn');
398        const resetBtn = document.getElementById('reset-progress-btn');
399        const progressText = document.getElementById('progress-text');
400        const progressBar = document.getElementById('progress-bar');
401        const statusDiv = document.getElementById('claim-status');
402        
403        // Add hover effects
404        startBtn.addEventListener('mouseenter', () => {
405            startBtn.style.transform = 'translateY(-2px)';
406            startBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
407        });
408        startBtn.addEventListener('mouseleave', () => {
409            startBtn.style.transform = 'translateY(0)';
410            startBtn.style.boxShadow = 'none';
411        });
412        
413        // Update progress display
414        async function updateProgress() {
415            const storedCodes = await GM.getValue('redPacketCodes', '[]');
416            const codes = JSON.parse(storedCodes);
417            const currentIndex = await GM.getValue('currentCodeIndex', 0);
418            
419            progressText.textContent = `${currentIndex}/${codes.length}`;
420            const percentage = codes.length > 0 ? (currentIndex / codes.length) * 100 : 0;
421            progressBar.style.width = `${percentage}%`;
422        }
423        
424        // Initial progress update
425        await updateProgress();
426        
427        // Start claiming
428        startBtn.addEventListener('click', async () => {
429            isClaimingActive = true;
430            startBtn.style.display = 'none';
431            stopBtn.style.display = 'block';
432            resetBtn.disabled = true;
433            resetBtn.style.opacity = '0.5';
434            
435            statusDiv.style.display = 'block';
436            statusDiv.style.background = 'rgba(33, 150, 243, 0.3)';
437            statusDiv.textContent = '⏳ Auto claiming started...';
438            
439            // Claim immediately, then set interval
440            async function claimNext() {
441                if (!isClaimingActive) return;
442                
443                const result = await claimRedPacketOnBinance();
444                await updateProgress();
445                
446                if (result.success) {
447                    statusDiv.style.background = 'rgba(76, 175, 80, 0.3)';
448                    statusDiv.textContent = `${result.message}`;
449                } else {
450                    if (result.message === 'All codes claimed') {
451                        statusDiv.style.background = 'rgba(255, 152, 0, 0.3)';
452                        statusDiv.textContent = '✓ All codes have been claimed!';
453                        isClaimingActive = false;
454                        startBtn.style.display = 'block';
455                        stopBtn.style.display = 'none';
456                        resetBtn.disabled = false;
457                        resetBtn.style.opacity = '1';
458                        if (claimingInterval) clearInterval(claimingInterval);
459                    } else {
460                        statusDiv.style.background = 'rgba(244, 67, 54, 0.3)';
461                        statusDiv.textContent = `⚠ Error: ${result.message}`;
462                    }
463                }
464            }
465            
466            await claimNext();
467            claimingInterval = setInterval(claimNext, 5000); // Claim every 5 seconds
468        });
469        
470        // Stop claiming
471        stopBtn.addEventListener('click', () => {
472            isClaimingActive = false;
473            if (claimingInterval) {
474                clearInterval(claimingInterval);
475                claimingInterval = null;
476            }
477            startBtn.style.display = 'block';
478            stopBtn.style.display = 'none';
479            resetBtn.disabled = false;
480            resetBtn.style.opacity = '1';
481            
482            statusDiv.style.background = 'rgba(255, 152, 0, 0.3)';
483            statusDiv.textContent = '⏸ Claiming stopped';
484        });
485        
486        // Reset progress
487        resetBtn.addEventListener('click', async () => {
488            await GM.deleteValue('currentCodeIndex');
489            await updateProgress();
490            
491            statusDiv.style.display = 'block';
492            statusDiv.style.background = 'rgba(255, 152, 0, 0.3)';
493            statusDiv.textContent = '✓ Progress reset';
494            
495            setTimeout(() => {
496                statusDiv.style.display = 'none';
497            }, 2000);
498        });
499    }
500
501    // ==================== INITIALIZATION ====================
502    async function init() {
503        console.log('Initializing extension...');
504        console.log('Current URL:', window.location.href);
505        
506        // Wait for page to be ready
507        await delay(1500);
508        
509        if (window.location.href.includes('web.telegram.org')) {
510            console.log('Running on Telegram');
511            await setupTelegramExtractor();
512        } else if (window.location.href.includes('binance.com/en/my/wallet/account/payment/cryptobox')) {
513            console.log('Running on Binance');
514            await setupBinanceClaimer();
515        }
516    }
517
518    // Start the extension
519    if (document.readyState === 'loading') {
520        document.addEventListener('DOMContentLoaded', init);
521    } else {
522        init();
523    }
524})();
Binance Red Packet Auto Claimer | Robomonkey