Search code examples
pythonpython-asynciotelethon

How I can avoid using "global" with asyncio (telethon)?


As far as I know using "global" is a bad practice in python, but I have no idea how to avoid it here. Thank you in advance.

import asyncio
from telethon import TelegramClient, sync, events

api_id = ***
api_hash = '***'

client = TelegramClient('session_name', api_id, api_hash).start()

channel_id = ***

@client.on(events.NewMessage(chats=channel_id))
async def handler(event):
    text = event.raw_text.lower()

    global task

    if text == 'start':
        task = client.loop.create_task(main())
        await client.send_message(channel_id, 'task was started')

    if text == 'stop':
        task.cancel()
        await client.send_message(channel_id, 'task was canceled')

async def main():
    while True:
        await client.send_message(channel_id, 'do something')
        await asyncio.sleep(3)

client.run_until_disconnected()

Solution

  • Looking at the documentation, I couldn't find the recommended way to use the client with classes, but you should always be able to connect it yourself. For example:

    class MyClient:
        def __init__(self, client):
            self.task = None
            self.client = client
    
        async def on_message(self, channel_id, event):
            text = event.raw_text.lower()
    
            if text == 'start':
                self.task = self.client.loop.create_task(self.main(channel_id))
                await self.client.send_message(channel_id, 'task was started')
    
            if text == 'stop':
                self.task.cancel()
                await self.client.send_message(channel_id, 'task was canceled')
    
        async def main(self, channel_id):
            while True:
                await self.client.send_message(channel_id, 'do something')
                await asyncio.sleep(3)
    
    def run_client():
        # instantiate telegram client, my client, and connect the two
        api_id = ***
        api_hash = '***'
    
        channel_id = ***
    
        client = TelegramClient('session_name', api_id, api_hash).start()
        my_client = MyClient(client)
    
        @client.on(events.NewMessage(chats=channel_id))
        async def handle(event):
            await my_client.on_message(channel_id, event)
    
        client.run_until_disconnected()
    
    run_client()