Задать вопрос
Ответы пользователя по тегу Боты
  • Как убрать лишние знаки?

    Vindicar
    @Vindicar
    RTFM!
    Ещё один не выучил основы языка, но пытается работать с БД.

    fectchone() возвращает кортеж, в твоём случае кортеж с одним элементом. Скобки - это строковое представление кортежа. Как вытащить значение из кортежа - читай по ссылке.

    Кортежи, списки и словари - это вообще азы языка. Их надо знать, и узнавать с первого взгляда.
    Ответ написан
    Комментировать
  • Почему не работает bot_func.stop(Client, module Pyrogram)?

    Vindicar
    @Vindicar
    RTFM!
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    Зачем?!
    Если у тебя бот асинхронный, просто сделай саму функцию GetUserByUsername() async.
    Ответ написан
  • Не выполгяется последняя часть кода @bot.callback_query_handler(func=lambda call:True) def callback2(call): почему и как исправить?

    Vindicar
    @Vindicar
    RTFM!
    @bot.callback_query_handler(func=lambda call:True)
    func говорит боту, когда вызывать обработчик. Бот вызывает только ОДИН обработчик (первый подходящий).
    func=lambda call:True означает, что обработчик должен вызываться для ВСЕХ кнопок.
    Научись различать обработчики по call.data. Например, пусть у одной группы кнопок data начинается с "foo.", а у другой - с "bar.".
    item = types.InlineKeyboardButton('4', callback_data='foo.question1')
    item2 = types.InlineKeyboardButton('3', callback_data='foo.question2')

    gotov = types.InlineKeyboardButton('Готов', callback_data='bar.gotov')

    Тогда ты сможешь прописать два обработчика:
    @bot.callback_query_handler(func=lambda call:call.data.startswith('foo.'))

    и
    @bot.callback_query_handler(func=lambda call:call.data.startswith('bar.'))


    Разумеется, вместо foo и bar можно придумать свои префиксы, в том числе многоуровневые (типа callback_data='questions.q1.answer1').
    Ответ написан
    1 комментарий
  • Как правильно одновременно запустить двух Telegram ботов одной программой на Python?

    Vindicar
    @Vindicar
    RTFM!
    Ну потому что ты фигню написал.
    th_bot = Thread(target=pyrobot(), args=())
    th_userbot = Thread(target=aiobot(), args=())

    Ты пытаешься запустить в качестве потока значение, возвращаемое функцией pyrobot(). А так как она уходит в цикл и значения не возвращает, то далее ничего не происходит. До вызова конструктора Thread() дело не доходит. С aiobot() аналогично.

    Еще раз:
    pyrobot() - вызов функции
    pyrobot - ссылка на функцию

    EDIT:
    Оба бота - асинхронные на базе asyncio, им для работы нужен цикл-реактор (event loop). Вообще не факт, что хорошая идея запускать их в потоках.
    Тут есть два варианта, сразу даже не скажу, что проще.
    Вариант А, лобовой: каждый бот создаёт своё собственные реактор через asyncio.new_event_loop(), потом задаёт его как текущий для своего потока через asyncio.set_event_loop(loop). Если ботам не требуется взаимодействовать, то это может быть проще. Если требуется... будут проблемы. Два реактора в одной программе - это не хорошо.

    Вариант Б, адекватный:
    И вызов app.run(), и вызов executor.start_polling(dp, skip_updates=True) скорее всего под капотом создают асинхронную функцию (корутину), и запускают её в реакторе. Тогда ты можешь обойтись без потоков, заставив обоих ботов работать на одном реакторе. Нужно будет зарыться в доки, или даже глянуть исходники.

    Например, для пирограмма написано такое:
    When calling this method (app.run()) without any argument it acts as a convenience method that calls start(), idle() and stop() in sequence. It makes running a single client less verbose.

    Т.е. вместо вызова app.run() ты можешь изменить код так:
    async def pyrobot():  # обрати внимание, теперь функция асинхронная!
        print("pyro started")
        @app.on_message(filters.chat("some_chat"))
        async def print_pyrogram():
            print("Pyrogram")
        # это вместо вызова app.run(), как написано в доках.
        await app.start()
        try:
            await app.idle()
        finally:
            await app.end()

    Затем делаешь аналогичный трюк с aiobot(). Нужно посмотреть в доках на аиограм, как именно.

    И потом запускаешь обоих ботов кодом вида...
    asyncio.run(asyncio.gather(pyrobot(), aiobot()))
    Ответ написан
    3 комментария
  • Как отправлять текст соответствующий картинке в телеграм боте на Python?

    Vindicar
    @Vindicar
    RTFM!
    1. вынеси random.choice(os.listdir('test')) в переменную, например, img
    2. используй os.path.splitext(os.path.basename(img))[0], чтобы получить имя файла картинки без расширения
    3. Не забудь отправить файл через photo = open('test/' + img, 'rb')
    4. PROFIT
    Ответ написан
    2 комментария
  • Бот рандомно выбирает вопрос, но проверяет по ответам для 1 вопроса, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    if x == 1:
        @bot.message_handler(content_types="text")
        def send(message):
            ...

    Так работать НЕ будет. Ты явно не очень понимаешь, что делаешь.

    1. Должна быть только одна функция, декорированная как @bot.message_handler(content_types="text"). Если их несколько, отработате только одна.

    2. Ты должен хранить сведения:
    - Какой вопрос был последним задан тому или иному пользователю
    - Какие вопросы были уже заданы тому или иному пользователю
    В рамках обучения их можно хранить в словаре, но в реальном боте потребуется постоянное хранилище (например, БД), в котором эти сведения пережили бы перезапуск бота

    3. Внутри обработчика @bot.message_handler ты должен получить ID пользователя, отправившего сообщение, взять из описанного выше хранилища номер последнего заданного вопроса (если есть), и уже на основании этого номера судить о том, правильный ли ответ.
    Ответ написан
  • Как заставить дискорд бота запустить песню?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе бот пишет прямым текстом где он ищет библиотеку:
    OSError: dlopen(opus, 0x0006): tried: 'opus' (no such file), '/usr/local/lib/opus' (no such file), '/usr/lib/opus' (no such file), '/Users/similization/Programming/python/discord_bot/opus' (no such file)

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

    Vindicar
    @Vindicar
    RTFM!
    Вариантов много. Самый простой - храни в БД время обновления (например, время, когда была добавлена запись), и пусть его бот периодически проверяет. Хорошо работает в том плане, что БД может обновляться разными источниками, бот о них знать не обязан. Но вносит лаг между обновлением данных и реакцией бота. Да и бот базу понапрасну дергает.

    Так как в тегах postgre, почитай про команду NOTIFY. Она вроде примерно про то же самое.

    Также есть вариант с сокетом - бот слушает UDP-сокет, парсер на него посылает пакет с оповещением. Плюс в том, что оповещать может любая программа, которая может до этого сокета достучаться.
    Ответ написан
    1 комментарий
  • Почему не принимает сообщение?

    Vindicar
    @Vindicar
    RTFM!
    text=(int)
    Это не будет работать.
    Учи, как пользоваться реализацией FSM (finite state machine) в aiogram.
    Ответ написан
    Комментировать
  • Как вывести данные из массива в сообщение?

    Vindicar
    @Vindicar
    RTFM!
    for product in select_db():
        @dp.callback_query_handler(text=product['name_but'])
        async def pole(message: types.message):
            await bot.send_message(message.from_user.id, product['desk'], reply_markup=but.nav_button)

    Ты делаешь глупость.
    Просто потому, что после того, как этот код отработает, созданные тобой копии обработчика pole() останутся, и будут мешать.
    Используй один, более общий обработчик callback_query_handler, и в нём уже смотри, какой текст тебе пришёл, какой пользователь его отправил, и что с этим текстом надо делать.
    Ответ написан
    1 комментарий
  • Как сделать условие в SQLite Python?

    Vindicar
    @Vindicar
    RTFM!
    Ну так у тебя второй запрос запршивает всех пользователей, без условия.
    А вообще приведённый код не имеет смысла и не должен работать вообще никак.
    for i in cursor.fetchone("SELECT ID FROM user_info WHERE RANK = '1'"):

    Ты перебираешь столбцы в первой строке (fetchone), для которой RANK = '1'. Это при том, что запрос возвращает тебе только один столбец - ID. А ещё метод fetchone() не принимает параметров. Ты пропустил вызов execute()?

    Потом ты почему-то берёшь 0й символ этого столбца. Если он равен 1 (а он не будет равен 1, так как это символ, а не число).
    Потом ты перебираешь всех пользователей, и отправляешь им сообщения (при этом у тебя в вызове send_message() две опечатки - в имени переменной и незакрытая скобка).

    А ещё у тебя отступы кривые - почему for i с отступом?

    В общем, по такой бредятине понять, в чём дело, нереально.
    Ответ написан
    4 комментария
  • Как ответить пользователю через бота?

    Vindicar
    @Vindicar
    RTFM!
    Хранить где-то (в БД, например) какое сообщение закрытого чата соответствует какому пользователю. При получении сообщения-ответа в закрытом чате узнать ID отвеченного сообщения, посмотреть в базе, какой пользователь отправил оригинал, переслать текст этому пользователю.
    Ответ написан
  • Ошибка TypeError: 'tuple' object is not callable?

    Vindicar
    @Vindicar
    RTFM!
    result = cursor.execute("SELECT id, name, price, colvo FROM tovars").fetchone()
    return result

    fetchone() возвращает либо None, либо кортеж (tuple). Значит, get_item() возвращает None (если такой строки нет) или tuple (если она есть).

    result = get_item()
    tgitem = result()

    Ты пытаешься вызвать (call) кортеж (tuple), как будто это функция. Так нельзя, и питон тебе так и говорит:
    TypeError: 'tuple' object is not callable

    Читай учебник, что такое кортежи.
    Ответ написан
    9 комментариев
  • Пишу бота в тг, выдается ошибка 'main', как решить?

    Vindicar
    @Vindicar
    RTFM!
    pprint(data)
    data = r.json()

    Тебя порядок не смущает?
    Ответ написан
    3 комментария
  • Почему не работает как положено aioschedule в телеграм боте?

    Vindicar
    @Vindicar
    RTFM!
    aioschedule работает с корутинами. trackingStart() - не корутина, а обычная синхронная процедура.
    Ответ написан
    1 комментарий
  • Как вывести баланс в телеграм боте?

    Vindicar
    @Vindicar
    RTFM!
    Значит у тебя нет записи в БД для этого юзера. Ты add_user() точно выполнял для него?
    Ответ написан
  • Как вызвать асинхронную функцию с синхронной функции?

    Vindicar
    @Vindicar
    RTFM!
    Если твой вызов асинхронной функции сводится к реакции на завершение выполнения синхронного кода, то используй run_in_executor(), он позволяет выносить код хоть в процесс, хоть в поток (смотря какой executor используешь), и оборачивает его в обычную асинхронную корутину, которую можно await-ить. Для простых случаев есть asyncio.to_thread(), но тут вопрос в природе выполняемого кода. CPU-bound код на питоне будет занимать GIL, тормозя остальные потоки (эта общая болезнь для потоков в питоне).

    А вообще есть асинхронные версии селениума, типа aioselenium или selenium-async. Можешь попробовать одну из них.

    Если же тебе нужно вызвать асинхронную корутину именно посреди синхронного кода в другом потоке, то run_coroutine_threadsafe() может помочь. Пример из доков на питон.
    async def coro_func():
         return await asyncio.sleep(1, 42)
    
    # Later in another OS thread:
    
    future = asyncio.run_coroutine_threadsafe(coro_func(), loop)
    # Wait for the result:
    result = future.result()
    Ответ написан
  • Почему выдаёт ошибку с @bot?

    Vindicar
    @Vindicar
    RTFM!
    Блин, еще раз - текст ошибки угадывать нужно?
    Вбил в гугл "@bot.callback_query_handlers", он подсказывает, что наверно нужно "@bot.callback_query_handler" (в конце нет буквы S).
    Ответ написан
    Комментировать
  • Как или с помощью чего сделать Telegram бота, который выполняет скрипт по заданному времени?

    Vindicar
    @Vindicar
    RTFM!
    aioschedule посмотри.
    Ответ написан
    Комментировать