167 lines
6.1 KiB
JavaScript
167 lines
6.1 KiB
JavaScript
import { chromium } from 'playwright';
|
||
import { config } from './config.js';
|
||
import { setupTempMail, waitForVerificationCode, updateBaseline } from './emailModule.js';
|
||
import { registerOnVerdent, completeRegistration } from './registerModule.js';
|
||
import { getBrowserAndContexts } from './browser.js';
|
||
import { generateUsername } from './util.js';
|
||
import { saveAccount } from './db.js';
|
||
|
||
/**
|
||
* 单次注册流程
|
||
*/
|
||
async function registerOnce(emailPage, registerPage, email) {
|
||
// ========== 开始 Verdent 注册 ==========
|
||
console.log('\n🌐 === 步骤 1: 开始 Verdent.ai 注册 ===');
|
||
const { sentAtMs } = await registerOnVerdent(registerPage, email);
|
||
|
||
// ========== 等待验证码邮件 ==========
|
||
console.log('\n📬 === 步骤 2: 等待验证码邮件 ===');
|
||
const verificationCode = await waitForVerificationCode(emailPage, sentAtMs, email);
|
||
|
||
if (!verificationCode) {
|
||
throw new Error('未能获取验证码');
|
||
}
|
||
|
||
// ========== 完成注册 ==========
|
||
console.log('\n✅ === 步骤 3: 完成注册 ===');
|
||
const success = await completeRegistration(registerPage, verificationCode);
|
||
|
||
return success;
|
||
}
|
||
|
||
/**
|
||
* 主自动注册流程(循环模式)
|
||
*/
|
||
async function main() {
|
||
console.log('🚀 开始自动注册流程(循环模式)...\n');
|
||
|
||
let browser;
|
||
let emailContext;
|
||
let registerContext;
|
||
let emailPage;
|
||
let registerPage;
|
||
let successCount = 0;
|
||
let failureCount = 0;
|
||
|
||
try {
|
||
// 启动浏览器
|
||
console.log('🌐 启动浏览器...');
|
||
({ browser, emailContext, registerContext } = await getBrowserAndContexts({
|
||
headless: config.browser.headless,
|
||
slowMo: config.browser.slowMo,
|
||
}));
|
||
|
||
// 创建邮箱页面(保持不关)
|
||
emailPage = await emailContext.newPage();
|
||
registerPage = await registerContext.newPage();
|
||
|
||
// 生成唯一用户名(随机 + 时间)
|
||
const localPart = generateUsername('qichen');
|
||
|
||
// ========== 第一步:设置临时邮箱 ==========
|
||
console.log('\n📧 === 步骤 1: 设置临时邮箱 ===');
|
||
const { inboxReady } = await setupTempMail(emailPage);
|
||
if (!inboxReady) {
|
||
throw new Error('未能成功创建临时邮箱');
|
||
}
|
||
const email = `${localPart}@${config.tempmail.domain}`;
|
||
console.log('📧 将用于注册的邮箱:', email);
|
||
|
||
// 获取初始基线时间
|
||
await updateBaseline(emailPage);
|
||
|
||
// ========== 第二步:在 Verdent 上开始注册 ==========
|
||
console.log('\n🌐 === 步骤 2: 开始 Verdent.ai 注册 ===');
|
||
const { sentAtMs } = await registerOnVerdent(registerPage, email);
|
||
|
||
// ========== 第三步:等待验证码邮件(只取发送后的邮件) ==========
|
||
console.log('\n📬 === 步骤 3: 等待验证码邮件 ===');
|
||
const verificationCode = await waitForVerificationCode(emailPage, sentAtMs, email);
|
||
|
||
if (!verificationCode) {
|
||
throw new Error('未能获取验证码');
|
||
}
|
||
|
||
// ========== 第四步:完成注册 ==========
|
||
console.log('\n✅ === 步骤 4: 完成注册 ===');
|
||
const success = await completeRegistration(registerPage, verificationCode);
|
||
|
||
// 注册页本次任务结束后关闭,并为下次准备新页签
|
||
try { await registerPage.close(); } catch {}
|
||
registerPage = await registerContext.newPage();
|
||
|
||
if (success) {
|
||
console.log('\n🎉 ============================================');
|
||
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 });
|
||
await emailPage.waitForTimeout(1500);
|
||
console.log('[邮箱] ✅ 已回退到收件箱');
|
||
} catch (e) {
|
||
console.log('[邮箱] 回退失败,尝试直接跳转:', e.message);
|
||
await emailPage.goto('https://tempmail.plus/zh/', { waitUntil: 'domcontentloaded', timeout: 10000 }).catch(() => {});
|
||
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] 账号已写入数据库');
|
||
} catch (e) {
|
||
console.log('[DB] 写入失败:', e.message);
|
||
}
|
||
} else if (success === false) {
|
||
console.log('\n❌ 注册失败,请检查错误信息');
|
||
} else {
|
||
console.log('\n⚠️ 注册状态未知,请手动检查浏览器窗口');
|
||
}
|
||
|
||
// 保持浏览器打开 30 秒以便查看结果
|
||
console.log('⏰ 浏览器将在 30 秒后关闭...');
|
||
await new Promise(resolve => setTimeout(resolve, 30000));
|
||
|
||
} catch (error) {
|
||
console.error('\n❌ 发生错误:', error.message);
|
||
console.error(error.stack);
|
||
|
||
// 错误时保持浏览器打开以便调试
|
||
console.log('⏰ 浏览器将在 60 秒后关闭,请检查问题...');
|
||
await new Promise(resolve => setTimeout(resolve, 60000));
|
||
|
||
} finally {
|
||
// 清理资源
|
||
try {
|
||
if (!config.browser.keepEmailOpen) {
|
||
if (emailContext && emailContext.close) await emailContext.close();
|
||
} else {
|
||
console.log('[INFO] 已根据配置保留临时邮箱窗口,未关闭 emailContext');
|
||
}
|
||
} catch {}
|
||
try {
|
||
if (registerContext && registerContext.close) await registerContext.close();
|
||
} catch {}
|
||
try {
|
||
if (!config.browser.keepEmailOpen) {
|
||
if (browser && browser.close) await browser.close();
|
||
}
|
||
} catch {}
|
||
|
||
console.log('👋 程序结束');
|
||
}
|
||
}
|
||
|
||
// 运行主程序
|
||
main().catch(console.error);
|