first init
This commit is contained in:
parent
593ffbf289
commit
3990aeb478
10
.env.example
Normal file
10
.env.example
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# AdsPower 指纹浏览器配置
|
||||||
|
ADSPOWER_USER_ID=k16x0qt2
|
||||||
|
ADSPOWER_API=http://local.adspower.net:50325
|
||||||
|
|
||||||
|
# 数据库配置(必须设置才会持久化)
|
||||||
|
DB_HOST=172.22.222.111
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_USER=auto-register-verdent
|
||||||
|
DB_PASS=Qichen5210523
|
||||||
|
DB_NAME=verdent_accounts
|
||||||
@ -4,7 +4,7 @@ export const config = {
|
|||||||
url: 'https://tempmail.plus/',
|
url: 'https://tempmail.plus/',
|
||||||
username: 'qichen111', // 固定的临时邮箱名称
|
username: 'qichen111', // 固定的临时邮箱名称
|
||||||
pinCode: '147258',
|
pinCode: '147258',
|
||||||
domain: 'qichen.cloud' // 我们注册时使用的域名(随机前缀会投递到此)
|
domain: 'qichen111.asia' // 我们注册时使用的域名(随机前缀会投递到此)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Verdent 注册配置
|
// Verdent 注册配置
|
||||||
|
|||||||
73
index.js
73
index.js
@ -55,50 +55,46 @@ async function main() {
|
|||||||
emailPage = await emailContext.newPage();
|
emailPage = await emailContext.newPage();
|
||||||
registerPage = await registerContext.newPage();
|
registerPage = await registerContext.newPage();
|
||||||
|
|
||||||
// 生成唯一用户名(随机 + 时间)
|
// ========== 初始化:设置临时邮箱 ==========
|
||||||
const localPart = generateUsername('qichen');
|
console.log('\n📧 === 初始化: 设置临时邮箱 ===');
|
||||||
|
|
||||||
// ========== 第一步:设置临时邮箱 ==========
|
|
||||||
console.log('\n📧 === 步骤 1: 设置临时邮箱 ===');
|
|
||||||
const { inboxReady } = await setupTempMail(emailPage);
|
const { inboxReady } = await setupTempMail(emailPage);
|
||||||
if (!inboxReady) {
|
if (!inboxReady) {
|
||||||
throw new Error('未能成功创建临时邮箱');
|
throw new Error('未能成功创建临时邮箱');
|
||||||
}
|
}
|
||||||
const email = `${localPart}@${config.tempmail.domain}`;
|
|
||||||
console.log('📧 将用于注册的邮箱:', email);
|
|
||||||
|
|
||||||
// 获取初始基线时间
|
// 获取初始基线时间
|
||||||
await updateBaseline(emailPage);
|
await updateBaseline(emailPage);
|
||||||
|
console.log('✅ 临时邮箱初始化完成\n');
|
||||||
|
|
||||||
// ========== 第二步:在 Verdent 上开始注册 ==========
|
// ========== 循环注册 ==========
|
||||||
console.log('\n🌐 === 步骤 2: 开始 Verdent.ai 注册 ===');
|
while (true) {
|
||||||
const { sentAtMs } = await registerOnVerdent(registerPage, email);
|
try {
|
||||||
|
console.log('\n' + '='.repeat(60));
|
||||||
|
console.log(`🔄 第 ${successCount + failureCount + 1} 次注册尝试 | 成功: ${successCount} | 失败: ${failureCount}`);
|
||||||
|
console.log('='.repeat(60));
|
||||||
|
|
||||||
// ========== 第三步:等待验证码邮件(只取发送后的邮件) ==========
|
// 生成新邮箱(纯随机)
|
||||||
console.log('\n📬 === 步骤 3: 等待验证码邮件 ===');
|
const localPart = generateUsername();
|
||||||
const verificationCode = await waitForVerificationCode(emailPage, sentAtMs, email);
|
const email = `${localPart}@${config.tempmail.domain}`;
|
||||||
|
console.log('📧 本次注册邮箱:', email);
|
||||||
|
|
||||||
if (!verificationCode) {
|
// 执行注册
|
||||||
throw new Error('未能获取验证码');
|
const success = await registerOnce(emailPage, registerPage, email);
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 第四步:完成注册 ==========
|
// 关闭注册页,准备下次
|
||||||
console.log('\n✅ === 步骤 4: 完成注册 ===');
|
|
||||||
const success = await completeRegistration(registerPage, verificationCode);
|
|
||||||
|
|
||||||
// 注册页本次任务结束后关闭,并为下次准备新页签
|
|
||||||
try { await registerPage.close(); } catch {}
|
try { await registerPage.close(); } catch {}
|
||||||
registerPage = await registerContext.newPage();
|
registerPage = await registerContext.newPage();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
successCount++;
|
||||||
console.log('\n🎉 ============================================');
|
console.log('\n🎉 ============================================');
|
||||||
console.log(' 注册流程成功完成!');
|
console.log(' 注册成功!');
|
||||||
console.log('============================================');
|
console.log('============================================');
|
||||||
console.log('📧 邮箱:', email);
|
console.log('📧 邮箱:', email);
|
||||||
console.log('🔑 密码:', config.verdent.password);
|
console.log('🔑 密码:', config.verdent.password);
|
||||||
console.log('============================================\n');
|
console.log('============================================\n');
|
||||||
|
|
||||||
// 邮件页面回退到收件箱列表,避免下次重复输入 PIN
|
// 邮件页面回退到收件箱
|
||||||
try {
|
try {
|
||||||
console.log('[邮箱] 回退到收件箱列表...');
|
console.log('[邮箱] 回退到收件箱列表...');
|
||||||
await emailPage.goBack({ waitUntil: 'domcontentloaded', timeout: 5000 });
|
await emailPage.goBack({ waitUntil: 'domcontentloaded', timeout: 5000 });
|
||||||
@ -110,33 +106,40 @@ async function main() {
|
|||||||
await emailPage.waitForTimeout(1500);
|
await emailPage.waitForTimeout(1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新基线为当前最新邮件时间
|
// 更新基线
|
||||||
await updateBaseline(emailPage);
|
await updateBaseline(emailPage);
|
||||||
|
|
||||||
// 持久化保存(注册时间与过期时间=7天)
|
// 保存到数据库
|
||||||
const createdAt = new Date();
|
const createdAt = new Date();
|
||||||
const expiresAt = new Date(createdAt.getTime() + 7 * 24 * 60 * 60 * 1000);
|
const expiresAt = new Date(createdAt.getTime() + 7 * 24 * 60 * 60 * 1000);
|
||||||
try {
|
try {
|
||||||
await saveAccount({ email, password: config.verdent.password, createdAt, expiresAt, status: 'active' });
|
await saveAccount({ email, password: config.verdent.password, createdAt, expiresAt, status: 'active' });
|
||||||
console.log('[DB] 账号已写入数据库');
|
console.log('[DB] ✅ 账号已写入数据库');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('[DB] 写入失败:', e.message);
|
console.log('[DB] ⚠️ 写入失败:', e.message);
|
||||||
}
|
}
|
||||||
} else if (success === false) {
|
|
||||||
console.log('\n❌ 注册失败,请检查错误信息');
|
|
||||||
} else {
|
} else {
|
||||||
console.log('\n⚠️ 注册状态未知,请手动检查浏览器窗口');
|
failureCount++;
|
||||||
|
console.log('\n❌ 注册失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保持浏览器打开 30 秒以便查看结果
|
// 等待 10 秒后继续下一次
|
||||||
console.log('⏰ 浏览器将在 30 秒后关闭...');
|
console.log('\n⏳ 等待 10 秒后开始下一次注册...');
|
||||||
await new Promise(resolve => setTimeout(resolve, 30000));
|
await new Promise(resolve => setTimeout(resolve, 10000));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('\n❌ 发生错误:', error.message);
|
failureCount++;
|
||||||
|
console.error('\n❌ 注册过程出错:', error.message);
|
||||||
|
console.log('⏳ 等待 10 秒后重试...');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 10000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('\n❌ 初始化失败:', error.message);
|
||||||
console.error(error.stack);
|
console.error(error.stack);
|
||||||
|
|
||||||
// 错误时保持浏览器打开以便调试
|
// 初始化失败时保持浏览器打开以便调试
|
||||||
console.log('⏰ 浏览器将在 60 秒后关闭,请检查问题...');
|
console.log('⏰ 浏览器将在 60 秒后关闭,请检查问题...');
|
||||||
await new Promise(resolve => setTimeout(resolve, 60000));
|
await new Promise(resolve => setTimeout(resolve, 60000));
|
||||||
|
|
||||||
|
|||||||
@ -231,6 +231,26 @@ export async function completeRegistration(page, verificationCode) {
|
|||||||
|
|
||||||
if (!currentUrl.includes('/signup')) {
|
if (!currentUrl.includes('/signup')) {
|
||||||
console.log('🎉 注册成功!');
|
console.log('🎉 注册成功!');
|
||||||
|
|
||||||
|
// 第一步:点击右上角用户头像展开菜单
|
||||||
|
try {
|
||||||
|
console.log('👤 步骤 1: 点击用户头像展开菜单...');
|
||||||
|
const userAvatar = page.locator('.user-avatar').first();
|
||||||
|
await userAvatar.click({ timeout: 5000 });
|
||||||
|
await page.waitForTimeout(1500);
|
||||||
|
|
||||||
|
// 第二步:点击 Dashboard 链接
|
||||||
|
console.log('📊 步骤 2: 点击 Dashboard 链接...');
|
||||||
|
const dashboardLink = page.locator('.link:has-text("Dashboard")').first();
|
||||||
|
await dashboardLink.click({ timeout: 5000 });
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
const finalUrl = page.url();
|
||||||
|
console.log('✅ 已跳转到 Dashboard:', finalUrl);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('⚠️ 跳转 Dashboard 失败:', e.message);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// 检查是否有错误提示
|
// 检查是否有错误提示
|
||||||
|
|||||||
12
schema.sql
Normal file
12
schema.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
-- Verdent 账号表
|
||||||
|
CREATE TABLE IF NOT EXISTS accounts (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
email VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
password VARCHAR(255) NOT NULL,
|
||||||
|
status VARCHAR(50) DEFAULT 'active',
|
||||||
|
created_at DATETIME NOT NULL,
|
||||||
|
expires_at DATETIME NOT NULL,
|
||||||
|
INDEX idx_email (email),
|
||||||
|
INDEX idx_created_at (created_at),
|
||||||
|
INDEX idx_expires_at (expires_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
15
util.js
15
util.js
@ -1,11 +1,8 @@
|
|||||||
export function generateUsername(prefix = 'user') {
|
export function generateUsername() {
|
||||||
|
// 生成纯随机字符串,不包含固定前缀
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const YYYY = now.getFullYear();
|
const timestamp = now.getTime(); // 使用时间戳
|
||||||
const MM = String(now.getMonth() + 1).padStart(2, '0');
|
const rand1 = Math.random().toString(36).slice(2, 8); // 6位随机
|
||||||
const DD = String(now.getDate()).padStart(2, '0');
|
const rand2 = Math.random().toString(36).slice(2, 6); // 4位随机
|
||||||
const hh = String(now.getHours()).padStart(2, '0');
|
return `${rand1}${timestamp}${rand2}`;
|
||||||
const mm = String(now.getMinutes()).padStart(2, '0');
|
|
||||||
const ss = String(now.getSeconds()).padStart(2, '0');
|
|
||||||
const rand = Math.random().toString(36).slice(2, 6);
|
|
||||||
return `${prefix}${YYYY}${MM}${DD}${hh}${mm}${ss}${rand}`;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user