Telethon多客户端(3+)启动报错及轮发消息实现问询
Telegram多客户端启动报错与轮发逻辑修复方案
一、解决sqlite3.OperationalError: database is locked错误
错误原因
你所有发送账号的客户端都使用了同一个session文件名'session1',导致多个客户端同时读写同一个SQLite数据库文件。SQLite仅支持单写操作,多客户端并发写入时会触发锁死报错。
解决方案
给每个账号分配唯一的session文件名,确保每个客户端拥有独立的会话存储文件,避免资源竞争。
修改后的多客户端初始化代码:
import asyncio from telethon import TelegramClient, events # 统一管理所有账号的配置,监听账号+6个发送账号 accounts_config = [ {"session_name": "session_monitor", "api_id": api_id, "api_hash": api_hash}, {"session_name": "session_send_1", "api_id": api_id1, "api_hash": api_hash1}, {"session_name": "session_send_2", "api_id": api_id2, "api_hash": api_hash2}, {"session_name": "session_send_3", "api_id": api_id3, "api_hash": api_hash3}, {"session_name": "session_send_4", "api_id": api_id4, "api_hash": api_hash4}, {"session_name": "session_send_5", "api_id": api_id5, "api_hash": api_hash5}, {"session_name": "session_send_6", "api_id": api_id6, "api_hash": api_hash6}, ] # 初始化客户端列表 clients = [] for config in accounts_config: client = TelegramClient(config["session_name"], config["api_id"], config["api_hash"]) clients.append(client) # 异步启动所有客户端(Telethon基于异步框架,异步启动更稳定) async def start_all_clients(): await asyncio.gather(*[client.start() for client in clients]) # 拆分监听客户端和发送客户端 monitor_client = clients[0] send_clients = clients[1:]
二、修复轮发消息逻辑
原逻辑问题
- 每次触发事件时
index都会被重置为0,永远无法切换账号 index == 0是比较操作而非赋值,无法重置计数器- 硬编码的
if-elif扩展性差,新增账号需修改大量代码
解决方案
- 使用全局计数器记录已发送消息总数
- 通过公式
账号索引 = 总发送数 // 单账号发送上限 % 账号数量实现循环轮发 - 基于客户端列表动态获取发送账号,无需硬编码判断
修改后的事件处理代码:
# 全局计数器:记录已发送消息总数 total_sent = 0 # 单账号发送上限:每发满50条切换下一个账号 SEND_LIMIT_PER_ACCOUNT = 50 @monitor_client.on(events.ChatAction) async def handle_new_member(event): global total_sent # 判断是否为新成员加入/被邀请事件 if event.user_added or event.user_joined: user = await event.get_user() message_content = "这里替换为你的私信内容" try: # 计算当前要使用的发送账号索引 current_account_idx = (total_sent // SEND_LIMIT_PER_ACCOUNT) % len(send_clients) current_client = send_clients[current_account_idx] # 发送消息,直接传入user对象即可,无需手动构造InputPeerUser await current_client.send_message(user, message_content) print(f"账号{current_account_idx+1}发送成功,累计发送{total_sent+1}条") total_sent += 1 except Exception as e: print(f"发送失败:{str(e)}")
三、完整启动流程
将代码整合后,通过asyncio运行主循环:
async def main(): await start_all_clients() print("所有客户端启动完成,开始监听群组新成员事件...") await monitor_client.run_until_disconnected() if __name__ == "__main__": asyncio.run(main())
内容的提问来源于stack exchange,提问作者Pekea
相关产品推荐
相关产品推荐

