• Не работают кнопки в тг боте на python как починить?

    @twistfire92
    Python backend developer
    При любом событии (новое сообщение, нажатие на кнопку и пр.) бот проходит по всем хендлерам и смотрит какой хендлер удовлетворяет условиям. После того, как найден нужный - выполняет описанную в нем функцию.

    А теперь смотрим:
    1. Пользователь жмет кнопку
    2. Побежали по нашим хендлерам. Видим первый с
    @bot.callback_query_handler(func=lambda call: True)

    что значит "при нажатии на ЛЮБУЮ inline кнопку"
    3. Выполняем функцию которая в этом хендлере описана
    4. Ожидаем новых событий.

    В вашем случае на 3-м шаге выполнится функция list (кстати очень неудачное название, это зарезервированное имя, его лучше не использовать, почитайте про это)
    если уберете ее, выполнится game_processing

    Что делать?
    вариант 1 - как подсказали в комментариях, делать однин хендлер и внутри описывать все сценарии
    if call.data == 'users':
        ...
    elif call.data == 'go_play':
        ....
    elif call.data == 'go_play_next':
        ...


    Вариант 2 (более правильный) - отфильтровывать call.data в хендлерах. Сейчас там лежит func=lambda call: True, т.е. функция, возвращающая ВСЕГДА True. нужно как-то ее видоизменить, чтобы возвращалось True только при необходимых значениях call.data. Например func=lambda call: call.data=="foo" отработает только тогда, когда в call.data будет значение "foo".

    Дальше сами
    Ответ написан
    Комментировать
  • Как задать состояние другому пользователю в Aiogram?

    @twistfire92
    Python backend developer
    Вроде тут уже было обсуждение.
    Ответ написан
    Комментировать
  • Как интегрировать FastAPI с aiogram для работы с вебхуками?

    @twistfire92
    Python backend developer
    У себя делал примерно следующим образом:

    WEBHOOK_PATH = f"/bot/{settings.token}"
    WEBHOOK_URL = settings.webhook_url + WEBHOOK_PATH
    
    app = FastAPI()
    
    @app.on_event("startup")
    async def on_startup():
        webhook_info = await bot.get_webhook_info()
        if webhook_info != WEBHOOK_URL:
            await bot.set_webhook(url=WEBHOOK_URL)
        logger.info("Bot started")
    
    @app.post(WEBHOOK_PATH)
    async def bot_webhook(update: dict):
        telegram_update = types.Update(**update)
        await dp.feed_update(bot=bot, update=telegram_update)
    
    @app.on_event("shutdown")
    async def on_shutdown():
        await bot.session.close()
        await bot.delete_webhook()
        logger.info("Bot stopped")
    Ответ написан
    Комментировать
  • Aiogram. Как обновить контекст для фильтров?

    @twistfire92
    Python backend developer
    можно поиграться с этим
    или навесить хендлер на любой текст и уже внутри делать проверку
    if message.text in posts:
        ...
    Ответ написан
    Комментировать
  • Запросы от 2 Flask приложений к 1 БД: почему второе приложение не получает новые данные и выпадает с ошибкой?

    @twistfire92
    Python backend developer
    Попробуйте сессию инициализировать в обработчике роутера через отдельный метод (еще лучше использовать DI)
    что-то типа такого:
    def get_session():
        with Session() as session:
            yield session
            session.commit()
            session.close()


    и уже в обработчике роута вызывать
    session = get_session()
    calls_data = session.query(Calls).order_by(Calls.id.desc()).all()
    return render_template("calls_default.html", calls_data=calls_data)
    Ответ написан
  • Подойдет ли backend на python?

    @twistfire92
    Python backend developer
    Если цель - только файлики проверять/собирать, я бы взял FastAPI. Причём, если процесс работы с файлами будет синхронный, то и ендпоинты создавать синхронные, библиотека сама их запуститв отдельных потоках. Связка Django + DRF будет сложна для ознакомления новичку, да и много лишнего с собой несёт, чем пользоваться вы не будете.

    Опять же смотря что называть сайтом. Если это отдельное frontend приложение, где от вас требуется только API, то да. Если же и пользовательский визуал в зоне вашей ответственности, то Django. Хотя и FastAPI с шаблонами работать умеет.
    Ответ написан
    2 комментария
  • Как получить event на то что пользователь разбанен, то бишь бан закончился?

    @twistfire92
    Python backend developer
    Если я правильно понял документацию, то я бы правило в хендлере описал так
    ChatMemberUpdatedFilter(member_status_changed=(+RESTRICTED) >> (MEMBER))


    Пользователь забанен, но он является еще участником чата. Поэтому поиск по LEFT не подходит. Так что стоит посмотреть в этом направлении.
    Ответ написан
    2 комментария
  • Как сделать так чтобы бот ждал ответ?

    @twistfire92
    Python backend developer
    Во-первых нужно убрать декоратор у функции easy_game. Эта функция вызывается в register_next_step_handler, так что следующее сообщение будет как раз обрабатываться этой функцией.

    Во-вторых. В этой же функции сначала отправляется страна, затем отправляется ответ. Должно быть не так.
    Страна должна отправляться в функции easy(). Но там у тебя пользователю выводится сообщение с предложением запустить игру. Так что пропускай (пока что) предложение с запуском игры и сразу выводи название страны, потом обрабатывай ответ от пользователя в easy_game.

    В-третьих. По текущей логике, ответив "Париж" на вопрос "Россия", выдаст правильный ответ. Ты должен где-то сохранять правильный ответ на поставленый вопрос, чтобы сравнить с вводом пользователя. Для этого в функцию easy_game() можно добавить еще один аргумент right_answer, и передавать в него правильный ответ через дополнительные параметры в register_next_step_handler

    В-четвертых. Лучше использовать словарь, где ключом будет вопрос, а значением - ответ.

    В-пятых. Столица Эмиратов - Абу-Даби.

    Весь код приводить не буду, только некоторые моменты.

    countries_easy = {
    	"Россия": "Москва",
    	"Франция": "Париж",
    	"Арабские Эмираты": "Абу-Даби",
    	}
    
    ...
    
    @bot.message_handler(content_types=["text"])
    def easy(message):
    	...
    	# рандомно выбираем пару ключ-значение из словаря.
    	country, capital = random.choice(list(countries_easy.items()))
    	msg = bot.send_message(messaga.chat.id, country)
    	# Третьим параметром отправляем правильный ответ
    	bot.register_next_step_handler(msg, easy_game, capital)
    
    
    def easy_game(message, right_answer):
        if message.text == capital:
            bot.send_message(message.chat.id, "Правильный ответ!")
        else:
            bot.send_message(message.chat.id, "Неправильный ответ")


    В общем, разобравшись в работе register_next_step_handler, можно будет уже полноценную логику собирать.
    Ответ написан
    2 комментария
  • Не отправляется рассылка в боте telegram?

    @twistfire92
    Python backend developer
    в роутере попробуйте внести изменения
    @router.message(States.broadcast)
    async def process_broadcast(message: Message, state: FSMContext):
        text = message.text
        await state.finish()
        ...
    Ответ написан
    Комментировать
  • Как сделать отложенную отправку сообщений ботом aiogram 3?

    @twistfire92
    Python backend developer
    Вообще asyncio.sleep работать то должно, но лучше прикрутить какой-нибудь шедулер, или celery
    Ответ написан
    Комментировать
  • Можно ли заставить бота на aiogram отвечать исключительно на каждое пятое сообщение с ключевыми словами?

    @twistfire92
    Python backend developer
    Посмотрите в сторону FSM. В функцию хендлера добавляется параметр state, куда вы запишете номер попытки для конкретного пользователя. Как только счётчик попыток дойдёт до пяти, отвечайте.
    Ответ написан
    Комментировать
  • Как отправить переменную вместе с нажатием кнопки, в декоратор callback, не прибегая к созданию глобальной переменной?

    @twistfire92
    Python backend developer
    сходу можно 2 варианта рассмотреть.
    1. Самое простое, но не самое правильное - глобальную переменную сделать не строкой, а словарем, куда будет записываться соответствие
    id пользователя (ключ) и его ответ на загадку (значение). Соответственно можно просто через метод update вставлять ответ для каждого пользователя.

    2. зашивать в callback_data номер текущей загадки и потом просто по этому номеру вытаскивать ответ.

    второй способ предпочтительнее, т.к. в первом случае после рестарта бота весь процесс у пользователей слетит. Да и не очень хорошо глобальными переменными пользоваться
    Ответ написан
    Комментировать
  • Не реагируют на нажатия кнопки в телеграм боте?

    @twistfire92
    Python backend developer
    1.
    @dp.message_handler(commands=["support"])
    поменяйте на
    @dp.callback_query_handler(text="support")
    2. Читайте документацию
    3. удалите из вопроса токен и обновите его
    Ответ написан
    4 комментария
  • Меню многоуровневое тг бота telebot почему не работает?

    @twistfire92
    Python backend developer
    Все у вас работает.
    Возможно вы тестировали работу только первой кнопки в меню СНИЛС. В ней ошибка. Сама кнопка содержит сообщение "Кто может получить СНИЛС?", а в функции SNILS проверка на строку "Кто может получить?".

    Чтобы избежать таких ошибок, советую либо использовать константы, где будут содержаться значения кнопок, либо использовать Inline клавиатуру. Она даст больше маневров для построения многоуровнего меню.
    Ответ написан
    Комментировать
  • Как сделать кнопку назад в телебот пайтон?

    @twistfire92
    Python backend developer
    1. вынести создание клавиатуры главного меню в отдельную функцию
    2. удалить ненужное условие if call.message:
    3. добавить условие на call.data == "back", где получите клавиатуру вызовом функции из п.1 и отредактируете сообщение с нужным текстом и этой клавиатурой
    Ответ написан
  • Как отправить кубик с нужным мне значением?

    @twistfire92
    Python backend developer
    Нельзя отправить эмодзи кубика с предопределенным значением. Если где-то такое было, то скорее всего использовались анимированные стикеры.
    Отправка кубика происходит через метод sendDice, в котором нет параметра для установки значения.
    В ответ прилетает объект Message, в котором есть свойство dice типа Dice.

    В документации четко прописано про random value
    Ответ написан
    Комментировать
  • Как выйти из вложенного хендлера в aiogram3 python?

    @twistfire92
    Python backend developer
    вы не разобрались с библиотекой. Вот эта вся т.н. вложенность в коде никакой вложенностью в логике не является. Вы должны все хендлеры регистрировать на одном уровне, а не внутри других.

    А для реализации вашей логики необходимо использовать машину состояний (FSM)
    Ответ написан
    Комментировать
  • Aiogram 3 как Установить state для определенного пользователя?

    @twistfire92
    Python backend developer
    Можете заглянуть в исходники aiogram, найти там класс FSMContext, экземпляр которого пробрасывается в вашу функцию, и поизучать это все.
    Один из аргументов функции __init__ этого класса имеет тип StorageKey, который в свою очередь содержит информацию о чате, пользователе, боте и пр.
    Я думаю вам стоит копать в эту сторону, создать руками отдельный инстанс FSMContext (назовем его custom_state), куда передадите отдельный инстанс StorageKey с нужными вам параметрами. Вторым параметром у FSMContext буедет выступать ваш Storage. Либо MemoryStorage, либо RedisStorage (либо у вас свой кастомный какой-то). Туда пробрасывайте тот Storage, который используете.

    И вот уже у этого отдельного инстанса custom_state вызывайте метод set_state()

    P.S. Сам такое не проворачивал, ответ написал опираясь на исходники aiogram. Копайте туда, пробуйте, экспериментируйте.
    Ответ написан
    Комментировать
  • Как создать хэндлер Aiogram для обработки ошибки на Python?

    @twistfire92
    Python backend developer
    Вам тут нужна машина состояний (гуглите aiogram FSM), информации в интернете достаточно много. С ее помощью сможете регистрировать текущее состояние каждого пользователя. Например сейчас пользователь в состоянии ввода цены на товар, поэтому в следующем сообщении которое он введет ожидается число. Если приходится выводить ошибку - выводите и не меняйте состояние пользователя
    Ответ написан
    1 комментарий
  • Как сделать inline кнопку чтобы при нажатии можно было позвонить человеку?

    @twistfire92
    Python backend developer
    Нет такого функционала у API телеги. Разве что сделать какую-то веб прослойку, на которую будет ссылаться кнопка и уже там при открытии вызывать tel:xxxxxxxxxx

    Но это что-то костыльное все равно
    Ответ написан
    Комментировать