Created
August 24, 2025 06:15
-
-
Save Ap0dexMe0/506406ff1e96fdb2157e453b5538687b to your computer and use it in GitHub Desktop.
Augment Code Automated Registration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name AugmentCode Auto Register | |
| // @namespace http://tampermonkey.net/ | |
| // @version 1.0.0 | |
| // @description AugmentCode Auto Registration Script | |
| // @author AugmentCode-AutoRegister-Userscript | |
| // @match https://*.augmentcode.com/* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=augmentcode.com | |
| // @grant GM_xmlhttpRequest | |
| // @grant GM_setValue | |
| // @grant GM_getValue | |
| // @grant GM_deleteValue | |
| // @grant GM_log | |
| // @connect tempmail.plus | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| // Main email domain constant for generating standard format email addresses | |
| const EMAIL_DOMAIN = "@mailto.plus"; | |
| /** | |
| * Temporary email service configuration | |
| * Used for scenarios requiring temporary email verification | |
| */ | |
| const TEMP_MAIL_CONFIG = { | |
| username: "test", // Temporary email username | |
| emailExtension: "@mailto.plus", // Temporary email domain extension | |
| epin: "000" // Temporary email PIN code | |
| }; | |
| const FIRST_NAMES = ["alex", "emily", "jason", "olivia", "ryan", "sophia", "thomas", "isabella", "william", "mia", "james", "ava", "noah", "charlotte", "ethan", "amelia", "jacob", "evelyn", "mason", "abigail"]; | |
| const LAST_NAMES = ["taylor", "anderson", "thompson", "jackson", "white", "harris", "martin", "thomas", "lewis", "clark", "lee", "walker", "hall", "young", "allen", "king", "wright", "scott", "green", "adams"]; | |
| // Continuous registration control variables - using local storage to maintain state | |
| var isAutoRegistering = GM_getValue('isAutoRegistering', false); | |
| var registrationCount = GM_getValue('registrationCount', 0); | |
| var registeredAccounts = GM_getValue('registeredAccounts', []); // Store successfully registered account information | |
| // ==================== Utility Functions ==================== | |
| // State saving function | |
| function saveState() { | |
| GM_setValue('isAutoRegistering', isAutoRegistering); | |
| GM_setValue('registrationCount', registrationCount); | |
| GM_setValue('registeredAccounts', registeredAccounts); | |
| } | |
| // Clear account information function (only clears registered user information) | |
| function clearAccountsData() { | |
| try { | |
| GM_setValue('registrationCount', 0); | |
| GM_setValue('registeredAccounts', []); | |
| registrationCount = 0; | |
| registeredAccounts = []; | |
| saveState(); | |
| return true; | |
| } catch (error) { | |
| console.error('Failed to clear account data:', error); | |
| return false; | |
| } | |
| } | |
| // Wait for element to appear | |
| async function waitForElement(selector, timeout = 10000) { | |
| const startTime = Date.now(); | |
| while (Date.now() - startTime < timeout) { | |
| const element = document.querySelector(selector); | |
| if (element) return element; | |
| await new Promise(resolve => setTimeout(resolve, 100)); | |
| } | |
| return null; | |
| } | |
| // Wait for page transition | |
| async function waitForPageTransition(selector, timeout = 10000) { | |
| const startTime = Date.now(); | |
| while (Date.now() - startTime < timeout) { | |
| if (typeof selector === 'string' && selector.includes('.com')) { | |
| if (window.location.href.includes(selector)) return true; | |
| } else { | |
| if (document.querySelector(selector)) return true; | |
| } | |
| await new Promise(resolve => setTimeout(resolve, 500)); | |
| } | |
| return false; | |
| } | |
| // Generate random email | |
| function generateEmail() { | |
| const firstName = FIRST_NAMES[Math.floor(Math.random() * FIRST_NAMES.length)]; | |
| const lastName = LAST_NAMES[Math.floor(Math.random() * LAST_NAMES.length)]; | |
| const timestamp = Date.now().toString(36); | |
| const randomNum = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); | |
| const username = `${firstName}${lastName}${timestamp}${randomNum}`; | |
| return `${username}${EMAIL_DOMAIN}`; | |
| } | |
| // Extract verification code | |
| function extractVerificationCode(text) { | |
| const patterns = [ | |
| /Your verification code is: <b>(\d{6})<\/b>/i, | |
| /verification code is[:\s]*([A-Z0-9]{6})/i, | |
| /code[:\s]*([A-Z0-9]{6})/i, | |
| /(?<![a-zA-Z0-9])(\d{6})(?![a-zA-Z0-9])/ | |
| ]; | |
| for (const pattern of patterns) { | |
| const match = text.match(pattern); | |
| if (match) return match[1] || match[0]; | |
| } | |
| return null; | |
| } | |
| // ==================== Email Processing Functions ==================== | |
| // Color configuration | |
| const COLORS = { | |
| primary: '#3498db', | |
| secondary: '#2ecc71', | |
| danger: '#e74c3c', | |
| warning: '#f39c12', | |
| info: '#34495e', | |
| light: '#ecf0f1', | |
| dark: '#2c3e50', | |
| background: 'rgba(30, 30, 30, 0.95)' | |
| }; | |
| // Log UI configuration | |
| const LOG_UI_CONFIG = { | |
| position: { | |
| bottom: 40, | |
| left: 20 | |
| }, | |
| dimensions: { | |
| width: 320, | |
| maxHeight: 450 | |
| } | |
| }; | |
| // Create log UI - positioned at bottom left, updated styles and colors | |
| function createLogUI() { | |
| const logContainer = document.createElement('div'); | |
| logContainer.id = "auto-register-log"; | |
| logContainer.style.cssText = ` | |
| position: fixed; | |
| bottom: ${LOG_UI_CONFIG.position.bottom}px; | |
| left: ${LOG_UI_CONFIG.position.left}px; | |
| width: ${LOG_UI_CONFIG.dimensions.width}px; | |
| max-height: ${LOG_UI_CONFIG.dimensions.maxHeight}px; | |
| background: ${COLORS.background}; | |
| border-radius: 10px; | |
| box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); | |
| z-index: 10000; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| `; | |
| logContainer.innerHTML = ` | |
| <div style=" | |
| padding: 14px 16px; | |
| background: ${COLORS.primary}; | |
| color: white; | |
| font-weight: 600; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| border-bottom: 2px solid ${COLORS.secondary}; | |
| "> | |
| <span>Auto Registration Assistant</span> | |
| <div> | |
| <button id="start-continuous-registration" style=" | |
| background: ${COLORS.secondary}; | |
| border: none; | |
| color: white; | |
| cursor: pointer; | |
| font-size: 13px; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| margin-right: 8px; | |
| transition: all 0.2s ease; | |
| ">Start Continuous Registration</button> | |
| <button id="stop-registration" style=" | |
| background: ${COLORS.error}; | |
| border: none; | |
| color: white; | |
| cursor: pointer; | |
| font-size: 13px; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| margin-right: 8px; | |
| display: none; | |
| transition: all 0.2s ease; | |
| ">Stop Registration</button> | |
| <button id="export-accounts" style=" | |
| background: ${COLORS.primary}; | |
| border: none; | |
| color: white; | |
| cursor: pointer; | |
| font-size: 13px; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| margin-right: 8px; | |
| transition: all 0.2s ease; | |
| ">Export Accounts</button> | |
| <button id="clear-state" style=" | |
| background: ${COLORS.warning}; | |
| border: none; | |
| color: white; | |
| cursor: pointer; | |
| font-size: 13px; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| margin-right: 8px; | |
| transition: all 0.2s ease; | |
| ">Clear Accounts</button> | |
| <button id="clear-log" style=" | |
| background: transparent; | |
| border: 1px solid rgba(255, 255, 255, 0.7); | |
| color: white; | |
| cursor: pointer; | |
| font-size: 13px; | |
| padding: 6px 12px; | |
| border-radius: 4px; | |
| transition: all 0.2s ease; | |
| ">Clear</button> | |
| <button id="minimize-log" style=" | |
| background: transparent; | |
| border: none; | |
| color: white; | |
| cursor: pointer; | |
| font-size: 16px; | |
| padding: 6px 12px; | |
| margin-left: 8px; | |
| transition: all 0.2s ease; | |
| ">_</button> | |
| </div> | |
| </div> | |
| <div style=" | |
| padding: 8px 16px; | |
| background: ${COLORS.dark}; | |
| border-bottom: 1px solid ${COLORS.info}; | |
| font-size: 12px; | |
| color: ${COLORS.light}; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| "> | |
| <span style="color: ${COLORS.secondary};">📢</span> | |
| <span>Control Panel</span> | |
| </div> | |
| <div id="registration-status" style=" | |
| padding: 8px 16px; | |
| background: ${COLORS.background}; | |
| border-bottom: 1px solid ${COLORS.border}; | |
| font-size: 12px; | |
| color: ${COLORS.text}; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| "> | |
| <span>Status: <span id="status-text">Not Started</span></span> | |
| <span>Registered: <span id="account-count">0</span> accounts</span> | |
| </div> | |
| <div id="log-content" style=" | |
| padding: 16px; | |
| overflow-y: auto; | |
| max-height: calc(${LOG_UI_CONFIG.dimensions.maxHeight}px - 120px); | |
| font-size: 14px; | |
| color: ${COLORS.light}; | |
| line-height: 1.5; | |
| "></div> | |
| `; | |
| document.body.appendChild(logContainer); | |
| // Minimize functionality | |
| let isMinimized = false; | |
| const logContent = document.getElementById('log-content'); | |
| const minimizeBtn = document.getElementById('minimize-log'); | |
| minimizeBtn.addEventListener('click', () => { | |
| isMinimized = !isMinimized; | |
| logContent.style.display = isMinimized ? 'none' : 'block'; | |
| minimizeBtn.textContent = isMinimized ? '▢' : '_'; | |
| }); | |
| // Clear log functionality | |
| const clearBtn = document.getElementById('clear-log'); | |
| clearBtn.addEventListener('click', () => { | |
| logContent.innerHTML = ''; | |
| log('Log cleared', 'info'); | |
| }); | |
| // Button event handling | |
| const startBtn = document.getElementById('start-continuous-registration'); | |
| const stopBtn = document.getElementById('stop-registration'); | |
| const exportBtn = document.getElementById('export-accounts'); | |
| const clearStateBtn = document.getElementById('clear-state'); | |
| // Start continuous registration | |
| startBtn.addEventListener('click', () => { | |
| startContinuousRegistration(); | |
| }); | |
| // Stop registration | |
| stopBtn.addEventListener('click', () => { | |
| stopContinuousRegistration(); | |
| }); | |
| // Export accounts | |
| exportBtn.addEventListener('click', () => { | |
| exportAccounts(); | |
| }); | |
| // Clear account data | |
| clearStateBtn.addEventListener('click', () => { | |
| // Show state before clearing | |
| logger.log(`Account data before clearing: Count=${registrationCount}, Accounts=${registeredAccounts.length}`, 'info'); | |
| logger.log(`Storage values before clearing: Count=${GM_getValue('registrationCount')}, Accounts=${GM_getValue('registeredAccounts', []).length}`, 'info'); | |
| if (confirm('Are you sure you want to clear all registered account information? (Will not affect current registration status)')) { | |
| const clearResult = clearAccountsData(); | |
| if (clearResult) { | |
| // Immediately update UI display | |
| updateRegistrationStatus(); | |
| // Verify clearing result | |
| logger.log(`Account data after clearing: Count=${registrationCount}, Accounts=${registeredAccounts.length}`, 'info'); | |
| logger.log(`Storage values after clearing: Count=${GM_getValue('registrationCount')}, Accounts=${GM_getValue('registeredAccounts', []).length}`, 'info'); | |
| logger.log(`Registration status maintained: ${isAutoRegistering ? 'Continuous registration in progress' : 'Stopped'}`, 'info'); | |
| if (registrationCount === 0 && registeredAccounts.length === 0) { | |
| logger.log('✅ Account data cleared successfully!', 'success'); | |
| } else { | |
| logger.log('❌ Account data clearing may have failed, please check', 'error'); | |
| } | |
| // Test export function to verify | |
| setTimeout(() => { | |
| logger.log('Verifying clearing result: Testing export function...', 'info'); | |
| exportAccounts(); | |
| }, 1000); | |
| } else { | |
| logger.log('❌ Failed to clear account data', 'error'); | |
| } | |
| } | |
| }); | |
| // Button hover effects | |
| [startBtn, stopBtn, exportBtn, clearStateBtn].forEach(btn => { | |
| if (btn) { | |
| btn.addEventListener('mouseenter', () => { | |
| btn.style.transform = 'scale(1.05)'; | |
| }); | |
| btn.addEventListener('mouseleave', () => { | |
| btn.style.transform = 'scale(1)'; | |
| }); | |
| } | |
| }); | |
| // Restore button display based on saved state | |
| if (isAutoRegistering) { | |
| if (startBtn) startBtn.style.display = 'none'; | |
| if (stopBtn) stopBtn.style.display = 'inline-block'; | |
| } else { | |
| if (startBtn) startBtn.style.display = 'inline-block'; | |
| if (stopBtn) stopBtn.style.display = 'none'; | |
| } | |
| // Restore status display | |
| updateRegistrationStatus(); | |
| return { | |
| log: function(message, type = 'info') { | |
| const logEntry = document.createElement('div'); | |
| logEntry.style.marginBottom = '10px'; | |
| logEntry.style.padding = '12px'; | |
| logEntry.style.borderRadius = '6px'; | |
| logEntry.style.wordBreak = 'break-all'; | |
| logEntry.style.transition = 'all 0.3s ease'; | |
| let bgColor, textColor; | |
| switch(type) { | |
| case 'success': | |
| bgColor = 'rgba(46, 204, 113, 0.2)'; | |
| textColor = COLORS.secondary; | |
| break; | |
| case 'error': | |
| bgColor = 'rgba(231, 76, 60, 0.2)'; | |
| textColor = COLORS.danger; | |
| break; | |
| case 'warning': | |
| bgColor = 'rgba(243, 156, 17, 0.2)'; | |
| textColor = COLORS.warning; | |
| break; | |
| default: | |
| bgColor = 'rgba(255, 255, 255, 0.05)'; | |
| textColor = COLORS.light; | |
| } | |
| logEntry.style.backgroundColor = bgColor; | |
| logEntry.style.color = textColor; | |
| const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute:'2-digit', second:'2-digit' }); | |
| logEntry.textContent = `[${time}] ${message}`; | |
| logContent.appendChild(logEntry); | |
| logContent.scrollTop = logContent.scrollHeight; | |
| } | |
| }; | |
| } | |
| // Create global logger object | |
| const logger = createLogUI(); | |
| // Delete email | |
| async function deleteEmail(firstId) { | |
| return new Promise((resolve, reject) => { | |
| const deleteUrl = 'https://tempmail.plus/api/mails/'; | |
| const maxRetries = 5; | |
| let retryCount = 0; | |
| function tryDelete() { | |
| GM_xmlhttpRequest({ | |
| method: "DELETE", | |
| url: deleteUrl, | |
| data: `email=${TEMP_MAIL_CONFIG.username}${TEMP_MAIL_CONFIG.emailExtension}&first_id=${firstId}&epin=${TEMP_MAIL_CONFIG.epin}`, | |
| headers: { | |
| "Content-Type": "application/x-www-form-urlencoded" | |
| }, | |
| onload: function(response) { | |
| try { | |
| const result = JSON.parse(response.responseText).result; | |
| if (result === true) { | |
| logger.log("Email deleted successfully", 'success'); | |
| resolve(true); | |
| return; | |
| } | |
| } catch (error) { | |
| logger.log("Failed to parse delete response: " + error, 'warning'); | |
| } | |
| // If there are still retries left, continue trying | |
| if (retryCount < maxRetries - 1) { | |
| retryCount++; | |
| logger.log(`Failed to delete email, retrying (${retryCount}/${maxRetries})...`, 'warning'); | |
| setTimeout(tryDelete, 500); | |
| } else { | |
| logger.log("Failed to delete email, reached maximum retry attempts", 'error'); | |
| resolve(false); | |
| } | |
| }, | |
| onerror: function(error) { | |
| if (retryCount < maxRetries - 1) { | |
| retryCount++; | |
| logger.log(`Error deleting email, retrying (${retryCount}/${maxRetries})...`, 'warning'); | |
| setTimeout(tryDelete, 500); | |
| } else { | |
| logger.log("Failed to delete email: " + error, 'error'); | |
| resolve(false); | |
| } | |
| } | |
| }); | |
| } | |
| tryDelete(); | |
| }); | |
| } | |
| // Get verification code from latest email | |
| async function getLatestMailCode() { | |
| return new Promise((resolve, reject) => { | |
| const mailListUrl = `https://tempmail.plus/api/mails?email=${TEMP_MAIL_CONFIG.username}${TEMP_MAIL_CONFIG.emailExtension}&limit=20&epin=${TEMP_MAIL_CONFIG.epin}`; | |
| GM_xmlhttpRequest({ | |
| method: "GET", | |
| url: mailListUrl, | |
| onload: async function(mailListResponse) { | |
| try { | |
| const mailListData = JSON.parse(mailListResponse.responseText); | |
| if (!mailListData.result || !mailListData.first_id) { | |
| resolve(null); | |
| return; | |
| } | |
| const firstId = mailListData.first_id; | |
| const mailDetailUrl = `https://tempmail.plus/api/mails/${firstId}?email=${TEMP_MAIL_CONFIG.username}${TEMP_MAIL_CONFIG.emailExtension}&epin=${TEMP_MAIL_CONFIG.epin}`; | |
| GM_xmlhttpRequest({ | |
| method: "GET", | |
| url: mailDetailUrl, | |
| onload: async function(mailDetailResponse) { | |
| try { | |
| const mailDetailData = JSON.parse(mailDetailResponse.responseText); | |
| if (!mailDetailData.result) { | |
| resolve(null); | |
| return; | |
| } | |
| const mailText = mailDetailData.text || ""; | |
| const mailSubject = mailDetailData.subject || ""; | |
| logger.log("Found email subject: " + mailSubject); | |
| const code = extractVerificationCode(mailText); | |
| // After getting the code, try to delete the email | |
| if (code) { | |
| await deleteEmail(firstId); | |
| } | |
| resolve(code); | |
| } catch (error) { | |
| logger.log("Failed to parse email details: " + error, 'error'); | |
| resolve(null); | |
| } | |
| }, | |
| onerror: function(error) { | |
| logger.log("Failed to get email details: " + error, 'error'); | |
| resolve(null); | |
| } | |
| }); | |
| } catch (error) { | |
| logger.log("Failed to parse email list: " + error, 'error'); | |
| resolve(null); | |
| } | |
| }, | |
| onerror: function(error) { | |
| logger.log("Failed to get email list: " + error, 'error'); | |
| resolve(null); | |
| } | |
| }); | |
| }); | |
| } | |
| // Get verification code (with retry mechanism) | |
| async function getVerificationCode(maxRetries = 5, retryInterval = 3000) { | |
| for (let attempt = 0; attempt < maxRetries; attempt++) { | |
| logger.log(`Attempting to get verification code (Attempt ${attempt + 1}/${maxRetries})...`); | |
| try { | |
| const code = await getLatestMailCode(); | |
| if (code) { | |
| logger.log("Successfully obtained verification code: " + code, 'success'); | |
| return code; | |
| } | |
| if (attempt < maxRetries - 1) { | |
| logger.log(`No verification code received, retrying in ${retryInterval/1000} seconds...`, 'warning'); | |
| await new Promise(resolve => setTimeout(resolve, retryInterval)); | |
| } | |
| } catch (error) { | |
| logger.log("Error getting verification code: " + error, 'error'); | |
| if (attempt < maxRetries - 1) { | |
| await new Promise(resolve => setTimeout(resolve, retryInterval)); | |
| } | |
| } | |
| } | |
| throw new Error(`Failed to get verification code after ${maxRetries} attempts.`); | |
| } | |
| // Handle human verification | |
| async function handleHumanVerification() { | |
| logger.log('Waiting for human verification to appear...', 'info'); | |
| let verifyCheckbox = null; | |
| let waitTime = 7; | |
| for (let i = 0; i < waitTime; i++) { | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| // First check if verification is already successful | |
| const successText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes('Success!') | |
| ); | |
| if (successText && successText.offsetParent !== null) { | |
| logger.log('Human verification completed', 'success'); | |
| return true; | |
| } | |
| // Check if there's a human verification checkbox | |
| verifyCheckbox = document.querySelector('input[type="checkbox"]'); | |
| if (verifyCheckbox) { | |
| logger.log('Found human verification checkbox', 'info'); | |
| break; | |
| } | |
| logger.log(`Waiting for human verification to appear... (${i + 1}/${waitTime} seconds)`, 'info'); | |
| } | |
| if (!verifyCheckbox) { | |
| logger.log('No human verification requirement found, may have already passed or not needed', 'info'); | |
| return true; | |
| } | |
| // Click human verification checkbox | |
| logger.log('Clicking human verification checkbox...', 'info'); | |
| verifyCheckbox.click(); | |
| // Wait for verification to complete, maximum 60 seconds | |
| for (let i = 0; i < 60; i++) { | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| // Check if verification is in progress | |
| const verifyingText = document.querySelector('#verifying-text'); | |
| if (verifyingText && verifyingText.textContent.includes('Verifying')) { | |
| logger.log(`Human verification in progress... (${i + 1}/60 seconds)`, 'info'); | |
| continue; | |
| } | |
| // Check if verification succeeded | |
| const successText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes('Success!') | |
| ); | |
| if (successText && successText.textContent.includes('Success!')) { | |
| if (successText.offsetParent !== null) { | |
| logger.log('✅ Human verification successful! Detected Success! flag', 'success'); | |
| return true; | |
| } else { | |
| logger.log('Success! text exists but not visible, continuing to wait...', 'info'); | |
| } | |
| } | |
| // Check if verification failed or needs re-verification | |
| const newCheckbox = document.querySelector('input[type="checkbox"]'); | |
| if (newCheckbox && !newCheckbox.checked) { | |
| logger.log('Verification failed, needs re-verification', 'warning'); | |
| newCheckbox.click(); | |
| await new Promise(resolve => setTimeout(resolve, 2000)); | |
| continue; | |
| } | |
| } | |
| // Final check of verification status | |
| const finalSuccessText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes('Success!') | |
| ); | |
| if (finalSuccessText && finalSuccessText.offsetParent !== null) { | |
| logger.log('Human verification finally successful! Detected Success! text', 'success'); | |
| return true; | |
| } | |
| logger.log('Human verification timeout or failure - Success! flag not detected', 'error'); | |
| return false; | |
| } | |
| // Detect registration success and save information | |
| async function checkRegistrationSuccess() { | |
| logger.log('Waiting for registration result...', 'info'); | |
| // Wait up to 30 seconds to detect registration result | |
| for (let i = 0; i < 30; i++) { | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| // Detect error messages | |
| const errorElements = document.querySelectorAll('.error, .alert-danger, [role="alert"], .rt-Text[color="red"]'); | |
| if (errorElements.length > 0) { | |
| const errorText = Array.from(errorElements).map(el => el.textContent.trim()).join('; '); | |
| logger.log('❌ Registration failed: ' + errorText, 'error'); | |
| return false; | |
| } | |
| // Detect success flag: page redirected to subscription page | |
| if (window.location.href.includes('app.augmentcode.com/account/subscription')) { | |
| logger.log('✅ Registration successful! Redirected to subscription page', 'success'); | |
| return true; | |
| } | |
| } | |
| logger.log('⏳ Registration status detection timeout, please check manually', 'warning'); | |
| return false; | |
| } | |
| // ==================== Main Process Control Functions ==================== | |
| // Execute complete registration process | |
| async function executeFullRegistration() { | |
| logger.log('🚀 Starting complete registration process', 'info'); | |
| try { | |
| // Check if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, terminating process', 'warning'); | |
| return false; | |
| } | |
| // Step 1: Handle email input and human verification | |
| logger.log('📧 Step 1: Processing email input page', 'info'); | |
| const firstPageResult = await handleFirstPage(); | |
| if (!firstPageResult) { | |
| logger.log('❌ First page processing failed', 'error'); | |
| return false; | |
| } | |
| // Check if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, terminating process', 'warning'); | |
| return false; | |
| } | |
| // Wait for page transition to verification code page | |
| logger.log('⏳ Waiting for transition to verification code page...', 'info'); | |
| await waitForPageTransition('input[name="code"]', 10000); | |
| // Check if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, terminating process', 'warning'); | |
| return false; | |
| } | |
| // Step 2: Handle verification code input | |
| logger.log('🔢 Step 2: Processing verification code input page', 'info'); | |
| const secondPageResult = await handleSecondPage(); | |
| if (!secondPageResult) { | |
| logger.log('❌ Second page processing failed or registration rejected', 'warning'); | |
| // If in continuous registration mode and registration was rejected, wait and restart | |
| if (isAutoRegistering) { | |
| logger.log('🔄 Continuous registration mode: Waiting 5 seconds before restarting registration process...', 'info'); | |
| await new Promise(resolve => setTimeout(resolve, 5000)); | |
| // Check if already redirected to registration page | |
| if (document.querySelector('input[name="username"]') || | |
| window.location.href.includes('login.augmentcode.com')) { | |
| logger.log('🔄 Returned to registration page, restarting registration process', 'info'); | |
| return await executeFullRegistration(); // Recursively restart | |
| } | |
| } | |
| return false; | |
| } | |
| // Wait for page transition to success page | |
| logger.log('⏳ Waiting for transition to success page...', 'info'); | |
| await waitForPageTransition('app.augmentcode.com/account/subscription', 15000); | |
| // Check if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, terminating process', 'warning'); | |
| return false; | |
| } | |
| // Step 3: Handle success page | |
| logger.log('🎉 Step 3: Processing success page', 'info'); | |
| const thirdPageResult = await handleThirdPage(); | |
| if (!thirdPageResult) { | |
| logger.log('❌ Third page processing failed', 'error'); | |
| return false; | |
| } | |
| logger.log('✅ Complete registration process executed successfully!', 'success'); | |
| return true; | |
| } catch (error) { | |
| logger.log(`❌ Registration process execution error: ${error}`, 'error'); | |
| return false; | |
| } | |
| } | |
| // Main function - only responsible for page detection and routing | |
| async function main() { | |
| logger.log('🔍 Detecting current page type...', 'info'); | |
| // Detect third page: success page | |
| if (window.location.href.includes('app.augmentcode.com/account/subscription')) { | |
| logger.log('📄 Detected third page: success page', 'info'); | |
| if (isAutoRegistering) { | |
| await handleThirdPage(); | |
| } | |
| return; | |
| } | |
| // Detect second page: verification code input page | |
| const emailSentText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes("We've sent an email with your code to") | |
| ); | |
| if (document.querySelector('input[name="code"]') || emailSentText) { | |
| logger.log('📄 Detected second page: verification code input page', 'info'); | |
| if (emailSentText) { | |
| const emailMatch = emailSentText.textContent.match(/to\s+([^\s]+@[^\s]+)/); | |
| if (emailMatch) { | |
| logger.log(`📧 Verification code sent to: ${emailMatch[1]}`, 'info'); | |
| } | |
| } | |
| if (isAutoRegistering) { | |
| await handleSecondPage(); | |
| } | |
| return; | |
| } | |
| // Detect registration rejected page | |
| const rejectedText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes('Sign-up rejected') | |
| ); | |
| if (rejectedText) { | |
| logger.log('📄 Detected registration rejected page', 'warning'); | |
| if (isAutoRegistering) { | |
| logger.log('🔄 Continuous registration mode: Automatically handling registration rejection', 'info'); | |
| await handleSignupRejectedPage(); | |
| } else { | |
| logger.log('💡 Registration rejected detected, please manually click retry link', 'warning'); | |
| } | |
| return; | |
| } | |
| // Detect first page: email input page | |
| const googleButton = Array.from(document.querySelectorAll('button')).find(btn => | |
| btn.textContent && btn.textContent.includes('Continue with Google') | |
| ); | |
| if (document.querySelector('input[name="username"]') || googleButton) { | |
| logger.log('📄 Detected first page: email input page', 'info'); | |
| if (googleButton) { | |
| logger.log('🔍 Detected Google login button, confirmed as registration page', 'info'); | |
| } | |
| if (isAutoRegistering) { | |
| logger.log('🔄 Continuous registration mode: Automatically starting registration process', 'info'); | |
| await executeFullRegistration(); | |
| } else { | |
| logger.log('💡 Please click "Start Continuous Registration" button to begin auto registration', 'info'); | |
| } | |
| return; | |
| } | |
| // Detect if on registration-related pages | |
| if (!window.location.href.includes('login.augmentcode.com') && | |
| !window.location.href.includes('auth.augmentcode.com')) { | |
| logger.log('⚠️ Current page is not a registration page, script will not execute', 'warning'); | |
| return; | |
| } | |
| logger.log('❓ Unable to identify current page status, waiting for page to load...', 'warning'); | |
| } | |
| // Handle third page: success page (subscription page) | |
| async function handleThirdPage() { | |
| logger.log('Detected subscription page, starting to extract account information...', 'info'); | |
| try { | |
| // Wait for page elements to load | |
| await new Promise(resolve => setTimeout(resolve, 3000)); | |
| // Extract credit information | |
| let credits = '0'; | |
| const creditElement = document.querySelector('span.rt-Text.rt-r-size-5.rt-r-weight-medium'); | |
| if (creditElement) { | |
| // Get initial value | |
| const initialText = creditElement.textContent.trim(); | |
| const initialMatch = initialText.match(/(\d+)/); | |
| const initialCredits = initialMatch ? initialMatch[1] : '0'; | |
| // Wait a few seconds to see if there are changes | |
| await new Promise(resolve => setTimeout(resolve, 3000)); | |
| // Get updated value | |
| const updatedText = creditElement.textContent.trim(); | |
| const updatedMatch = updatedText.match(/(\d+)/); | |
| const updatedCredits = updatedMatch ? updatedMatch[1] : '0'; | |
| // Use new value if changed, otherwise use initial value | |
| credits = updatedCredits !== initialCredits ? updatedCredits : initialCredits; | |
| logger.log(`Detected account credits: ${credits}`, 'success'); | |
| } else { | |
| logger.log('Credit information element not found', 'warning'); | |
| } | |
| // Extract email information | |
| const emailElement = document.querySelector('[data-testid="user-email"]'); | |
| let email = ''; | |
| if (emailElement) { | |
| email = emailElement.textContent.trim(); | |
| logger.log(`Detected registered email: ${email}`, 'success'); | |
| } else { | |
| logger.log('Email information element not found', 'warning'); | |
| } | |
| // Save account information | |
| if (email) { | |
| const accountInfo = { | |
| email: email, | |
| credits: credits, | |
| registeredAt: new Date().toISOString() | |
| }; | |
| registeredAccounts.push(accountInfo); | |
| registrationCount++; | |
| // Save state to local storage | |
| saveState(); | |
| // Update UI display | |
| updateRegistrationStatus(); | |
| logger.log(`Account information saved: ${email} (Credits: ${credits})`, 'success'); | |
| } | |
| // Check if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, not executing logout', 'warning'); | |
| return true; | |
| } | |
| // Wait a bit before clicking logout | |
| await new Promise(resolve => setTimeout(resolve, 2000)); | |
| // Check again if registration has been stopped | |
| if (!isAutoRegistering) { | |
| logger.log('⏹️ Registration stopped, not executing logout', 'warning'); | |
| return true; | |
| } | |
| // Click logout button | |
| const logoutBtn = document.querySelector('[data-testid="logout-button"]'); | |
| if (logoutBtn) { | |
| logoutBtn.click(); | |
| logger.log('Clicked logout button', 'success'); | |
| // Wait for page transition | |
| await new Promise(resolve => setTimeout(resolve, 3000)); | |
| // Final check if still in continuous registration mode | |
| if (isAutoRegistering) { | |
| logger.log('Preparing for next registration round...', 'info'); | |
| setTimeout(() => { | |
| window.location.reload(); | |
| }, 2000); | |
| } else { | |
| logger.log('⏹️ Registration stopped, not continuing to next round', 'warning'); | |
| } | |
| } else { | |
| logger.log('Logout button not found', 'error'); | |
| } | |
| } catch (error) { | |
| logger.log('Error processing subscription page: ' + error, 'error'); | |
| } | |
| } | |
| // ==================== UI Control and State Management Functions ==================== | |
| // Start continuous registration | |
| function startContinuousRegistration() { | |
| isAutoRegistering = true; | |
| saveState(); // Save state to local storage | |
| updateRegistrationStatus(); | |
| logger.log('🚀 Starting continuous registration mode', 'success'); | |
| // Update button states | |
| const startBtn = document.getElementById('start-continuous-registration'); | |
| const stopBtn = document.getElementById('stop-registration'); | |
| if (startBtn) startBtn.style.display = 'none'; | |
| if (stopBtn) stopBtn.style.display = 'inline-block'; | |
| // If not currently on registration page, automatically redirect | |
| if (!window.location.href.includes('login.augmentcode.com') && | |
| !window.location.href.includes('auth.augmentcode.com') && | |
| !window.location.href.includes('app.augmentcode.com/account/subscription')) { | |
| logger.log('🔄 Redirecting to registration page to start continuous registration...', 'info'); | |
| window.location.href = 'https://login.augmentcode.com/signup'; | |
| } else { | |
| // If already on relevant page, start execution immediately | |
| logger.log('📍 Already on relevant page, starting registration process immediately...', 'info'); | |
| setTimeout(() => { | |
| executeFullRegistration().catch(error => { | |
| logger.log('Registration process execution error: ' + error, 'error'); | |
| }); | |
| }, 1000); | |
| } | |
| } | |
| // Stop continuous registration | |
| function stopContinuousRegistration() { | |
| isAutoRegistering = false; | |
| saveState(); // Save state to local storage | |
| updateRegistrationStatus(); | |
| logger.log('Stopped continuous registration mode', 'warning'); | |
| // Update button states | |
| const startBtn = document.getElementById('start-continuous-registration'); | |
| const stopBtn = document.getElementById('stop-registration'); | |
| if (startBtn) startBtn.style.display = 'inline-block'; | |
| if (stopBtn) stopBtn.style.display = 'none'; | |
| } | |
| // Update registration status display | |
| function updateRegistrationStatus() { | |
| const statusText = document.getElementById('status-text'); | |
| const accountCount = document.getElementById('account-count'); | |
| if (statusText) { | |
| statusText.textContent = isAutoRegistering ? 'Continuous Registration' : 'Stopped'; | |
| } | |
| if (accountCount) { | |
| accountCount.textContent = registrationCount; | |
| } | |
| } | |
| // Export account information | |
| function exportAccounts() { | |
| if (registeredAccounts.length === 0) { | |
| logger.log('No account information to export', 'warning'); | |
| return; | |
| } | |
| // Generate export content | |
| let exportContent = ''; | |
| registeredAccounts.forEach(account => { | |
| exportContent += `${account.email}\n${account.credits}\n\n`; | |
| }); | |
| // Create download link | |
| const blob = new Blob([exportContent], { type: 'text/plain' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `augmentcode_accounts_${new Date().toISOString().slice(0, 10)}.txt`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| logger.log(`Exported ${registeredAccounts.length} account information`, 'success'); | |
| } | |
| // ==================== Page Processing Functions ==================== | |
| // Handle first page: email input and human verification | |
| async function handleFirstPage() { | |
| logger.log('Starting to process first page: email input and human verification', 'info'); | |
| // 1. Check and fill email | |
| const emailInput = await waitForElement('input[name="username"]'); | |
| if (!emailInput) { | |
| logger.log('Email input field not found', 'error'); | |
| return false; | |
| } | |
| // Check if email is already pre-filled (retry after rejection case) | |
| const existingEmail = emailInput.value.trim(); | |
| if (existingEmail) { | |
| logger.log(`Detected pre-filled email: ${existingEmail}`, 'info'); | |
| logger.log('Skipping email filling, using pre-filled email', 'success'); | |
| } else { | |
| // No pre-filled email, generate new email | |
| const email = generateEmail(); | |
| logger.log('Using email: ' + email); | |
| logger.log('Found email input field, starting to fill'); | |
| emailInput.value = email; | |
| emailInput.dispatchEvent(new Event('input', { bubbles: true })); | |
| logger.log('Email filled successfully', 'success'); | |
| } | |
| // 2. Wait and handle human verification | |
| logger.log('Starting human verification process...', 'info'); | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| const verificationResult = await handleHumanVerification(); | |
| if (!verificationResult) { | |
| logger.log('Human verification failed, waiting 5 seconds to retry...', 'warning'); | |
| await new Promise(resolve => setTimeout(resolve, 5000)); | |
| const retryResult = await handleHumanVerification(); | |
| if (!retryResult) { | |
| logger.log('Human verification retry failed, stopping current registration process', 'error'); | |
| return false; | |
| } | |
| } | |
| // 3. After successful human verification, click continue button | |
| const continueBtn = await waitForElement('button[type="submit"]'); | |
| if (!continueBtn) { | |
| logger.log('Continue button not found', 'error'); | |
| return false; | |
| } | |
| logger.log('Human verification completed, clicking continue button'); | |
| continueBtn.click(); | |
| logger.log('First page processing completed', 'success'); | |
| return true; | |
| } | |
| // Handle second page: verification code input | |
| async function handleSecondPage() { | |
| logger.log('Starting to process second page: verification code input', 'info'); | |
| // 1. Get verification code | |
| const code = await getVerificationCode(); | |
| if (!code) { | |
| logger.log('Failed to get verification code', 'error'); | |
| return false; | |
| } | |
| // 2. Fill verification code | |
| const codeInput = await waitForElement('input[name="code"]'); | |
| if (!codeInput) { | |
| logger.log('Verification code input field not found', 'error'); | |
| return false; | |
| } | |
| logger.log('Found verification code input field, starting to fill'); | |
| codeInput.value = code; | |
| codeInput.dispatchEvent(new Event('input', { bubbles: true })); | |
| logger.log('Verification code filled successfully', 'success'); | |
| // 3. Click continue button | |
| const continueBtn = await waitForElement('button[type="submit"]'); | |
| if (!continueBtn) { | |
| logger.log('Continue button not found', 'error'); | |
| return false; | |
| } | |
| logger.log('Clicking continue button'); | |
| continueBtn.click(); | |
| // 4. Wait and detect registration result | |
| logger.log('Waiting for registration to complete...', 'info'); | |
| await new Promise(resolve => setTimeout(resolve, 3000)); // Wait for page response | |
| // Check if registration rejected page appears | |
| if (await handleSignupRejectedPage()) { | |
| logger.log('Detected registration rejection, handled retry', 'warning'); | |
| return false; // Return false indicating need to restart process | |
| } | |
| // Detect registration success | |
| await checkRegistrationSuccess(); | |
| logger.log('Second page processing completed', 'success'); | |
| return true; | |
| } | |
| // Handle registration rejected page | |
| async function handleSignupRejectedPage() { | |
| logger.log('Checking if registration rejected page appears...', 'info'); | |
| // Detect if page contains "Sign-up rejected" text | |
| const rejectedText = Array.from(document.querySelectorAll('*')).find(el => | |
| el.textContent && el.textContent.includes('Sign-up rejected') | |
| ); | |
| if (rejectedText) { | |
| logger.log('⚠️ Detected registration rejected page', 'warning'); | |
| // Find "Try again here" link | |
| const tryAgainLink = document.querySelector('a[href*="/login"]'); | |
| if (tryAgainLink) { | |
| logger.log('Found retry link, clicking...', 'info'); | |
| tryAgainLink.click(); | |
| // Wait for page transition | |
| await new Promise(resolve => setTimeout(resolve, 3000)); | |
| logger.log('Clicked retry link, page will redirect to registration page', 'success'); | |
| return true; // Return true indicating handled rejection page | |
| } else { | |
| logger.log('Retry link not found', 'error'); | |
| return false; | |
| } | |
| } | |
| return false; // No rejection page detected | |
| } | |
| // Start script | |
| main().catch(error => logger.log('Script execution error: ' + error, 'error')); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment