• Не работает инлайн-кнопка после нажатия, как исправить?

    @twistfire92
    Python backend developer
    потому что ваше нажатие на кнопку перехватывает хендлер
    @dp.message()
    async def echo(message: Message):

    Который перехватывает воообще все сообщения, в том числе сообщение "оплатить", которое вы посылаете кнопкой. Просто на это сообщение этот хендлер никак не отреагирует, судя по коду. Поднимите хендлер с функцией оплаты выше.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы при написании команды, начался обратный отсчёт?

    @twistfire92
    Python backend developer
    Программа делает ровно то, что вы ей указали. Берет пользователя, и начинает ему показывать обратный отсчет. Потом берет второго пользователя и делает то же самое. И т.д., пока пользователи не закончатся.

    Если вы хотите чтобы все было одновременно, вам следует одновременно все это запускать. Сначала получше изучите асинхронность, потом напишите асинхронную функцию которая принимает на вход id пользователя, запрашивает его количество секунд и пр. По сути функция должна делать все то, что описано у вас в теле цикла.

    И потом можно попробовать запустить это все, например, через asyncio.gather().

    Сразу предупрежу, что если будет много таких пользователей, есть риск схватить временную блокировку от серверов телеги из-за большого количества запросов. Лучше изучите информацию о том, какие есть ограничения по частоте запросов к серверам телеги.
    Ответ написан
  • Как сделать Многопоточную или асинхронную обработку запросов FASTAPI?

    @twistfire92
    Python backend developer
    Скорее всего у вас где-то вызывается синхронный код в асинхронном ендпоинте. И этот код блокирует event loop.
    Посмотрите пример
    @app.get("/delay")
    async def delay():
        time.sleep(10)
        return {"result": "OK!"}
    
    
    @app.get("/instantly")
    async def instantly():
        return {"result": "OK!"}


    Если сделать запрос на /delay и тут же сделать запрос на /instantly, получится то, о чем я говорю, когда синхронная time.sleep() блокирует цикл событий. Ответ от второго запроса придет только после отработки первого. Обратите внимание, что delay объявлена через async def.

    Исправить это можно двумя способами
    - Использовать асинхронный await asyncio.sleep()
    @app.get("/delay")
    async def delay():
        await asyncio.sleep(10)
        return {"result": "OK!"}

    - Объявить функцию синхронной через def
    @app.get("/delay")
    def delay():
        time.sleep(10)
        return {"result": "OK!"}


    Возможно именно в этом у вас проблема. Найдите синхронный код и либо перепишите на асинхронный вариант, если это возможно (если для обращения в другой сервис вы используете requests, замените на aiohttp или httpx), либо саму функцию ендпоинта сделайте синхронной.
    Ответ написан
  • Проблема с импортами, ошибка, сам не смог решить, как сделать?

    @twistfire92
    Python backend developer
    вот это
    sql = f"SELECT * FROM tg(id, sub) values({id_user}, {sub})"


    перенесите в функцию creat_account (переименуйте в create_account) и удалите строку from bot import sub, id_user
    Ответ написан
    2 комментария
  • Как правильно парсить в телебот и requests?

    @twistfire92
    Python backend developer
    а вы хоть смотрели что попадает в nickname после выполнения nickname = message.text.lower()?
    там по идее всегда будет "/username_search"

    После команды предлагайте пользователю отдельно ввести свой никнейм.
    Воспользуйтесь bot.register_next_step_handler()
    Ответ написан
    2 комментария
  • Вопрос по тг боту на aiogram?

    @twistfire92
    Python backend developer
    у вас видимо код был написан для 2-й версии aiogram.

    Зайдите в документацию, там сразу же показан пример как запускать. executor больше не используется
    Ответ написан
    Комментировать
  • Почему бот дважды выполняет команду (telebot)?

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

    Когда пользователь пишет боту лично, то он находится в чате с самим ботом, где участников 2 - пользователь и бот. Поэтому bot.get_chat_members_count(message.chat.id) выдаст всегда значение 2.
    Если бот будет админом в какой-либо группе, тогда уже выведется количество участников этой группы.

    Вот теперь вы берете и проходите в цикле 2 раза, отправляя в этот чат сообщение.

    Вам же надо где-то хранить все id пользователей, с кем бот взаимодействует. Когда будет отлавливаться нужная команда, проходить в цикле по всем id и отправлять им нужный текст сообщения. Можно из этого списка во время отправки исключить текущего пользователя, чтобы самому не получить сообщение.
    Ответ написан
    5 комментариев
  • Как сохранить машиносостоянии игры :кубик в телеграмме с последующей отправкой кубика в канал?

    @twistfire92
    Python backend developer
    Вместо этого
    lambda message: message.text == ''
    Попробуйте указать так:
    lambda message: message.dice
    Ответ написан
    Комментировать
  • Как перенести aiogram-бота с "long polling" на вебхук?

    @twistfire92
    Python backend developer
    Все с нуля писать скорее всего не придется (Хотя хз как именно у вас все написано). В репозитории aiogram есть пример как можно поднять бота на webhook с использованием aiohttp.

    Я использовал FastAPI как ASGI приложение, которое ловило запрос от сервера телеги и вызывало метод dp.feed_update()
    Ответ написан
    Комментировать
  • Как сделать, чтобы message.text смотрел на только что введеный, а не старый текст?

    @twistfire92
    Python backend developer
    Объект message у вас один всегда, который берется из аргументов функции. Вы его нигде не меняете, поэтому при проверке if message.text == 'Подтвердить': всегда вернется одно и то же значение.
    Если вы хотите ожидать от пользователя нового ввода, стоит перекинуть управление в другую функцию.
    Конкретно в вашем случае лучше воспользоваться register_next_step_handler. И каждый раз прокидывать в него оставшиеся элементы списка из cells_products_data.
    Я не уверен, что register_next_step_handler работает в асинхронном режиме, не юзал telebot в async.
    Изучите этот инструмент подробнее.
    Ответ написан
    Комментировать
  • Как сделать форматирование текста пересланого поста в бота тг?

    @twistfire92
    Python backend developer
    В объекте message текст сообщения и правила форматирования разделены по разным полям - text и entities

    aiogram, к счастью, позволяет получить текст сообщения с уже примененным форматированием в форматах markdown или html

    Поэтому вам стоит работать не с message.text, а с message.html_text, или message.md_text

    Не забудьте потом указать нужный ParseMode при отправке измененного сообщения
    Ответ написан
    Комментировать
  • Как создать реферальную систему Python aiogram 3?

    @twistfire92
    Python backend developer
    В обработчике команды start в объекте message смотрите что пришло в поле text. Там будет что-то типа
    "/start MTIzNDU2Nzg5"
    Отбрасываете "/start ", декодируете оставшееся из Base64, получите id пользователя кому отправлять сообщение.

    Можно при вызове create_start_link значение параметра encode установить False, тогда id реферала кодироваться не будет и никакого декодирования делать не надо будет. Но я бы так не делал.
    Ответ написан
  • Как запретить пользователю писать сообщения в группе на время?

    @twistfire92
    Python backend developer
    Есть вероятность, что сервер телеги ожидает от вас время UTC+0, а вы, возможно передаете время своего часового пояса, (UTC+3 или где вы находитесь), поэтому пользователь блокируется не на 30 секунд, а на 3 часа 30 секунд (опять же, если у вас часовой пояс +3)

    Также в документации Bot API указано, что если время бана меньше 30 секунд или больше 366 дней, то пользователь блокируется навсегда.

    Я бы начал проверку с часовых поясов.

    UPD
    А вы точно правильно используете метод
    restrict_chat_member?
    await bot.restrict_chat_member(chat_id=message.chat.id,
                    user_id=message.reply_to_message.from_user.id,
                    until_date=ban_time,
                    permissions=ChatPermissions(can_send_messages=False)
                    )


    Все разрешения нужно передавать через отдельный объект ChatPermissions в параметре permissions
    Ответ написан
    3 комментария
  • Что нужно поправить в коде на Python, который удаляет последний пост в Телеграм канале?

    @twistfire92
    Python backend developer
    Вы должны сначала получить чат с помощью
    await bot.get_chat(chat_id)
    и только потом у этого объекта вызвать метод fetch_all()

    либо
    chat = await bot.get_chat(chat_id)
    messages = chat.fetch_all()

    либо
    messages = (await bot.get_chat(chat_id)).fetch_all()
    Ответ написан
    Комментировать
  • Как хранить константы в python?

    @twistfire92
    Python backend developer
    Как вариант, можете использовать BaseSettings из Pydantic (Но надо смотреть на версию, во второй отдельная либа для настроек). Получится лишь в ваш класс добавить наследование от BaseSettings. Но если вы не собираетесь прокидывать переменные окружения в настройки, то и ваш вариант вполне рабочий.
    Ответ написан
    Комментировать
  • Как запустить скрипт на Python с использованием сторонних библиотек?

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

    @twistfire92
    Python backend developer
    Уберите global переменную choosed_category

    @router.callback_query(F.data == 'shirt_shorts')
    async def ss(callback: CallbackQuery, state: FSMContext):
        await state.set_data({"choosed_category": shirt_shorts}) # прокидываем в state нужные данные
        # либо await state.update_data(choosed_category=shirt_shorts)
        await callback.answer()
        await callback.message.answer('Ты выбрал(а) категорию Футболка / Шорты \n' + txt.calculation)
        await state.set_state(CalculateCost.choosing_cost)
    
    ....
    
    @router.message(CalculateCost.choosing_cost)
    async def calculate(message: Message, state: FSMContext):
        state_data = await state.get_data()
        choosed_category = state_data["choosed_category]
        ....

    По-хорошему все 4 функции с обработкой калбеков можно сократить в одну, но это уже не тема вопроса
    Ответ написан
    3 комментария
  • Можно ли в Python сделать такой механизм, чтобы при изменении значения в любой ветки словаря, я был уведомлен?

    @twistfire92
    Python backend developer
    Как верно подметил fenrir , наследоваться надо от UserDict.
    Чуть поменял код, можете посмотреть что вышло. Была еще проблема в том, что при создании объекта вызывается метод __setitem__, для этого добавил флаг _initialization_finished

    from collections import UserDict
    
    
    class MyDict(UserDict):
        def __init__(self, **kwargs):
            self._initialization_finished = False
            print('Создан объект')
            super().__init__(**kwargs)
            self._initialization_finished = True
    
        def __setitem__(self, item, value):
            if self._initialization_finished:
                print(f"Вы поменяли значение {item} на {value}!")
            if isinstance(value, dict):
                value = MyDict(**value)
            super().__setitem__(item, value)
    
        def __getitem__(self, item):
            print(f"Пытаемся получить значение {item}")
            return super().__getitem__(item)
    
    
    d = MyDict(x='123', y=15, z={'a': 4})
    # Создан объект
    # Создан объект
    
    d['x'] = '456'
    # Вы поменяли значение x на 456!
    
    e = d['y']
    # Пытаемся получить значение y


    Два сообщения подряд "Создан объект" из-за того, что сначала создается основной кастомный словарь, потом создается словарь под ключом z, который тоже вызывает сообщение
    Ответ написан
    Комментировать
  • Как дополнить Python код телеграмм бота?

    @twistfire92
    Python backend developer
    Никак. Такие кнопки просто отправляют сообщение с текстом который в них указан. Т.е. если есть кнопка с текстом "назад", то ее нажатие будет равносильно тому, что вы просто наберете "назад" и отправите.

    Если хотите какой-то более сложной логики с кнопками - используйте InlineButton
    Ответ написан
    Комментировать
  • Ошибка при миграции DJANGO?

    @twistfire92
    Python backend developer
    Попробуй откатить БД к состоянию до первой миграции
    manage.py migrate <имя приложения> <номер последней миграции до новых правок>


    Потом удали эти 2 новые миграции и сгенерируй заново через makemigrations
    Ответ написан
    Комментировать