Ответы пользователя по тегу Telegram
  • Как сделать некоторые функции в telegrabotapi Python?

    Vindicar
    @Vindicar
    RTFM!
    1. "with con:" закроет соединение по выходу из блока with.
    2. Зачем вообще хранить справки, если вы их генерируете на лету? Или они будут как-то ещё обрабатываться?
    3. Я бы посоветовал вынести всё, что касается работы с базой и генерации PDF в отдельный класс, а боту оставить ботово, т.е. интеграцию с телегой. Так и отлаживать проще, и код поддерживать.
    Ответ написан
    3 комментария
  • Как отправить музыку через bot.send_audio (telebot, python)?

    Vindicar
    @Vindicar
    RTFM!
    Ты используешь pyTelegramBotAPI? Если заглянуть на гитхаб проекта, можно найти любопытный комментарий в одном из issue:
    You can't set title and performer when you are sending audio by url, but there would be no problem if you will do the same with local file

    Т.е. параметры типа title/performer/thumb работают только при загрузке файла, а не ссылки. ФЗ правда ли это, и если да, то почему такое ограничение.
    Ответ написан
    5 комментариев
  • Почему Телеграм api блокирует client.get_entity()?

    Vindicar
    @Vindicar
    RTFM!
    Очевидно, спамишь запросами слишком часто. Тебе точно нужно имя отправителя?
    Ответ написан
  • Как исправить ошибку при запуске?

    Vindicar
    @Vindicar
    RTFM!
    Ну ошибку даже автопереводчик расшифрует: конструктору класса неизвестен аргумент threaded, который ты передаёшь.
    Вот почему он неизвестен - уже интереснее. Это аргумент есть там уже лет 6.
    Опечатки типа русская/латинская "e" я не наблюдаю...
    На всякий случай уточни версию пакета telebot, который у тебя стоит. Последнйи релиз у них - 3.8.1.
    Ответ написан
  • Как настроить черный список для телеграм бота?

    Vindicar
    @Vindicar
    RTFM!
    Вариант 1, простой: оформи проверку в виде функции вида user_id -> bool (true - заблокирован), вызывай в начале каждого обработчика команды. Если вернёт true, то просто return.
    Вариант 1.5: не знаю, как насчёт телеги, а вот бибилиотека для дискорда позволяет для обработчика команды указать функцию вида "можно ли вызывать этот обработчик?". Может, для библиотеки, которую ты используешь, есть что-то похожее?
    Вариант 2: оформи проверку как декоратор, и декорируй свои обработчики. Чуть короче чем вариант 1, если реакция на забаненного пользователя однотипная (например, игнор), то я бы предпочёл его.
    Ответ написан
  • Как сделать два парсера?

    Vindicar
    @Vindicar
    RTFM!
    А переиспользовать один и тот же driver нельзя?
    Ответ написан
    Комментировать
  • Что не так с кодом?Не работает бот?

    Vindicar
    @Vindicar
    RTFM!
    1. Оформляй код как положено, кнопкой </>
    2. Тебе бот прямо говорит в чём дело:
    FileNotFoundError: [Errno 2] No such file or directory: 'static/welcome.webp'
    Ему в текущей рабочей директории нужна поддиректория static, и в ней файл welcome.webp
    Если файл есть, проверь, нет ли опечаток в имени.
    Также обрати внимание, что путь к файлу относительный, а потому зависит от текущей рабочей директории. Поменяй путь на абсолютный, или вычисляй этот путь относительно пути к исполняемому файлу бота.
    Ответ написан
    2 комментария
  • Ограничение ввода данных в переменную?

    Vindicar
    @Vindicar
    RTFM!
    number1 = message.text.split()[1] #вытащили нужный кусок строки
    try:
      number_value = int(number1) #int() выбросит исключение ValueError, если строка не является записью числа
      if  not (0 < number_value <= 1000):
        raise ValueError() #мы сами выкинем ValueError, если число недопустимое
    except ValueError: 
      await message.answer('введите число от 1 до 1000') #ругаем пользователя
      return #завершаем обработку команды
    #если управление дошло досюда, число number_value допустимое.
    Ответ написан
    Комментировать
  • Как прибавить +1 к значению в sqlite?

    Vindicar
    @Vindicar
    RTFM!
    > Сама ошибка - star = cursor.fetchone()[0]
    > TypeError: 'NoneType' object is not subscriptable

    not subscriptable означает что ты пытаешься взять индекс у объекта, который это не поддерживает. В твоем случае объект типа NoneType - т.е. None.
    Иными словами, cursor.fetchone() вернул None, и конечно у None нельзя взять индекс.
    Почему fetchone() вернул None? Потому что запрос SELECT не нашёл ни одной строки с подходящим значением photo!

    Как это решить?
    Вставить в таблицу строку с photo, а если не получится (так как такое photo уже есть), то обновить. Есть два способа.
    1. Кодом. Проверить, что вернул fetchone(). Если None, то делаем INSERT. Если не None, то UPDATE.
    2. Средствами БД, что обычно называется UPDATE/INSERT, или коротко UPSERT. Для sqlite это потребует примерно такого запроса:
    INSERT INTO stars (photo, star) VALUES (ид фото, 1) ON CONFLICT (photo) DO UPDATE SET star = star + 1

    Требование: столбец photo должен быть первичным ключом или хотя бы иметь уникальный индекс, иначе запрос просто будет добавлять дубликат строки.

    ВАЖНО
    f'SELECT star FROM stars WHERE photo = "{photo}"' - никогда так не делайте! Особенно если входные данные получены от пользователя. Это хороший способ заполучить SQL-инъекцию.
    Используйте placeholders, по порядку:
    cursor.execute('SELECT star FROM stars WHERE photo = ?', (photo, ) )
    или по именам
    cursor.execute('SELECT star FROM stars WHERE photo = :photo', {'photo' : photo} )
    И удобнее и безопаснее.
    Ответ написан
    7 комментариев
  • Как сделать кнопку "назад"?

    Vindicar
    @Vindicar
    RTFM!
    Тебе придётся реализовать state machine (оно же конечный автомат) самому. Это не так уж сложно, погугли.
    Если коротко: есть список состояний (шагов, на которых может находиться пользователь), есть список переходов между состояниями. Каждому переходу сопоставлена кнопка.
    Когда пользователь входит в состояние, выведи кнопки, соответствующие всем переходам из этого состояния. Когда пользователь нажимает кнопку, перейди в состояние, помеченное как конец соответствующего перехода.
    Текущее состояние нужно хранить для каждого пользователя отдельно. По-хорошему это надо делать в БД (чтобы состояния пережили перезапуск бота), но обучения ради можно и в памяти, просто в словаре вида user_id:state_id.
    Ответ написан
    Комментировать
  • Как заблокировать человека в боте?

    Vindicar
    @Vindicar
    RTFM!
    Храни список (в файле, а лучше в базе данных) ID заблокированных, при поступлении команды проверяй что ID отправителя сообщения нет в списке.

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

    Vindicar
    @Vindicar
    RTFM!
    Фиксируешь время нажатия на кнопку.
    Выбираешь из базы значение предыдущего времени по id пользотеля запросом SELECT.

    Если значения нет, человек пишет в первый раз, заносим значение времени и id пользователя в базу запросом INSERT. Отправляем сообщение о бонусе.

    Если значение есть, и разница между ним и текущим временем более 24 часов, человек может получить бонус. Обновляем значение в базе запросом UPDATE и отправляем сообщение о бонусе.

    Если значение есть, и разница менее 24 часов, отправляем сообщение с оставшимся до следующего бонуса временем.
    Ответ написан