Automatically loops through and views Frameless Ads and Framed Ads on Coinpayu
Size
10.4 KB
Version
1.0.1
Created
Nov 25, 2025
Updated
18 days ago
1// ==UserScript==
2// @name Coinpayu Auto Ad Viewer
3// @description Automatically loops through and views Frameless Ads and Framed Ads on Coinpayu
4// @version 1.0.1
5// @match https://*.coinpayu.com/*
6// @icon https://www.coinpayu.com/favicon.ico
7// @grant GM.getValue
8// @grant GM.setValue
9// @grant GM.openInTab
10// ==/UserScript==
11(function() {
12 'use strict';
13
14 console.log('Coinpayu Auto Ad Viewer started');
15
16 // Configuration
17 const CONFIG = {
18 FRAMELESS_ADS_URL: '/dashboard/ads_surf',
19 FRAMED_ADS_URL: '/dashboard/ads_active',
20 CHECK_INTERVAL: 2000, // Check every 2 seconds
21 AD_WAIT_TIME: 3000, // Wait 3 seconds before checking for next ad
22 MIN_TIMER_SECONDS: 5 // Minimum seconds to wait for timer
23 };
24
25 // Debounce function to prevent multiple rapid calls
26 function debounce(func, wait) {
27 let timeout;
28 return function executedFunction(...args) {
29 const later = () => {
30 clearTimeout(timeout);
31 func(...args);
32 };
33 clearTimeout(timeout);
34 timeout = setTimeout(later, wait);
35 };
36 }
37
38 // Get current page type
39 function getCurrentPageType() {
40 const path = window.location.pathname;
41 if (path.includes(CONFIG.FRAMELESS_ADS_URL)) {
42 return 'frameless';
43 } else if (path.includes(CONFIG.FRAMED_ADS_URL)) {
44 return 'framed';
45 }
46 return null;
47 }
48
49 // Get ad statistics from the page
50 function getAdStats() {
51 const pageType = getCurrentPageType();
52 if (!pageType) return null;
53
54 const statsElement = document.querySelector('.ads-number');
55 if (statsElement) {
56 const text = statsElement.textContent.trim();
57 const match = text.match(/(\d+)\/(\d+)/);
58 if (match) {
59 return {
60 viewed: parseInt(match[1]),
61 total: parseInt(match[2]),
62 pageType: pageType
63 };
64 }
65 }
66 return null;
67 }
68
69 // Check if all ads are viewed
70 function allAdsViewed() {
71 const stats = getAdStats();
72 if (!stats) return false;
73 console.log(`Ad stats: ${stats.viewed}/${stats.total} viewed on ${stats.pageType} ads`);
74 return stats.viewed >= stats.total;
75 }
76
77 // Get the next unviewed ad
78 function getNextAd() {
79 const adBoxes = document.querySelectorAll('.ags-list-box');
80 console.log(`Found ${adBoxes.length} ad boxes`);
81
82 if (adBoxes.length > 0) {
83 // Return the first ad (they should be in order)
84 return adBoxes[0];
85 }
86 return null;
87 }
88
89 // Click on an ad
90 async function clickAd(adElement) {
91 if (!adElement) return false;
92
93 try {
94 console.log('Clicking ad...');
95 adElement.click();
96
97 // Save state that we're viewing an ad
98 await GM.setValue('viewing_ad', true);
99 await GM.setValue('ad_click_time', Date.now());
100
101 return true;
102 } catch (error) {
103 console.error('Error clicking ad:', error);
104 return false;
105 }
106 }
107
108 // Check if we're currently viewing an ad
109 async function isViewingAd() {
110 const viewing = await GM.getValue('viewing_ad', false);
111 return viewing;
112 }
113
114 // Mark ad as viewed and ready for next
115 async function markAdComplete() {
116 console.log('Marking ad as complete');
117 await GM.setValue('viewing_ad', false);
118 await GM.setValue('ad_click_time', 0);
119 }
120
121 // Wait for ad timer to complete
122 async function waitForAdTimer() {
123 const clickTime = await GM.getValue('ad_click_time', 0);
124 if (clickTime === 0) return true;
125
126 const elapsed = Date.now() - clickTime;
127 const adDuration = await getAdDuration();
128
129 console.log(`Ad timer: ${Math.floor(elapsed/1000)}s elapsed, need ${adDuration}s total`);
130
131 if (elapsed >= adDuration * 1000) {
132 return true;
133 }
134 return false;
135 }
136
137 // Get the duration of the current ad
138 async function getAdDuration() {
139 // Try to find the ad duration from the ad details
140 const timeElement = document.querySelector('.ags-detail-time span');
141 if (timeElement) {
142 const seconds = parseInt(timeElement.textContent.trim());
143 if (!isNaN(seconds)) {
144 console.log(`Found ad duration: ${seconds} seconds`);
145 return seconds + 2; // Add 2 seconds buffer
146 }
147 }
148 // Default to 20 seconds if not found
149 return 20;
150 }
151
152 // Switch to the other ad type
153 async function switchAdType() {
154 const currentType = getCurrentPageType();
155 console.log(`Current page type: ${currentType}`);
156
157 if (currentType === 'frameless') {
158 console.log('Switching to Framed Ads...');
159 window.location.href = 'https://www.coinpayu.com/dashboard/ads_active';
160 } else if (currentType === 'framed') {
161 console.log('Switching to Frameless Ads...');
162 window.location.href = 'https://www.coinpayu.com/dashboard/ads_surf';
163 }
164 }
165
166 // Main loop to process ads
167 async function processAds() {
168 const pageType = getCurrentPageType();
169 if (!pageType) {
170 console.log('Not on an ads page');
171 return;
172 }
173
174 console.log(`Processing ${pageType} ads...`);
175
176 // Check if we're currently viewing an ad
177 const viewing = await isViewingAd();
178
179 if (viewing) {
180 // Wait for the ad timer to complete
181 const timerComplete = await waitForAdTimer();
182 if (timerComplete) {
183 console.log('Ad timer complete, marking as done');
184 await markAdComplete();
185 // Wait a bit before checking for next ad
186 setTimeout(() => processAds(), CONFIG.AD_WAIT_TIME);
187 }
188 } else {
189 // Check if all ads on this page are viewed
190 if (allAdsViewed()) {
191 console.log(`All ${pageType} ads viewed!`);
192
193 // Check if we should switch to the other ad type
194 const otherType = pageType === 'frameless' ? 'framed' : 'frameless';
195 const switchedBefore = await GM.getValue(`switched_to_${otherType}`, false);
196
197 if (!switchedBefore) {
198 await GM.setValue(`switched_to_${otherType}`, true);
199 await GM.setValue(`switched_to_${pageType}`, false);
200 await switchAdType();
201 } else {
202 console.log('All ads viewed on both pages! Resetting...');
203 await GM.setValue('switched_to_frameless', false);
204 await GM.setValue('switched_to_framed', false);
205 // Start over with frameless ads
206 if (pageType !== 'frameless') {
207 window.location.href = 'https://www.coinpayu.com/dashboard/ads_surf';
208 }
209 }
210 } else {
211 // Get and click the next ad
212 const nextAd = getNextAd();
213 if (nextAd) {
214 await clickAd(nextAd);
215 } else {
216 console.log('No ads found, waiting...');
217 }
218 }
219 }
220 }
221
222 // Start the auto-viewer
223 async function init() {
224 console.log('Initializing Coinpayu Auto Ad Viewer...');
225
226 // Wait for page to load
227 if (document.readyState === 'loading') {
228 document.addEventListener('DOMContentLoaded', init);
229 return;
230 }
231
232 // Check if we're on an ads page
233 const pageType = getCurrentPageType();
234 if (!pageType) {
235 console.log('Not on an ads page, extension inactive');
236 return;
237 }
238
239 console.log(`On ${pageType} ads page, starting auto-viewer...`);
240
241 // Add visual indicator
242 addStatusIndicator();
243
244 // Start processing ads after a short delay
245 setTimeout(() => {
246 processAds();
247 // Set up interval to keep checking
248 setInterval(processAds, CONFIG.CHECK_INTERVAL);
249 }, 2000);
250 }
251
252 // Add a visual status indicator
253 function addStatusIndicator() {
254 const indicator = document.createElement('div');
255 indicator.id = 'coinpayu-auto-viewer-status';
256 indicator.style.cssText = `
257 position: fixed;
258 top: 10px;
259 right: 10px;
260 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
261 color: white;
262 padding: 12px 20px;
263 border-radius: 8px;
264 font-family: Arial, sans-serif;
265 font-size: 14px;
266 font-weight: bold;
267 z-index: 999999;
268 box-shadow: 0 4px 6px rgba(0,0,0,0.1);
269 cursor: pointer;
270 transition: all 0.3s ease;
271 `;
272 indicator.textContent = '🤖 Auto Viewer Active';
273
274 indicator.addEventListener('mouseenter', () => {
275 indicator.style.transform = 'scale(1.05)';
276 });
277
278 indicator.addEventListener('mouseleave', () => {
279 indicator.style.transform = 'scale(1)';
280 });
281
282 indicator.addEventListener('click', async () => {
283 const stats = getAdStats();
284 if (stats) {
285 alert(`Coinpayu Auto Viewer\n\nStatus: Active\nPage: ${stats.pageType} ads\nProgress: ${stats.viewed}/${stats.total} viewed`);
286 }
287 });
288
289 document.body.appendChild(indicator);
290
291 // Update indicator periodically
292 setInterval(async () => {
293 const viewing = await isViewingAd();
294 const stats = getAdStats();
295 if (viewing) {
296 indicator.textContent = '👁️ Viewing Ad...';
297 indicator.style.background = 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)';
298 } else {
299 indicator.textContent = '🤖 Auto Viewer Active';
300 indicator.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
301 }
302
303 if (stats) {
304 indicator.title = `${stats.viewed}/${stats.total} ads viewed on ${stats.pageType} page`;
305 }
306 }, 1000);
307 }
308
309 // Initialize the extension
310 init();
311
312})();