您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
8/1/2025, 12:22:39 PM
// ==UserScript== // @name AmericanExpress Offer Automator // @namespace Violentmonkey Scripts // @match https://*americanexpress.*/* // @grant none // @version 1.0.2 // @author Yeung // @license MIT // @description 8/1/2025, 12:22:39 PM // ==/UserScript== // // // American Express Offer Automation Script class AmexOfferAutomator { constructor() { this.offerButtons = []; this.isRunning = false; this.delay = 3000; this.currentButton = null; this.init(); } init() { this.createStartButton(); this.startMonitoring(); } createStartButton() { this.currentButton = document.createElement('button'); this.currentButton.textContent = 'Add all offers'; this.currentButton.className = 'amex-offer-button'; this.applyButtonStyles(this.currentButton); this.addHoverEffects(this.currentButton); this.currentButton.addEventListener('click', () => this.startAutomation()); document.body.appendChild(this.currentButton); } createPauseButton() { const pauseButton = document.createElement('button'); pauseButton.textContent = '⏸️ Pause automation'; pauseButton.className = 'amex-offer-button pause'; this.applyButtonStyles(pauseButton); this.addHoverEffects(pauseButton); pauseButton.style.backgroundColor = '#dc3545'; pauseButton.addEventListener('mouseenter', () => { pauseButton.style.backgroundColor = '#c82333'; }); pauseButton.addEventListener('mouseleave', () => { pauseButton.style.backgroundColor = '#dc3545'; }); pauseButton.addEventListener('click', () => this.stopAutomation()); return pauseButton; } applyButtonStyles(button) { Object.assign(button.style, { position: 'fixed', top: '20px', right: '20px', zIndex: '9999', padding: '10px 20px', backgroundColor: '#007BFF', color: 'white', border: 'none', borderRadius: '5px', cursor: 'pointer', boxShadow: '0 2px 6px rgba(0, 0, 0, 0.2)', fontFamily: 'Arial, sans-serif', fontSize: '14px', fontWeight: 'bold', transition: 'background-color 0.2s ease' }); } addHoverEffects(button) { button.addEventListener('mouseenter', () => { if (!button.classList.contains('pause')) { button.style.backgroundColor = '#0056b3'; } }); button.addEventListener('mouseleave', () => { if (!button.classList.contains('pause')) { button.style.backgroundColor = '#007BFF'; } }); } replaceButton(newButton) { if (this.currentButton && this.currentButton.parentNode) { this.currentButton.parentNode.replaceChild(newButton, this.currentButton); } this.currentButton = newButton; } findOfferButtons() { const buttons = Array.from(document.querySelectorAll('button')); return buttons.filter(btn => btn.title === 'Add to Card' || btn.title === 'Activate Offer' ); } async clickOfferButton(index) { if (!this.isRunning || index >= this.offerButtons.length) { this.isRunning = false; if (index >= this.offerButtons.length) { console.log('✅ All offers processed successfully!'); this.showCompletionMessage(); } return; } const button = this.offerButtons[index]; console.log(`🔄 Clicking offer ${index + 1} of ${this.offerButtons.length}`); try { button.click(); await this.sleep(this.delay); await this.clickOfferButton(index + 1); } catch (error) { console.error('❌ Error clicking offer button:', error); this.isRunning = false; } } async startAutomation() { if (this.isRunning) { console.log('⚠️ Automation already running...'); return; } this.isRunning = true; console.log('🚀 Starting AMEX offer automation...'); // Replace start button with pause button const pauseButton = this.createPauseButton(); this.replaceButton(pauseButton); // Wait a bit before starting to ensure page is ready await this.sleep(this.delay); await this.processOffers(); } stopAutomation() { this.isRunning = false; console.log('⏹️ Automation paused'); // Replace pause button with resume button const resumeButton = this.createResumeButton(); this.replaceButton(resumeButton); } createResumeButton() { const resumeButton = document.createElement('button'); resumeButton.textContent = '▶️ Resume automation'; resumeButton.className = 'amex-offer-button resume'; this.applyButtonStyles(resumeButton); this.addHoverEffects(resumeButton); resumeButton.style.backgroundColor = '#28a745'; resumeButton.addEventListener('mouseenter', () => { resumeButton.style.backgroundColor = '#218838'; }); resumeButton.addEventListener('mouseleave', () => { resumeButton.style.backgroundColor = '#28a745'; }); resumeButton.addEventListener('click', () => this.resumeAutomation()); return resumeButton; } async resumeAutomation() { if (this.isRunning) { console.log('⚠️ Automation already running...'); return; } this.isRunning = true; console.log('🔄 Resuming AMEX offer automation...'); // Replace resume button with pause button const pauseButton = this.createPauseButton(); this.replaceButton(pauseButton); // Continue from where we left off await this.processOffers(); } showCompletionMessage() { // Replace current button with completion button const completionButton = document.createElement('button'); completionButton.textContent = '✅ Completed!'; completionButton.className = 'amex-offer-button completed'; this.applyButtonStyles(completionButton); completionButton.style.backgroundColor = '#28a745'; completionButton.style.cursor = 'default'; // Remove hover effects for completion button completionButton.addEventListener('mouseenter', () => { completionButton.style.backgroundColor = '#28a745'; }); completionButton.addEventListener('mouseleave', () => { completionButton.style.backgroundColor = '#28a745'; }); this.replaceButton(completionButton); // Auto-remove completion button after 5 seconds setTimeout(() => { if (completionButton.parentNode) { completionButton.parentNode.removeChild(completionButton); } }, 5000); } async processOffers() { this.offerButtons = this.findOfferButtons(); if (this.offerButtons.length === 0) { console.log('⏳ No offer buttons found, retrying in 3 seconds...'); if (this.isRunning) { setTimeout(() => this.processOffers(), this.delay); } return; } console.log(`🎯 Found ${this.offerButtons.length} AMEX offer buttons`); await this.clickOfferButton(0); } startMonitoring() { // Monitor for dynamic content changes const observer = new MutationObserver(() => { if (!this.isRunning) { this.offerButtons = this.findOfferButtons(); } }); observer.observe(document.body, { childList: true, subtree: true }); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } stop() { this.isRunning = false; console.log('⏹️ Automation stopped'); } } // Initialize the automator when the script loads const amexAutomator = new AmexOfferAutomator(); // Expose to global scope for debugging window.amexAutomator = amexAutomator;