diff --git a/telegram_bot.py b/telegram_bot.py
index 7fb7b50..7639b8c 100644
--- a/telegram_bot.py
+++ b/telegram_bot.py
@@ -118,6 +118,7 @@ class ProvisionerBot:
("list", self.cmd_list),
("config", self.cmd_config),
("fingerprint", self.cmd_fingerprint),
+ ("concurrent", self.cmd_concurrent),
("run", self.cmd_run),
("run_all", self.cmd_run_all),
("resume", self.cmd_resume),
@@ -247,6 +248,7 @@ class ProvisionerBot:
BotCommand("stop", "停止当前任务"),
# 配置管理
BotCommand("fingerprint", "开启/关闭随机指纹"),
+ BotCommand("concurrent", "开启/关闭并发处理"),
BotCommand("include_owners", "开启/关闭 Owner 入库"),
BotCommand("reload", "重载配置文件"),
# 清理管理
@@ -307,6 +309,8 @@ class ProvisionerBot:
⚙️ 配置管理:
/fingerprint - 开启/关闭随机指纹
+/concurrent - 开启/关闭并发处理
+/concurrent <n> - 设置并发数 (1-10)
/include_owners - 开启/关闭 Owner 入库
/reload - 重载配置文件 (无需重启)
/clean - 清理 team.json 和 tracker 数据
@@ -347,15 +351,15 @@ class ProvisionerBot:
/team_fingerprint - 开启/关闭随机指纹
/team_register - 开始自动订阅注册
-� AutoGPTPlus:
+🔧 AutoGPTPlus:
/autogptplus - ChatGPT 订阅自动化管理面板
-�💡 示例:
+💡 示例:
/list - 查看所有待处理账号
/run 0 - 处理第一个 Team
+/concurrent 4 - 开启 4 并发处理
/gptmail_add my-api-key - 添加 Key
-/iban_add DE123...,DE456... - 添加 IBAN
-/domain_add @example.com - 添加域名"""
+/iban_add DE123...,DE456... - 添加 IBAN"""
await update.message.reply_text(help_text, parse_mode="HTML")
@admin_only
@@ -487,6 +491,8 @@ class ProvisionerBot:
@admin_only
async def cmd_config(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""查看当前系统配置"""
+ from config import CONCURRENT_ENABLED, CONCURRENT_WORKERS
+
# 授权服务地址
if AUTH_PROVIDER == "s2a":
auth_url = S2A_API_BASE or "未配置"
@@ -507,6 +513,12 @@ class ProvisionerBot:
# 随机指纹状态
fingerprint_status = "✅ 已开启" if BROWSER_RANDOM_FINGERPRINT else "❌ 未开启"
+ # 并发处理状态
+ if CONCURRENT_ENABLED:
+ concurrent_status = f"✅ 已开启 ({CONCURRENT_WORKERS} 并发)"
+ else:
+ concurrent_status = "❌ 未开启"
+
lines = [
"⚙️ 系统配置",
"",
@@ -520,6 +532,7 @@ class ProvisionerBot:
"",
"🌐 浏览器",
f" 随机指纹: {fingerprint_status}",
+ f" 并发处理: {concurrent_status}",
"",
"👥 账号设置",
f" 每 Team 账号数: {ACCOUNTS_PER_TEAM}",
@@ -530,6 +543,7 @@ class ProvisionerBot:
"",
"💡 提示:",
"/fingerprint - 切换随机指纹",
+ "/concurrent - 切换并发处理",
"/include_owners - 切换 Owner 入库",
"/s2a_config - 配置 S2A 参数",
]
@@ -621,6 +635,89 @@ class ProvisionerBot:
except Exception as e:
await update.message.reply_text(f"❌ 修改配置失败: {e}")
+ @admin_only
+ async def cmd_concurrent(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
+ """切换并发处理开关或设置并发数"""
+ import tomli_w
+ from config import CONCURRENT_ENABLED, CONCURRENT_WORKERS
+
+ try:
+ # 读取当前配置
+ with open(CONFIG_FILE, "rb") as f:
+ import tomllib
+ config = tomllib.load(f)
+
+ # 确保 concurrent section 存在
+ if "concurrent" not in config:
+ config["concurrent"] = {"enabled": False, "workers": 4}
+
+ # 解析参数
+ args = context.args if context.args else []
+
+ if not args:
+ # 无参数: 切换开关
+ current = config["concurrent"].get("enabled", False)
+ new_value = not current
+ config["concurrent"]["enabled"] = new_value
+
+ # 写回文件
+ with open(CONFIG_FILE, "wb") as f:
+ tomli_w.dump(config, f)
+
+ workers = config["concurrent"].get("workers", 4)
+ status = "✅ 已开启" if new_value else "❌ 已关闭"
+
+ await update.message.reply_text(
+ f"⚡ 并发处理\n\n"
+ f"状态: {status}\n"
+ f"并发数: {workers}\n\n"
+ f"开启后将同时启动 {workers} 个浏览器实例并行处理账号\n\n"
+ f"💡 设置并发数:\n"
+ f"/concurrent 4 - 设置为 4 并发\n\n"
+ f"使用 /reload 立即生效",
+ parse_mode="HTML"
+ )
+
+ else:
+ # 有参数: 设置并发数
+ try:
+ workers = int(args[0])
+ if workers < 1 or workers > 10:
+ await update.message.reply_text("❌ 并发数范围: 1-10")
+ return
+
+ config["concurrent"]["workers"] = workers
+ config["concurrent"]["enabled"] = True # 设置并发数时自动开启
+
+ # 写回文件
+ with open(CONFIG_FILE, "wb") as f:
+ tomli_w.dump(config, f)
+
+ await update.message.reply_text(
+ f"⚡ 并发处理\n\n"
+ f"状态: ✅ 已开启\n"
+ f"并发数: {workers}\n\n"
+ f"将同时启动 {workers} 个浏览器实例并行处理账号\n\n"
+ f"💡 使用 /reload 立即生效",
+ parse_mode="HTML"
+ )
+
+ except ValueError:
+ await update.message.reply_text(
+ "❌ 无效的并发数\n\n"
+ "用法:\n"
+ "/concurrent - 切换开关\n"
+ "/concurrent 4 - 设置为 4 并发"
+ )
+
+ except ImportError:
+ await update.message.reply_text(
+ "❌ 缺少 tomli_w 依赖\n"
+ "请运行: uv add tomli_w"
+ )
+ except Exception as e:
+ await update.message.reply_text(f"❌ 修改配置失败: {e}")
+
@admin_only
async def cmd_reload(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""重载配置文件"""