-2

I made a function to test my telegram bot, it sends a request message to the chat bot to change some value in the database for this user. The problem is that all the code is played before the code of the function "first_handler" with the decorator (due to which the "print (flag)" writes "false" ). Even if the reply message from the bot appears before the execution of the code reaches "print", then the function with the decorator does not trigger before the "print". Due to the same problem, I have to use "client.run_until_disconnected()" because without it, the bot's message handler doesn't work at all, and because of this method, I have to stop the program execution manually, since I don't need to disconnect the client. My scuffed code:

from telethon import TelegramClient, events, sync
import conf_tests as ct

import time

client = TelegramClient('TestClient', ct.api_id, ct.api_hash, system_version = ct.sys_ver)

def test_first():
    flag = False

    @client.on(events.NewMessage(chats=ct.bot_name))
    async def fist_handler(event):
        global flag, f2

        if (event.sender_id == ct.bot_id) and ('Enter new value' in event.raw_text):
            global f1
            f1 = True
            await client.send_message(ct.bot_name, 'Value')

        if (event.sender_id == ct.bot_id) and ('Value successfully changed!' in event.raw_text):
            f2 = True
            if f1 and f2:
                flag = True
    
    client.start()        
    client.send_message(ct.bot_name, ct.change_group_btn)
    
    client.run_until_disconnected() 
    print (flag)

test_first()       
  • Bonus problem, which is more related to my lack of knowledge of python: I cannot set f1 and f2 (no problem with f2 in this particular case) to False before the first if, because otherwise I will not be able to declare f1 a global variable to be able to change it in if below. If the check passes, there are no problems, but if it does not pass, it will give an error that the variables have not been assigned a value.

Tried to use this, but nothing has changed, but it shouldn't i guess, because in fact I just call the function, just in a different place.

with client:
   client.loop.run_until_complete(test_first())

And, to be honest, I don’t remember in what form I added these lines, cos now, it seems, they will not work due to asynchrony.

alantbarlow
  • 138
  • 6
BDBazuso
  • 5
  • 1
  • Sorry, but no bonus questions. One question per question. – Klaus D. May 06 '23 at 20:01
  • I agree with @KlausD., the question title needs to point out your exact issue so that it can be helpful to others that have a similar issue. the description of the problem should just provide more context around the issue so it can be more accurately answered. To do this, you should only focus on one problem per question. If you still have questions unrelated to the single problem, they need to be addressed in a separate question so they can help others also. – alantbarlow May 06 '23 at 21:45
  • Well, I understand now, however "bonus" one is unnecessary and simple, I'm sure the answer to it is already here, it was just not the main problem and I didn't really understand it. – BDBazuso May 07 '23 at 11:32

1 Answers1

0

I think the main issue is that the test_first function should be asynchronous. The following code should help you fix your issues.

from telethon import TelegramClient, events
import conf_tests as ct

import asyncio # Recommended to be used by the telethon package

client = TelegramClient('TestClient', ct.api_id, ct.api_hash, system_version=ct.sys_ver)

async def test_first():
    flag = False
    f1 = False
    f2 = False

    @client.on(events.NewMessage(chats=ct.bot_name))
    async def first_handler(event):
        nonlocal flag, f1, f2 # lets you use the flag, f1, and f2 variables that were defined earlier but doesnt make them global
        if event.sender_id == ct.bot_id:
            if 'Enter new value' in event.raw_text:
                f1 = True
                await client.send_message(ct.bot_name, 'Value')
            elif 'Value successfully changed!' in event.raw_text:
                f2 = True
                if f1 and f2:
                    flag = True
                    client.disconnect()

    async with client: # properly connect and disconnect the client
        await client.send_message(ct.bot_name, ct.change_group_btn)
        await client.run_until_disconnected()
    
    print(flag)

asyncio.run(test_first()) # Creates a new asyncio event loop asynchronously running "test_first"

As you can see, it uses the asyncio package that is recommended in the Telethon Documentation. It sets the flag, f1, and f2 variables as nonlocal so they can be used outside the first_handler function. It also makes the test_first function async and awaits on the client.

I left comments in the code explaining what some of the changes are for. Let me know if this was helpful or not in the comments. You can also check out the documentation using the link above if you have not done so already.

alantbarlow
  • 138
  • 6
  • When I run this code, in the console it says: "DeprecationWarning: There is no current event loop client = TelegramClient('TestClient', ct.api_id, ct.api_hash, system_version=ct.sys_ver, loop=asyncio.get_event_loop()) # Assigns the asyncio loop as the main loop for the client." And the function does not stop working, and does not write the value of "flag", because "await client.run_until_disconnected()" never ends because the client is not disconnected. Yep, I'm read documentation, and saw suggestions to use "sync" from telethon, but if ot better with acyncio, I'll use it. – BDBazuso May 07 '23 at 11:52
  • Well, I added "client.disconnect()" into last "if" block and deleted "loop=asyncio.get_event_loop()", now it works fine, big thanks! – BDBazuso May 07 '23 at 12:22
  • I updated the answer to include the changes you made. I'm glad I could help, though, consider upvoting the answer if you found it helpful. – alantbarlow May 07 '23 at 17:32
  • Unfortunately, I do not have enough reputation to upvote, apparently it is only available with 15 reputation. – BDBazuso May 07 '23 at 17:47