Size
6.4 KB
Version
1.1.1
Created
Feb 28, 2026
Updated
21 days ago
1// ==UserScript==
2// @name Binance Red Packet Auto Collector
3// @description Automatically collects red packets on Binance Square
4// @version 1.1.1
5// @match https://*.binance.com/*
6// @icon https://bin.bnbstatic.com/static/images/common/favicon.ico
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('Binance Red Packet Auto Collector started');
12
13 // Debounce function to prevent excessive calls
14 function debounce(func, wait) {
15 let timeout;
16 return function executedFunction(...args) {
17 const later = () => {
18 clearTimeout(timeout);
19 func(...args);
20 };
21 clearTimeout(timeout);
22 timeout = setTimeout(later, wait);
23 };
24 }
25
26 // Function to click all claim buttons in the modal
27 async function claimAllRedPackets() {
28 console.log('Checking for red packet claim buttons...');
29
30 // Find all claim buttons in the modal
31 const claimButtons = document.querySelectorAll('button.bn-button.bn-button__primary.data-size-small');
32
33 if (claimButtons.length > 0) {
34 console.log(`Found ${claimButtons.length} red packet(s) to claim`);
35
36 for (let i = 0; i < claimButtons.length; i++) {
37 const button = claimButtons[i];
38 if (button.textContent.trim() === 'Claim') {
39 console.log(`Claiming red packet ${i + 1}...`);
40 button.click();
41 // Wait a bit between claims to avoid rate limiting
42 await new Promise(resolve => setTimeout(resolve, 1000));
43 }
44 }
45
46 console.log('Finished claiming all available red packets');
47 } else {
48 console.log('No claimable red packets found');
49 }
50 }
51
52 // Function to automatically open red packet notifications and claim
53 async function autoCollectRedPackets() {
54 console.log('Looking for red packet notifications...');
55
56 // Find red packet notification elements
57 const redPacketNotifications = document.querySelectorAll('div.text-EmphasizeText.flex.cursor-pointer.items-center');
58
59 for (const notification of redPacketNotifications) {
60 const text = notification.textContent.trim();
61 if (text.includes('Sent a Red Packet')) {
62 console.log('Found red packet notification, clicking...');
63 notification.click();
64
65 // Wait for modal to appear
66 await new Promise(resolve => setTimeout(resolve, 2000));
67
68 // Claim all red packets in the modal
69 await claimAllRedPackets();
70
71 // Close the modal
72 const closeButton = document.querySelector('div.bn-modal-header-next[role="button"][aria-label="Close"]');
73 if (closeButton) {
74 closeButton.click();
75 await new Promise(resolve => setTimeout(resolve, 1000));
76 }
77
78 break; // Process one at a time
79 }
80 }
81 }
82
83 // Function to monitor for red packet modals that are already open
84 const checkForOpenModal = debounce(async function() {
85 const modal = document.querySelector('div.bn-modal[role="dialog"][aria-label="modal"]');
86 const modalTitle = document.querySelector('div.bn-modal-header-main div.text-lg');
87
88 if (modal && modalTitle && modalTitle.textContent.includes('Red Packet')) {
89 console.log('Red packet modal detected, claiming...');
90 await claimAllRedPackets();
91 }
92 }, 500);
93
94 // Observe DOM changes to detect new red packets and modals
95 const observer = new MutationObserver(debounce(function(mutations) {
96 checkForOpenModal();
97 }, 1000));
98
99 // Start observing when body is ready
100 function init() {
101 if (document.body) {
102 console.log('Starting red packet observer...');
103
104 observer.observe(document.body, {
105 childList: true,
106 subtree: true
107 });
108
109 // Initial check for existing red packets
110 setTimeout(() => {
111 autoCollectRedPackets();
112 }, 3000);
113
114 console.log('Red packet auto collector is active!');
115 } else {
116 setTimeout(init, 100);
117 }
118 }
119
120 // Add a manual trigger button
121 function addManualTriggerButton() {
122 const button = document.createElement('button');
123 button.textContent = '🧧 Collect Red Packets';
124 button.style.cssText = `
125 position: fixed;
126 bottom: 20px;
127 right: 20px;
128 z-index: 10000;
129 background: linear-gradient(135deg, #ff6b6b 0%, #ee5a6f 100%);
130 color: white;
131 border: none;
132 padding: 12px 20px;
133 border-radius: 25px;
134 font-size: 14px;
135 font-weight: 600;
136 cursor: pointer;
137 box-shadow: 0 4px 15px rgba(238, 90, 111, 0.4);
138 transition: all 0.3s ease;
139 `;
140
141 button.onmouseover = () => {
142 button.style.transform = 'translateY(-2px)';
143 button.style.boxShadow = '0 6px 20px rgba(238, 90, 111, 0.6)';
144 };
145
146 button.onmouseout = () => {
147 button.style.transform = 'translateY(0)';
148 button.style.boxShadow = '0 4px 15px rgba(238, 90, 111, 0.4)';
149 };
150
151 button.onclick = async () => {
152 button.textContent = '🔄 Collecting...';
153 button.disabled = true;
154
155 await autoCollectRedPackets();
156
157 // Also check if modal is already open
158 await claimAllRedPackets();
159
160 button.textContent = '✅ Done!';
161 setTimeout(() => {
162 button.textContent = '🧧 Collect Red Packets';
163 button.disabled = false;
164 }, 2000);
165 };
166
167 document.body.appendChild(button);
168 console.log('Manual trigger button added');
169 }
170
171 // Initialize
172 if (document.readyState === 'loading') {
173 document.addEventListener('DOMContentLoaded', () => {
174 init();
175 addManualTriggerButton();
176 });
177 } else {
178 init();
179 addManualTriggerButton();
180 }
181
182})();