如何在 Telethon 中正确启动线程?

问题描述

我正在编写一个机器人,我需要实现以下功能:机器人每 10 分钟一次(例如)解析某个 URL,如果上次调用发生变化,则写入聊天。 由于 bot 还从事其他事情,我决定在函数中循环解析,最后使用 sleep。如果有变化,我尝试向聊天发送消息,但随后出现问题。 由于聊天中的事件不会产生成功的情况组合,因此我无法从“send_message”函数的“事件”中提取“实体”。因此,我们必须通过“get_entity”函数并将聊天链接作为参数,但由于某种原因,这在另一个流中不起作用。下面是一个简化的代码

import threading,queue
from time import sleep
import asyncio
from telethon.sync import TelegramClient,events
import config as cfg

bot = TelegramClient('Bot',cfg.api_id,cfg.api_hash)

@bot.on(events.NewMessage(pattern=r'^(?i)(idchat){1}$'))
async def echoidchat(event):
    channelaa = await bot.get_entity('https://t.me/elvistest')
    await bot.send_message(channelaa,'ответ')


def parseurls():
    for x in range(10):
        q.put(x)
    pass
    

async def pre_sendmsg():
    while True:
        try:
            msg = q.get_Nowait()
        except Exception as e:
            await asyncio.sleep(1.0)
        else:
            await sendmsg(msg)
            q.task_done()

async def sendmsg(msg):
    channel = await bot.get_entity('https://t.me/elvistest')
    await bot.send_message(channel,f'ответ из другого потока {msg}')

if __name__ == '__main__':
    q = queue.Queue()
    parseurls()
    bot.start(bot_token=cfg.bot_token)
    threading.Thread(target=asyncio.run,daemon=True,args=(pre_sendmsg(),)).start()
    bot.run_until_disconnected()

问题是在“boot.get_entity”行上什么也没有发生。脚本执行在某处丢失并没有进一步执行,即下一行带有“bot.send_message”的根本不执行。但是,“def echoidchat”此时正在工作。

解决方法

干得好! 这是我想要的工作。

import random
import threading,queue
from time import sleep
import asyncio
from telethon import TelegramClient,events
import config as cfg

bot = TelegramClient('Bot',cfg.api_id,cfg.api_hash)

@bot.on(events.NewMessage(pattern=r'^(?i)(idchat){1}$'))
async def echoidchat(event):
    await bot.send_message(event.chat,'ответ')


async def parseurls():
    while True:
        ts = abs(int(random.random()*10))
        print(f'parseurls({ts})')
        await sendmsg(ts)
        await asyncio.sleep(ts)


async def sendmsg(msg):
    print(f'sendmsg({msg}) - start')
    channel = await bot.get_entity('https://t.me/elvistest')
    await bot.send_message(channel,f'ответ из другого потока {msg}')
    print(f'sendmsg({msg}) - done')


def main():
    bot.start(bot_token=cfg.bot_token)
    loop = asyncio.get_event_loop()
    tasks = [
        loop.create_task(parseurls()),loop.create_task(bot.run_until_disconnected()),]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

if __name__ == '__main__':
    main()