Ответы пользователя по тегу Telegram
  • Query is too old and response timeout expired or query id is invalid, как решить?

    @o5a
    Потому что answer_callback_query первым параметром принимает id, а не текст.
    await bot.answer_callback_query(callback_query.id, 'Выбери удобное время')
    Ответ написан
    4 комментария
  • Как проверить реферальную ссылку в Telegram bot?

    @o5a
    Если речь про то, как считать передаваемые в команду аргументы, то просто разбором текста (команда по сути приходит как message.text в виде '/start 12345678').
    @bot.message_handler(commands=['start'])
    def start(message):
        # соответственно берем первый аргумент
        per = message.text.split()[1]

    Можно предусмотреть проверку на случай, если запустят команду без аргументов, например так
    args = message.text.split()[1:]
    per = args[0] if args else None
    Ответ написан
    Комментировать
  • Как сделать так, чтобы бот отвечал на определенную команду в определенном меню?

    @o5a
    Например учитывать только callback, а не прямой текст:
    import telebot
    from telebot import types
    
    bot = telebot.TeleBot(TOKEN)
    
    @bot.message_handler(commands=['start'])
    def start(message):
        keyboard = types.InlineKeyboardMarkup()
        key_buy = types.InlineKeyboardButton(text='Покупка', callback_data='/buy')
        key_info = types.InlineKeyboardButton(text='Инфо', callback_data='/info')
        keyboard.add(key_buy, key_info)
        bot.send_message(message.chat.id, 'Команды:', reply_markup=keyboard)
    
    @bot.message_handler(content_types=["text"])
    def handle_text(message):
        if message.text.startswith('/'):
            bot.send_message(message.chat.id, 'Неправильная команда')
    
    @bot.callback_query_handler(func = lambda call: True)
    def calls(call):
        if call.data == '/buy':
            bot.send_message(call.message.chat.id, 'Обрабатываем покупку')
        elif call.data == '/info':
            bot.send_message(call.message.chat.id, 'Вот инфо')
    
    bot.polling(none_stop=True)
    Ответ написан
  • Ошибка записи данных из бота в файл?

    @o5a
    Потому что это так не делается. От того, что хэндлеры записали как вложенные функции, они не будут работать только внутри тех функций. Первый записанный хэндлер одинакового типа (в данном случае content_types=['text']) и будет использоваться для всех вводов.
    В данном случае подойдет использование register_next_step_handler, когда указывается функция, обрабатывающая последующий шаг операции. Про нее много где написано подробно, в т.ч. на этом сайте.
    Для данного бота будет примерно так:
    вместо
    @bot.message_handler(commands=["api_id"])
    def api_id(m, res=False):
        bot.send_message(m.chat.id, 'Введите Api ID, полученное на сайте my.telegram.org')
        @bot.message_handler(func=lambda message: True, content_types=['text'])
        def msg(message):
            print(message.text)
            f = open('C:/Users/асер/Desktop/python/bot/api_id.txt', 'a')
            f.write(message.text + '\n')
            f.close()
            bot.send_message(m.chat.id, 'Прекрасно!')

    сделать так (указать запрос api_id следующим шагом):
    @bot.message_handler(commands=["api_id"])
    def api_id(m, res=False):
        bot.send_message(m.chat.id, 'Введите Api ID, полученное на сайте my.telegram.org')
        # указываем запуск следующего шага обработки - свою функцию
        bot.register_next_step_handler(message, get_api_id)
    
    def get_api_id(message):
        print(message.text)
        with open('C:/Users/асер/Desktop/python/bot/api_id.txt', 'a') as f:
            f.write(message.text + '\n')
        bot.send_message(m.chat.id, 'Прекрасно!')


    Аналогично для обработчиков других команд.
    Ответ написан
    1 комментарий
  • Incorrect number of bindings supplied. The current statement uses 3, and there are 1 supplied. Как решить проблему?

    @o5a
    Ошибка говорит о том, что в качестве параметра execute передается несоответствующее запросу число данных.

    В 'INSERT INTO post VALUES (?, ?, ?)' предполагается 3 значения, а tuple(data.values()) содержит только одно, т.е. в словаре только 1 ключ. Проверяйте, что туда пишете и что хотите взять.
    Ответ написан
    Комментировать
  • Как изменить переменную в бд, при условии наличия нужного параметра из того-же бд?

    @o5a
    Если речь про формирование бонуса по условию, зависящему от других полей (как в данном случае buster1 и т.п.), можно это прописать в самом запросе через оператор case (по логике похоже на ветвления if в самом python). Например:

    sql = "UPDATE users SET balance = balance + \
    CASE WHEN buster1 = 'Нет' AND buster2 = 'Нет' AND buster3 = 'Нет' THEN 0.010 \
        WHEN buster1 = 'Да' AND buster2 = 'Нет' AND buster3 = 'Нет' THEN 0.050 \
        WHEN buster1 = 'Да' AND buster2 = 'Да' AND buster3 = 'Да' THEN 0.100 \
    END \
    WHERE id = ?"

    И соответственно в запросе передавать только id пользователя, сам бонус будет считаться автоматически.
    Таким образом сами формируете зависимость бонуса от этих полей.

    Если же имелось в виду что-то другое, лучше пишите подробнее с примером.
    Ответ написан
    1 комментарий
  • В какую строку кода надо добавить lower?

    @o5a
    if msg.text.lower().startswith('инфа'):
    Ответ написан
    Комментировать
  • Как достать и отправить все строки в Telegram-боте, включающие в себя одну из переменных в базе данных?

    @o5a
    В result содержится вложенный список со всеми полями данных таблицы. Примерно так:
    [(ряд1значение1, ряд1значение2, ...), (ряд2значение1, ряд2значение2, ...), ...]
    Чтобы использовать join нужно сначала сформировать из всех значений ряда текст, чтобы получилось вида
    [строка_ряда1, строка_ряда2, ... ]
    тогда уже можно будет сделать '\n'.join()

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

    @o5a
    Добавить ограничение по уникальности этого поля, затем при добавлении записи можно будет при возникновении конфликта (дублировании записей) автоматически пропустить добавление. Конкретный формат зависит от базы данных. Для sqlite:
    добавить unique(имя поля) в создание таблицы
    create table mytable (id integer primary key,
    user_id integer,
    ....,
    unique(user_id)
    )

    затем при вставке данных
    INSERT INTO mytable (user_id, user_name) VALUES (...) ON CONFLICT(user_id) DO NOTHING


    Можно и более костыльный вариант. Перед вставкой данных делать запрос
    result = cur.execute('select 1 from mytable where user_id = ?), (user_id, )).fetchone()
    if not result:
       # делаем insert
    Ответ написан
    Комментировать
  • Бот не отвечает на команды?

    @o5a
    Потому что это обработчик уже пришедшего текста ("БОНУС" и т.п.). А кнопки нужно вставить в обработчик команды /start
    @bot.message_handler(commands=['start'])
    def start(message):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
        butt_1 = types.KeyboardButton("ПОЛУЧИТЬ ДЕНЬГИ")
        butt_2 = types.KeyboardButton("БОНУС")
        markup.add(butt_1, butt_2)
    
        bot.send_message(message.chat.id, "Чё надо?", reply_markup=markup)
    Ответ написан
  • Ограничение ввода данных в переменную?

    @o5a
    Проверку нужно до перевода в число делать, плюс добавить проверку на само число (или отсутствие букв, по желанию)
    async def process_start_command(message: types.Message):
        number1 = message.text.split()[1]
        if not (number1.isdigit() and 1 <= int(number1) <= 1000):
        	await message.answer(f'введите число меньше 1000')
        else:
            random_number = random.randint(0, int(number1))

    И кстати random.randint(0, x) выдаст число из x+1 набора чисел, а не x.
    Ответ написан
  • Дает кучу ошибок при написании бота на Python. Что делать?

    @o5a
    Параметры (команды, типы) в хэндлере нужно указывать списком:
    @bot.message_handler(commands=['start'])
    Ответ написан
    3 комментария
  • Ошибка AttributeError: 'NoneType' object has no attribute 'from_user', как исправить?

    @o5a
    Так и проверяйте в условии, что ответ
    if message.reply_to_message:
        bot.send_message(message.chat.id, ~f'@{message.from_user.username} Обнял @{message.reply_to_message.from_user.username}')
    Ответ написан
    2 комментария
  • Telegram bot. Как можно считать информацию введённую пользователем?

    @o5a
    register_next_step_handler поддерживает указание дополнительных параметров вызова функции:
    bot.register_next_step_handler(msg, getweather, city_name)

    Соответственно надо будет изменить саму getweather, чтобы понимала этот параметр
    Ответ написан
    Комментировать
  • Как сделать так, чтобы бот отредактировал свое сообщение через какой-либо промежуток времени?

    @o5a
    В цикле запускать edit_message_text() с обновлением сообщения, ограничивая time.sleep().
    Чтобы не блокировать ввод при множественных запусках можно использовать threading. Возможно есть более правильный способ в данном случае, чем threading, я не особо в курсе, как лучше для телеграма.
    Для примера заполнение по 10%
    from threading import Thread
    
    @bot.message_handler(commands=['start'])
    def start(message):
        msg = bot.send_message(message.chat.id, f'заполнение 0%')
        t = Thread(target=thread_update_text, args=[msg, 'заполнение {}%'])
        t.start()
    
    def thread_update_text(message, text):
        for i in range(10,110,10):
            time.sleep(1)
            bot.edit_message_text(chat_id=message.chat.id, message_id=message.message_id, text=text.format(i))
    Ответ написан
  • Как мне отправить все картинки из папки через бота на питоне?

    @o5a
    Потому что в msg.photo содержится не одно, а список вариантов с разными разрешениями. Так что сначала нужно выбрать нужное. Например так
    photo = max(msg.photo, key=lambda x: x.height)
    file_id = photo.file_id

    P.S. хотя я упустил, что ругается на 'NoneType', т.е. информации о фото вообще нет (msg.photo = None), причина еще в чем-то
    Ответ написан
  • Ошибка в sqlite3 python?

    @o5a
    Для tik не использован fetchone(), так что в него запишется сам курсор, а не его данные. Но даже в таком случае он текстом должен был написать что-то типа <sqlite3.Cursor ...а не просто пустую строку.
    Лучше сделать этот кусок так:
    ...
          user_info = sql.execute(f"SELECT tiktok, cash from users WHERE login = '{message.from_user.id}'").fetchone()
          if user_info:
              tik, balance = user_info
              bot.send_message(message.chat.id, f"ваш тикток: {tik}")
              bot.send_message(message.chat.id, f" Ваш баланс: {balance} RUB ")
    Ответ написан
    Комментировать
  • Как сделать закрытый Telegram бот?

    @o5a
    def get_access_status(user_id):
        cursor.execute("SELECT 1 FROM Dostyp WHERE Iduser = %s", (user_id, ))
        return bool(cursor.fetchone())
    
    # сам проверка в функции
    @bot.message_handler(commands=['start'])
    def welcome(message):
        if get_access_status(message.from_user.id):
            # доступ есть, продолжаем
    Ответ написан
    Комментировать
  • Как боту сделать рассылку в телеграмме через python?

    @o5a
    fetchall() в get_subscriptions в текущем виде будет возвращать вложенные списки со всеми полями. Лучше сразу возвращать только нужную информацию - список самих id
    ...
        def get_subscriptions(self, status = True):
            with self.connection:
                return [x[0] for x in self.cursor.execute("SELECT user_id FROM `subscriptions` WHERE `status` = ?", (status,)).fetchall()]

    тогда можно просто напрямую использовать идентификаторы при отправке
    @dp.message_handler(commands=['go'])
    async def go(message: types.Message):
      subscriptions = db.get_subscriptions()
      for user in subscriptions:
        await bot.send_message(user, "...")
    Ответ написан
  • Как ограничить отправку в боте Telegram?

    @o5a
    Без кода сложно что-то однозначное сказать, но можете выставлять статус по пользователям (хотя бы просто словарь с данными). Обработка началась - выставляете пользователю статус, что обрабатывается запрос. И пока статус стоит, другая команда не выполняется. По окончании обработки статус сбрасывается. Условно:
    user_status = {}
    
    @bot.message_handler ...
    def process_something(message):
        if user_status.get(message.from_user.id, 0) == 0:
            user_status[message.from_user.id] == 1
            start_our_process()
    Ответ написан
    Комментировать