first init

This commit is contained in:
dengqichen 2025-11-13 15:42:34 +08:00
parent 593ffbf289
commit 3990aeb478
6 changed files with 117 additions and 75 deletions

10
.env.example Normal file
View 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

View File

@ -4,7 +4,7 @@ export const config = {
url: 'https://tempmail.plus/',
username: 'qichen111', // 固定的临时邮箱名称
pinCode: '147258',
domain: 'qichen.cloud' // 我们注册时使用的域名(随机前缀会投递到此)
domain: 'qichen111.asia' // 我们注册时使用的域名(随机前缀会投递到此)
},
// Verdent 注册配置

View File

@ -55,50 +55,46 @@ async function main() {
emailPage = await emailContext.newPage();
registerPage = await registerContext.newPage();
// 生成唯一用户名(随机 + 时间)
const localPart = generateUsername('qichen');
// ========== 第一步:设置临时邮箱 ==========
console.log('\n📧 === 步骤 1: 设置临时邮箱 ===');
// ========== 初始化:设置临时邮箱 ==========
console.log('\n📧 === 初始化: 设置临时邮箱 ===');
const { inboxReady } = await setupTempMail(emailPage);
if (!inboxReady) {
throw new Error('未能成功创建临时邮箱');
}
const email = `${localPart}@${config.tempmail.domain}`;
console.log('📧 将用于注册的邮箱:', email);
// 获取初始基线时间
await updateBaseline(emailPage);
console.log('✅ 临时邮箱初始化完成\n');
// ========== 第二步:在 Verdent 上开始注册 ==========
console.log('\n🌐 === 步骤 2: 开始 Verdent.ai 注册 ===');
const { sentAtMs } = await registerOnVerdent(registerPage, email);
// ========== 循环注册 ==========
while (true) {
try {
console.log('\n' + '='.repeat(60));
console.log(`🔄 第 ${successCount + failureCount + 1} 次注册尝试 | 成功: ${successCount} | 失败: ${failureCount}`);
console.log('='.repeat(60));
// ========== 第三步:等待验证码邮件(只取发送后的邮件) ==========
console.log('\n📬 === 步骤 3: 等待验证码邮件 ===');
const verificationCode = await waitForVerificationCode(emailPage, sentAtMs, email);
// 生成新邮箱(纯随机)
const localPart = generateUsername();
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 {}
registerPage = await registerContext.newPage();
if (success) {
successCount++;
console.log('\n🎉 ============================================');
console.log(' 注册流程成功完成');
console.log(' 注册成功!');
console.log('============================================');
console.log('📧 邮箱:', email);
console.log('🔑 密码:', config.verdent.password);
console.log('============================================\n');
// 邮件页面回退到收件箱列表,避免下次重复输入 PIN
// 邮件页面回退到收件箱
try {
console.log('[邮箱] 回退到收件箱列表...');
await emailPage.goBack({ waitUntil: 'domcontentloaded', timeout: 5000 });
@ -110,33 +106,40 @@ async function main() {
await emailPage.waitForTimeout(1500);
}
// 更新基线为当前最新邮件时间
// 更新基线
await updateBaseline(emailPage);
// 持久化保存(注册时间与过期时间=7天
// 保存到数据库
const createdAt = new Date();
const expiresAt = new Date(createdAt.getTime() + 7 * 24 * 60 * 60 * 1000);
try {
await saveAccount({ email, password: config.verdent.password, createdAt, expiresAt, status: 'active' });
console.log('[DB] 账号已写入数据库');
console.log('[DB] 账号已写入数据库');
} catch (e) {
console.log('[DB] 写入失败:', e.message);
console.log('[DB] ⚠️ 写入失败:', e.message);
}
} else if (success === false) {
console.log('\n❌ 注册失败,请检查错误信息');
} else {
console.log('\n⚠ 注册状态未知,请手动检查浏览器窗口');
failureCount++;
console.log('\n❌ 注册失败');
}
// 保持浏览器打开 30 秒以便查看结果
console.log('⏰ 浏览器将在 30 秒后关闭...');
await new Promise(resolve => setTimeout(resolve, 30000));
// 等待 10 秒后继续下一次
console.log('\n⏳ 等待 10 秒后开始下一次注册...');
await new Promise(resolve => setTimeout(resolve, 10000));
} 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.log('⏰ 浏览器将在 60 秒后关闭,请检查问题...');
await new Promise(resolve => setTimeout(resolve, 60000));

View File

@ -231,6 +231,26 @@ export async function completeRegistration(page, verificationCode) {
if (!currentUrl.includes('/signup')) {
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;
} else {
// 检查是否有错误提示

12
schema.sql Normal file
View 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
View File

@ -1,11 +1,8 @@
export function generateUsername(prefix = 'user') {
export function generateUsername() {
// 生成纯随机字符串,不包含固定前缀
const now = new Date();
const YYYY = now.getFullYear();
const MM = String(now.getMonth() + 1).padStart(2, '0');
const DD = String(now.getDate()).padStart(2, '0');
const hh = String(now.getHours()).padStart(2, '0');
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}`;
const timestamp = now.getTime(); // 使用时间戳
const rand1 = Math.random().toString(36).slice(2, 8); // 6位随机
const rand2 = Math.random().toString(36).slice(2, 6); // 4位随机
return `${rand1}${timestamp}${rand2}`;
}