Automatically claims red packets on Binance and monitors Binance Square for new opportunities
Size
14.5 KB
Version
1.1.1
Created
Feb 28, 2026
Updated
21 days ago
1// ==UserScript==
2// @name Binance Red Packet Auto Claimer
3// @description Automatically claims red packets on Binance and monitors Binance Square for new opportunities
4// @version 1.1.1
5// @match https://*.binance.com/*
6// @match https://www.binance.com/*
7// @icon https://web.telegram.org/k/assets/img/favicon.ico?v=jw3mK7G9Ry
8// ==/UserScript==
9(function() {
10 'use strict';
11
12 console.log('Binance Red Packet Auto Claimer initialized');
13
14 // Configuration
15 const CONFIG = {
16 CHECK_INTERVAL: 5000, // Check every 5 seconds
17 SQUARE_CHECK_INTERVAL: 30000, // Check Binance Square every 30 seconds
18 AUTO_CLAIM_ENABLED: true,
19 MONITOR_SQUARE: true
20 };
21
22 // State management
23 let claimedPackets = [];
24 let isProcessing = false;
25
26 // Initialize state from storage
27 async function initState() {
28 try {
29 const saved = await GM.getValue('claimedPackets', '[]');
30 claimedPackets = JSON.parse(saved);
31 console.log('Loaded claimed packets:', claimedPackets.length);
32 } catch (error) {
33 console.error('Error loading state:', error);
34 claimedPackets = [];
35 }
36 }
37
38 // Save state to storage
39 async function saveState() {
40 try {
41 await GM.setValue('claimedPackets', JSON.stringify(claimedPackets));
42 } catch (error) {
43 console.error('Error saving state:', error);
44 }
45 }
46
47 // Debounce function to prevent excessive calls
48 function debounce(func, wait) {
49 let timeout;
50 return function executedFunction(...args) {
51 const later = () => {
52 clearTimeout(timeout);
53 func(...args);
54 };
55 clearTimeout(timeout);
56 timeout = setTimeout(later, wait);
57 };
58 }
59
60 // Check if packet was already claimed
61 function isPacketClaimed(packetId) {
62 return claimedPackets.includes(packetId);
63 }
64
65 // Mark packet as claimed
66 async function markPacketClaimed(packetId) {
67 if (!claimedPackets.includes(packetId)) {
68 claimedPackets.push(packetId);
69 await saveState();
70 console.log('Marked packet as claimed:', packetId);
71 }
72 }
73
74 // Find red packet elements on the page
75 function findRedPacketElements() {
76 const selectors = [
77 // Red packet claim buttons
78 'button[class*="red-packet"]',
79 'button[class*="redpacket"]',
80 'button[class*="claim"]',
81 'div[class*="red-packet"]',
82 'div[class*="redpacket"]',
83 // Binance Pay red packet
84 'button[data-bn-type="button"][class*="red"]',
85 'a[href*="red-packet"]',
86 'a[href*="redpacket"]',
87 // Modal and popup elements
88 'div[class*="modal"][class*="red"]',
89 'div[class*="popup"][class*="red"]'
90 ];
91
92 const elements = [];
93 selectors.forEach(selector => {
94 try {
95 const found = document.querySelectorAll(selector);
96 found.forEach(el => {
97 const text = el.textContent.toLowerCase();
98 if (text.includes('claim') || text.includes('red packet') || text.includes('receive')) {
99 elements.push(el);
100 }
101 });
102 } catch (error) {
103 console.error('Error with selector:', selector, error);
104 }
105 });
106
107 return elements;
108 }
109
110 // Extract red packet code from URL or page
111 function extractRedPacketCode() {
112 // Check URL for red packet code
113 const urlParams = new URLSearchParams(window.location.search);
114 const codeFromUrl = urlParams.get('code') || urlParams.get('ref');
115
116 if (codeFromUrl) {
117 return codeFromUrl;
118 }
119
120 // Check page content for red packet codes
121 const bodyText = document.body.textContent;
122 const codePattern = /[A-Z0-9]{8,16}/g;
123 const matches = bodyText.match(codePattern);
124
125 return matches ? matches[0] : null;
126 }
127
128 // Attempt to claim a red packet
129 async function claimRedPacket(element) {
130 if (isProcessing) {
131 console.log('Already processing a claim, skipping...');
132 return false;
133 }
134
135 isProcessing = true;
136 console.log('Attempting to claim red packet...');
137
138 try {
139 // Extract packet ID if available
140 const packetId = element.getAttribute('data-packet-id') ||
141 element.getAttribute('id') ||
142 extractRedPacketCode() ||
143 Date.now().toString();
144
145 // Check if already claimed
146 if (isPacketClaimed(packetId)) {
147 console.log('Packet already claimed:', packetId);
148 return false;
149 }
150
151 // Click the claim button
152 if (element.tagName === 'BUTTON' || element.tagName === 'A') {
153 element.click();
154 console.log('Clicked claim button');
155 } else {
156 // Try to find a button inside the element
157 const button = element.querySelector('button') || element.querySelector('a');
158 if (button) {
159 button.click();
160 console.log('Clicked nested button');
161 }
162 }
163
164 // Wait for claim to process
165 await new Promise(resolve => setTimeout(resolve, 2000));
166
167 // Look for success indicators
168 const successIndicators = [
169 'success',
170 'claimed',
171 'received',
172 'congratulations'
173 ];
174
175 const pageText = document.body.textContent.toLowerCase();
176 const isSuccess = successIndicators.some(indicator => pageText.includes(indicator));
177
178 if (isSuccess) {
179 await markPacketClaimed(packetId);
180 console.log('Successfully claimed red packet:', packetId);
181 showNotification('Red packet claimed successfully!', 'success');
182 return true;
183 } else {
184 console.log('Claim status unclear, marking as attempted');
185 await markPacketClaimed(packetId);
186 return false;
187 }
188
189 } catch (error) {
190 console.error('Error claiming red packet:', error);
191 return false;
192 } finally {
193 isProcessing = false;
194 }
195 }
196
197 // Monitor Binance Square for red packets
198 async function monitorBinanceSquare() {
199 if (!CONFIG.MONITOR_SQUARE) return;
200
201 console.log('Monitoring Binance Square for red packets...');
202
203 try {
204 // Check if we're on Binance Square
205 if (window.location.href.includes('/square')) {
206 // Look for red packet posts
207 const posts = document.querySelectorAll('a[href*="/square/post"]');
208
209 for (const post of posts) {
210 const text = post.textContent.toLowerCase();
211 if (text.includes('red packet') || text.includes('redpacket') || text.includes('giveaway') || text.includes('gift')) {
212 console.log('Found potential red packet post:', post.href);
213
214 // Check if we've already processed this post
215 const postId = post.href.split('/').pop();
216 if (!isPacketClaimed('square_' + postId)) {
217 // Mark as seen
218 await markPacketClaimed('square_' + postId);
219
220 // Auto-open the post to claim
221 console.log('Auto-opening red packet post:', post.href);
222 showNotification('Found red packet in Binance Square! Opening...', 'info');
223
224 // Open in current tab to auto-claim
225 window.location.href = post.href;
226 return; // Exit to allow page to load
227 }
228 }
229 }
230
231 // Also check for red packet codes in visible posts
232 await extractAndClaimCodesFromSquare();
233 }
234 } catch (error) {
235 console.error('Error monitoring Binance Square:', error);
236 }
237 }
238
239 // Extract and claim red packet codes from Binance Square posts
240 async function extractAndClaimCodesFromSquare() {
241 try {
242 // Look for red packet codes in post content
243 const postContents = document.querySelectorAll('[class*="post-content"], [class*="article"], [class*="content"]');
244
245 for (const content of postContents) {
246 const text = content.textContent;
247
248 // Look for red packet code patterns
249 const codePatterns = [
250 /code[:\s]+([A-Z0-9]{8,16})/gi,
251 /red packet[:\s]+([A-Z0-9]{8,16})/gi,
252 /claim[:\s]+([A-Z0-9]{8,16})/gi,
253 /\b([A-Z0-9]{8,16})\b/g
254 ];
255
256 for (const pattern of codePatterns) {
257 const matches = text.matchAll(pattern);
258 for (const match of matches) {
259 const code = match[1] || match[0];
260
261 if (code && !isPacketClaimed('code_' + code)) {
262 console.log('Found red packet code in Square:', code);
263 await markPacketClaimed('code_' + code);
264
265 // Navigate to red packet claim page
266 const claimUrl = `https://www.binance.com/en/my/wallet/account/payment/cryptobox?code=${code}`;
267 showNotification('Found red packet code! Claiming...', 'info');
268 window.location.href = claimUrl;
269 return;
270 }
271 }
272 }
273 }
274 } catch (error) {
275 console.error('Error extracting codes from Square:', error);
276 }
277 }
278
279 // Show notification to user
280 function showNotification(message, type = 'info') {
281 const notification = document.createElement('div');
282 notification.style.cssText = `
283 position: fixed;
284 top: 20px;
285 right: 20px;
286 background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'};
287 color: white;
288 padding: 16px 24px;
289 border-radius: 8px;
290 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
291 z-index: 999999;
292 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
293 font-size: 14px;
294 font-weight: 500;
295 max-width: 300px;
296 animation: slideIn 0.3s ease-out;
297 `;
298 notification.textContent = message;
299 document.body.appendChild(notification);
300
301 setTimeout(() => {
302 notification.style.animation = 'slideOut 0.3s ease-out';
303 setTimeout(() => notification.remove(), 300);
304 }, 5000);
305 }
306
307 // Add CSS animations
308 const style = document.createElement('style');
309 style.textContent = `
310 @keyframes slideIn {
311 from {
312 transform: translateX(400px);
313 opacity: 0;
314 }
315 to {
316 transform: translateX(0);
317 opacity: 1;
318 }
319 }
320 @keyframes slideOut {
321 from {
322 transform: translateX(0);
323 opacity: 1;
324 }
325 to {
326 transform: translateX(400px);
327 opacity: 0;
328 }
329 }
330 `;
331 document.head.appendChild(style);
332
333 // Main monitoring loop
334 async function monitorForRedPackets() {
335 if (!CONFIG.AUTO_CLAIM_ENABLED) return;
336
337 try {
338 // Find red packet elements
339 const redPacketElements = findRedPacketElements();
340
341 if (redPacketElements.length > 0) {
342 console.log('Found', redPacketElements.length, 'potential red packet elements');
343
344 // Try to claim the first unclaimed packet
345 for (const element of redPacketElements) {
346 const claimed = await claimRedPacket(element);
347 if (claimed) {
348 break; // Only claim one at a time
349 }
350 }
351 }
352 } catch (error) {
353 console.error('Error in monitoring loop:', error);
354 }
355 }
356
357 // Handle red packet URLs directly
358 function handleRedPacketUrl() {
359 const url = window.location.href;
360
361 // Check if URL contains red packet parameters
362 if (url.includes('red-packet') || url.includes('redpacket') || url.includes('/pay/')) {
363 console.log('Red packet URL detected, attempting auto-claim...');
364
365 // Wait for page to load then try to claim
366 setTimeout(() => {
367 const claimButtons = findRedPacketElements();
368 if (claimButtons.length > 0) {
369 claimRedPacket(claimButtons[0]);
370 }
371 }, 3000);
372 }
373 }
374
375 // Observe DOM changes for dynamically loaded red packets
376 const observer = new MutationObserver(debounce(() => {
377 if (CONFIG.AUTO_CLAIM_ENABLED) {
378 monitorForRedPackets();
379 }
380 }, 1000));
381
382 // Initialize the extension
383 async function init() {
384 console.log('Starting Binance Red Packet Auto Claimer...');
385
386 // Initialize state
387 await initState();
388
389 // Handle direct red packet URLs
390 handleRedPacketUrl();
391
392 // Start monitoring
393 setInterval(monitorForRedPackets, CONFIG.CHECK_INTERVAL);
394 setInterval(monitorBinanceSquare, CONFIG.SQUARE_CHECK_INTERVAL);
395
396 // Observe DOM changes
397 observer.observe(document.body, {
398 childList: true,
399 subtree: true
400 });
401
402 console.log('Binance Red Packet Auto Claimer is now active!');
403 showNotification('Red Packet Auto Claimer is active!', 'success');
404 }
405
406 // Wait for page to be ready
407 if (document.readyState === 'loading') {
408 document.addEventListener('DOMContentLoaded', init);
409 } else {
410 init();
411 }
412
413})();