使用Telethon开发时二次循环调用函数出现coroutine never awaited报错
问题根源
- 协程未等待警告:Telethon的
client.start()、client.run_until_disconnected()均为异步协程方法,你在同步函数中直接调用未添加await关键字,也没有放到异步事件循环中执行,因此触发运行时警告。 - 无触发自动执行函数:你每次进入
scanTg1函数都会给全局的client重复注册新的消息事件监听器,上一次扫描注册的监听器没有被移除,同时你通过sellToken→mainScreen→scanTg1的递归调用方式跳转流程,会导致多个监听器同时生效,旧监听器触发后就会无预期执行后续逻辑,而且全局client重复启动也会导致状态混乱。
修复方案
- 统一异步逻辑:所有和Telethon client相关的操作都放到异步上下文中执行,程序入口用
asyncio.run()启动主异步循环,不要混用同步异步调用逻辑。 - 避免重复注册监听器:事件监听器全局仅注册一次,或者每次扫描结束后主动移除之前注册的监听器,不要每次进入扫描功能都重复注册。
- 替换递归跳转逻辑:改用死循环控制主界面的展示和功能切换,不要用函数递归的方式返回主界面,避免栈溢出和逻辑混乱。
- 主动控制client生命周期:需要扫描的时候启动client,扫描完成(比如买到代币后)主动调用
client.disconnect()断开连接,不要一直挂着run_until_disconnected()阻塞流程。
修改后参考代码
import asyncio from telethon import TelegramClient, events from web3 import Web3 # 配置和全局变量 config = { "telegram_id": 替换为你的API_ID, "telegram_hash": "替换为你的API_HASH", "tgGroup": "" } addresses = [] # 替换为你的地址列表 web3 = Web3(Web3.HTTPProvider("替换为你的RPC节点地址")) handleNewMessage = True client = TelegramClient('anon', config['telegram_id'], config['telegram_hash']) # 全局只注册一次事件监听器 current_scan_group = None @client.on(events.NewMessage) async def my_event_handler(event): global handleNewMessage, current_scan_group if not handleNewMessage or event.chat.username != current_scan_group.replace("https://t.me/", ""): return if event.raw_text is None: return if 'stealth' in event.raw_text.lower(): contract_found = False if '0x' in event.raw_text: x = event.raw_text.split() for string in x: if '0x' in string: start = string.index('0') contract = Web3.toChecksumAddress(string[start:start+42].lower()) contract_found = await checkContract(contract) if contract_found == True: print("Contract Found: " + contract) handleNewMessage = False # 停止client监听 await client.disconnect() await buyTheToken(contract) return if not contract_found and 't.me' in event.raw_text: x = event.raw_text.split() for string in x: if 't.me' in string: tgLink = string print("Found " + tgLink) await scanOldMessages(tgLink) return print('*') else: print('*') async def checkContract(contract): # 补充你的合约检查逻辑 return True async def scanOldMessages(link): # 补充你的历史消息扫描逻辑 pass async def buyTheToken(contract): print("Bought the Token") await sellToken() async def sellToken(): print("Token sold") async def scanTg1(): global current_scan_group, handleNewMessage print('') if config['tgGroup'] == "": group = input("Link to the TG: ") else: group = config['tgGroup'] current_scan_group = group handleNewMessage = True print("Scanning : " + group) # 异步启动client await client.start() await client.run_until_disconnected() async def mainScreen(): while True: # Display Wallet / Buy Info print('Wallets List') print('------------') for address in addresses: balance = web3.fromWei(web3.eth.get_balance(address["wallet"]), 'ether') print(f'{address["wallet"]} | Amount to buy: {address["amount"]} | Current Balance : {balance}') # Print Options print('') print('What do you want to do?') print('-----------------------') print('') print('1) TG Scan') print('') choice = input("Enter your answer: ") if choice == "1": await scanTg1() if __name__ == "__main__": asyncio.run(mainScreen())
内容的提问来源于stack exchange,提问作者profoundwatcher
相关产品推荐
相关产品推荐

