eternnoir / pyTelegramBotAPI

Python Telegram bot api.
GNU General Public License v2.0
8.12k stars 2.03k forks source link

State not being updated #1972

Closed uniqueuser-repo closed 1 year ago

uniqueuser-repo commented 1 year ago

Please answer these questions before submitting your issue. Thanks!

  1. What version of pyTelegramBotAPI are you using? 4.11.0

  2. What OS are you using? Windows 11

  3. What version of python are you using? 3.10.11

I am using AsyncTelebot.

I am trying to do a very simple proof of concept with states, but the states are not persisting.

In my testing, I am simply privately messaging the bot. The bot is set up to display a button, and once you click the button, it starts asking you a series of questions.

At this point, I'm just trying to see the fact that I invoke set_state on a user persist. I call set_state and immediately try to get the state back:

await tb.set_state(call.from_user.id, State()) state_set = await tb.get_state(call.from_user.id)

However, state_set is ALWAYS "None" after the execution of get_state. I'm not sure what I'm doing wrong.

Here are my telebot related imports & calls to add_custom_filter & other possibly useful details:


from telebot import types, asyncio_filters
from telebot.asyncio_storage import StateMemoryStorage
from telebot.asyncio_handler_backends import State

tb = AsyncTeleBot(TG_API_KEY, state_storage=StateMemoryStorage())

tb.add_custom_filter(asyncio_filters.StateFilter(tb))
tb.add_custom_filter(asyncio_filters.IsDigitFilter())

loop = asyncio.get_event_loop() # Create event loop that will host our bot
loop.create_task(tb.infinity_polling())  # Add telebot to event loop
loop.run_forever() # Run event loop forever
uniqueuser-repo commented 1 year ago

I guess the issue is that the State is not being created inside of a class that inherits StatesGroup. In the asynctelebot examples, we see:

class MyStates(StatesGroup):
    name = State()  # statesgroup should contain states
    surname = State()
    age = State()

Unfortunately, I can't just drop a class like this in my code because the amount of states in my application can differ based upon what's in the database.

E.g., maybe in the database there's "name" "surname" and "state", then I need to have those 3 states.

But there also might be another (or a million more) states like "location", "gender" that will have to be determined at runtime by querying the database.

How can I put these states that are determined at runtime into a StatesGroup so that I don't see this issue?

If that's not possible, what is the recommended workaround for this?

coder2020official commented 1 year ago

StatesGroup is not a necessary class. You can pass a string, such as "get_name" or other random strings. Always remember to pass chat_id and user_id when getting & setting states