Ответы пользователя по тегу Telegram
  • Как правильно настроить многопоточность у бота telegram?

    Vindicar
    @Vindicar
    RTFM!
    Если коротко: пусть бот работает в главном потоке. ФЗ, синхронно или асинхронно, зависит от используемой библиотеки. Судя по приведённому коду, синхронно.
    А вот все длительные операции запускайте в отдельных потоках или даже процессах.
    Для общения между потоком бота и рабочими потоками/процессами организуйте две очереди. Из одной потоки обработки данных будут принимать задания. В другую они будут складывать сообщения для отправки (текст + id пользователя, например). Тогда основной бот должен по готовности запроса положить объект с описанием задания в первую очередь, а также периодически проверять наличие сообщений во второй. При наличии - извлекать и отправлять по назначению.
    Ответ написан
  • Почему то ошибки в консоле нету, но и сообщение (123), не отправляться (aiogram)?

    Vindicar
    @Vindicar
    RTFM!
    test = False
    Ниже
    if test == True:
    async def prdfg(message: types.Message):
    У тебя prdfg не будет объявлено, так как на момент выполнения этой строки test всё ещё False.
    Ответ написан
  • Возможно ли сделать стрим в видео звонок телеграм?

    Vindicar
    @Vindicar
    RTFM!
    Гипотетически - да. Но не факт, что есть готовые решения, и тем более конкретно для ноды. Нужно смотреть используемую вами библиотеку для телеги, поддерживает ли она видео-звонки, и если да, что в каком виде она принимает видеопоток. Если это что-то абстрактное, то возможно, удастся завернуть видео из стрима в этот формат и скармливать телеге понемножку. Если же требуется доступ именно к вебкамере, то тогда искать реализацию виртуальной вебкамеры.
    Ответ написан
    1 комментарий
  • Как из базы данных получить все значения столбца в список?

    Vindicar
    @Vindicar
    RTFM!
    Если используешь для работы с базой движок sqlite3, то будет как-то так
    con = sqlite3.connect("mydb.sqlite") #подразумеваю, что таблицу ты уже создал
    cur = con.cursor()
    cur.execute("SELECT id FROM users")
    ids = [row['id'] for row in cur]

    Только если данных много, такой запрос может съесть много памяти.
    Так что встречный вопрос: а тебе зачем выбирать всю таблицу? Может, всё-таки нужно отфильтровать часть записей?
    Ответ написан
    Комментировать
  • Как отправлять по очереди данные заказа по команде "Дальше" из БД Sqlite3?

    Vindicar
    @Vindicar
    RTFM!
    Ответ очевиден. Тебе нужно для пользователя хранить, на какой позиции он остановился, и продолжать оттуда.
    Простой способ - использовать модификаторы OFFSET и LIMIT в SQL запросе. Тогда достаточно будет хранить просто число, которое будет использоваться в OFFSET. При начальном запросе это число ставить в 0, а по нажатию дальше - увеличивать на значение LIMIT.

    Технически это можно оформить таблицей БД с парами "id пользователя - число".
    Ответ написан
    1 комментарий
  • Как сделать, чтобы телеграм-бот отвечал уже вычисленным числом?

    Vindicar
    @Vindicar
    RTFM!
    1. Поставь обработчик "входящее сообщение".
    2. Прогони текст сообщения через float(), а для надёжности можно попробовать использовать locale.atof() - оно понимает региональное форматирование. Например, в США сумма "5,000.00" а у нас "5 000,00", причем и там и там могут написать просто "5000". Выцепить все варианты будет непросто, но atof() для начала сойдёт.
    3. Рассчитай проценты.
    4. Ответь на сообщение рассчитанной суммой процентов.

    Вот и всё. Если хочешь код - изволь предоставить то, что написал сам (и оформить кнопкой </>).
    Ответ написан
    5 комментариев
  • Как для тг бота сделать одновременно слушатель сообщений и выполнение чего-то в цикле?

    Vindicar
    @Vindicar
    RTFM!
    Советую почитать про основы работы асинхронных программ.

    Но если на пальцах, считай, что из bot.polling() программа не выйдет до своего завершения. Она там будет крутиться, ждать события, и дёргать обработчики.

    Поэтому всё, что ты хочешь научить бота делать, нужно делать
    • ИЛИ в рамках фреймворка (какого кстати? pyTelegramBotAPI? Он это не умеет)
    • ИЛИ в рамках отдельного потока, который запускать до вызова bot.polling()
    • ИЛИ вообще в рамках отдельного скрипта, который вызывать по крону.

    Если в рамках потока, нужно будет посмотреть, позволяет ли телебот вызывать методы из другого потока.
    Ответ написан
    2 комментария
  • Как разобрать запрос на несколько переменных в боте телеграм?

    Vindicar
    @Vindicar
    RTFM!
    Пример запроса? Он должен следовать какой-то специфической форме, я надеюсь?
    Если запрос просто состоит из некольких слов, разделённых пробелами (опционально, строка в кавычках считается одним словом), то посмотри в сторону shlex. Но кроме как "разбить строку по пробелами и экранировать кавычки" shlex мало что умеет.
    Если нужно подобие командной строки (с фишками типа --ключей и необязательных параметров), посмотри в сторону argparse. Тут тебе и преобразование типов данных (т.е. "вот этот параметр должен быть числом"), и справка об использовании, и ещё много чего.
    Если что-то ещё более заковыристое, то посмотри в сторону регулярных выражений. Они позволяют распознавать довольно заковыристые паттерны, но многое придётся делать вручную.
    Если нужен анализ естественной речи... это дело муторное.

    Так что я бы сначала посмотрел argparse. Оно заточено на аргументы командной строки, но чат-боты недалеко от неё ушли.
    Ответ написан
    4 комментария
  • Как добавить айдишников в конфиг.py?

    Vindicar
    @Vindicar
    RTFM!
    > operator = "4609....71" and "109....307"
    Извините мой французский, но что это за фигня? Вы применяете логические операторы к строкам, неужели ничего неладного не заподозрили?
    Вам нужна коллекция idшников, и нужно проверять вхождение в эту коллекцию!
    Например, множество (так как я не думаю, что оператор должен входить в список дважды, верно?):
    operators = {"4609....71",  "109....307"}
    for op in operators: #перебираем элементы множества
        await bot.forward_message(op, message.from_user.id, message.message_id)

    Тогда добавить нового оператора будет легко и просто:
    operators.add("1234....890")
    При этом при попытке повторного добавления просто ничего не произойдёт.
    Аналогично можно удалить:
    operators.remove("1234....890")
    При попытке удаления отсутствующего оператора будет выброшено KeyError.
    Ну и если надо проверить, является ли id оператором:
    if "1234...890" in operators:
    Ответ написан
    Комментировать
  • Нужно как-то остановить цикл и после проверки модератора продолжить его. Бот телеграм(Telebot). Как это сделать?

    Vindicar
    @Vindicar
    RTFM!
    Нет, нельзя. Нужно архитектуру бота менять, так ты результата не добьёшься.

    1. Поступающие запросы складываешь в очередь (а лучше в БД).
    2. Бот периодически проверяет наличие непроверенных запросов и выкидывает их менеджеру. Так как менеджер - существо неторопливое, это можно делать раз в пару минут или даже реже.
    3. По реакции от менеджера запрос помечается как проверенный (одобренный/отклонённый).
    4. Бот периодически проверяет, есть ли проверенные, но не обработанные запросы. Если есть, обрабатывает их, и помечает их как обработанные.
    5. Опционально: периодически запросы, отмеченные как обработанные, удаляются из БД.
    Ответ написан
    Комментировать
  • Почему await con.commit() вызывает ошибку ValueError?

    Vindicar
    @Vindicar
    RTFM!
    Посмотри базовый пример, может, лучше переделать по его образу и подобию?

    pool = await aiomysql.create_pool(host='127.0.0.1', port=3306,
                                          user='root', password='',
                                          db='mysql', loop=loop)
        async with pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute("SELECT 42;")
                print(cur.description)
                (r,) = await cur.fetchone()
                assert r == 42
        pool.close()
        await pool.wait_closed()
    Ответ написан
  • Как сделать некоторые функции в 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 комментариев