• Бот удаляет сразу несколько сообщений из чата. Является ли это нарушением лимитов Телеграм?

    @EugeneVKruglov Автор вопроса
    При внимательном изучении логов выяснилось, что в некоторые моменты происходит нарушение условия первичного ключа БД, а отсюда уже запускается цепь событий, приводящая к падению бота. Исправил ПК плюс вместо bot.polling(none_stop = True) сделал bot.infinity_polling. Пока все работает нормально.
    Ответ написан
    Комментировать
  • Как получить username пользователя по нажатию inline кнопки и, сделать так чтобы бот его отправил в чат? pytelebot, pytelegrambotapi?

    @EugeneVKruglov
    user = callback.from_user.username
    Если нужно сделать ник кликабельным, нужно добавить к нему в начале @
    А дальше отправить через send_message
    Ответ написан
    3 комментария
  • Как направить вывод ошибок из консоли в файл?

    @EugeneVKruglov Автор вопроса
    Все-таки, похоже, я правильно настроил службу Линукс. Удалось получить логи ошибок. Судя по всему, бот отваливается из-за каких-то внешних причин. Может кто-нибудь подсказать, что-то с этим можно сделать?
    Лог (извините, что длинный):
    spoiler
    2023-01-30 22:30:19,823 (__init__.py:1083 MainThread) ERROR - TeleBot: "Threaded polling exception: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway"
    2023-01-30 22:30:19,824 (__init__.py:1085 MainThread) ERROR - TeleBot: "Exception traceback:
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1073, in __threaded_polling
        polling_thread.raise_exceptions()
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 118, in raise_exceptions
        raise self.exception_info
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 100, in run
        task(*args, **kwargs)
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 649, in __retrieve_updates
        updates = self.get_updates(offset=(self.last_update_id + 1),
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 623, in get_updates
        json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 321, in get_updates
        return _make_request(token, method_url, params=payload)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 162, in _make_request
        json_result = _check_result(method_name, result)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 189, in _check_result
        raise ApiTelegramException(method_name, result, result_json)
    telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway
    "
    2023-01-30 22:30:20,115 (__init__.py:1083 MainThread) ERROR - TeleBot: "Threaded polling exception: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway"
    2023-01-30 22:30:20,115 (__init__.py:1085 MainThread) ERROR - TeleBot: "Exception traceback:
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1073, in __threaded_polling
        polling_thread.raise_exceptions()
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 118, in raise_exceptions
        raise self.exception_info
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 100, in run
        task(*args, **kwargs)
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 649, in __retrieve_updates
        updates = self.get_updates(offset=(self.last_update_id + 1),
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 623, in get_updates
        json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 321, in get_updates
        return _make_request(token, method_url, params=payload)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 162, in _make_request
        json_result = _check_result(method_name, result)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 189, in _check_result
        raise ApiTelegramException(method_name, result, result_json)
    telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway
    "
    2023-01-30 22:30:20,658 (__init__.py:1083 MainThread) ERROR - TeleBot: "Threaded polling exception: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway"
    2023-01-30 22:30:20,659 (__init__.py:1085 MainThread) ERROR - TeleBot: "Exception traceback:
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1073, in __threaded_polling
        polling_thread.raise_exceptions()
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 118, in raise_exceptions
        raise self.exception_info
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 100, in run
        task(*args, **kwargs)
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 649, in __retrieve_updates
        updates = self.get_updates(offset=(self.last_update_id + 1),
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 623, in get_updates
        json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 321, in get_updates
        return _make_request(token, method_url, params=payload)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 162, in _make_request
        json_result = _check_result(method_name, result)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 189, in _check_result
        raise ApiTelegramException(method_name, result, result_json)
    telebot.apihelper.ApiTelegramException: A request to the Telegram API was unsuccessful. Error code: 502. Description: Bad Gateway
    "
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 445, in _make_request
        six.raise_from(e, None)
      File "<string>", line 3, in raise_from
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 440, in _make_request
        httplib_response = conn.getresponse()
      File "/usr/lib/python3.9/http/client.py", line 1347, in getresponse
        response.begin()
      File "/usr/lib/python3.9/http/client.py", line 307, in begin
        version, status, reason = self._read_status()
      File "/usr/lib/python3.9/http/client.py", line 268, in _read_status
        line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
      File "/usr/lib/python3.9/socket.py", line 704, in readinto
        return self._sock.recv_into(b)
      File "/usr/lib/python3.9/ssl.py", line 1241, in recv_into
        return self.read(nbytes, buffer)
      File "/usr/lib/python3.9/ssl.py", line 1099, in read
        return self._sslobj.read(len, buffer)
    socket.timeout: The read operation timed out
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
        resp = conn.urlopen(
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 755, in urlopen
        retries = retries.increment(
      File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 532, in increment
        raise six.reraise(type(error), error, _stacktrace)
      File "/usr/lib/python3/dist-packages/six.py", line 719, in reraise
        raise value
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 699, in urlopen
        httplib_response = self._make_request(
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 447, in _make_request
        self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 336, in _raise_timeout
        raise ReadTimeoutError(
    urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=25)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/local/bin/AF_PatientBot/main.py", line 1404, in <module>
        bot.polling(none_stop = True)
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1043, in polling
        self.__threaded_polling(non_stop=non_stop, interval=interval, timeout=timeout, long_polling_timeout=long_polling_timeout,
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1118, in __threaded_polling
        raise e
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 1073, in __threaded_polling
        polling_thread.raise_exceptions()
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 118, in raise_exceptions
        raise self.exception_info
      File "/usr/local/lib/python3.9/dist-packages/telebot/util.py", line 100, in run
        task(*args, **kwargs)
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 649, in __retrieve_updates
        updates = self.get_updates(offset=(self.last_update_id + 1), 
      File "/usr/local/lib/python3.9/dist-packages/telebot/__init__.py", line 623, in get_updates
        json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 321, in get_updates
        return _make_request(token, method_url, params=payload)
      File "/usr/local/lib/python3.9/dist-packages/telebot/apihelper.py", line 156, in _make_request
        result = _get_req_session().request(
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 655, in send
        r = adapter.send(request, **kwargs)
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 529, in send
        raise ReadTimeout(e, request=request)
    requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.telegram.org', port=443): Read timed out. (read timeout=25)
    Ответ написан
    Комментировать
  • Как узнать название темы Телеграм по ее ID?

    @EugeneVKruglov Автор вопроса
    Выяснил. У сообщения есть поле message.forum_topic_created.name, в котором и содержится нужное название.
    Ответ написан
    1 комментарий
  • Почему в топике Телеграм не отображается кнопка меню бота?

    @EugeneVKruglov Автор вопроса
    Не нашел информации по этому вопросу нигде, в т.ч. в официальном BotAPI. В десктопном приложении кнопка отображается, а в мобильном нет. Будем надеяться, что при очередном обновлении это исправят. А для отображения самого меню нужно использовать свойство message.message_thread_id.
    Ответ написан
    Комментировать
  • Как узнать, что отправлен последний файл медиагруппы в Телеграм?

    @EugeneVKruglov Автор вопроса
    Решил вопрос так: через bot.middleware_handler отлавливаю первое сообщение медиагруппы, после чего в этом хэндлере продолжаю работу нужных функций. Остальные сообщения приходят, но в эти функции не попадают и обрабатываются отдельно. При этом можно не ждать, когда придут все сообщения из медиагруппы.
    Ответ написан
    Комментировать
  • Как загрузить целый пак фоток в тг?

    @EugeneVKruglov
    С aiogram я не работаю, а в pyTelegramBotApi это реализуется через bot.send_media_group(), где в параметрах передается список медиафайлов (от 2 до 10). Caption нужно установить только для 1-го элемента списка.
    Ответ написан
    Комментировать
  • Как вывести определенное количество кнопок в боте?

    @EugeneVKruglov
    Делюсь своим. Разобраться можно. Только кнопки Inline, но смысл функции одинаковый: вывести любое нужное количество кнопок.

    from telebot import types
    
    def message_dialog(*args):
        btns_in_row = 3
        buttons = []
        buttons.extend([*args])
        if len(buttons) < 3:
            raise AttributeError('Ошибка! Диалог должен иметь не менее 3 аргументов: заголовок, user_id и названия кнопок')
        caption = buttons[0]
        del buttons[0]
        user_id = buttons[0]
        if type(user_id) != int:
            raise AttributeError('Второй аргумент (user_id) должен быть числом')
        del buttons[0]
        keyboard = types.InlineKeyboardMarkup()
        keyboard.row_width = btns_in_row
        btn_count = len(buttons)
        row_count = btn_count//btns_in_row
        surplus = btn_count - row_count * btns_in_row
        btn_no = -1
        def fill_kb_row(btn_names:list, count):
            btn_list = []
            for N in range(count):
                nonlocal btn_no
                btn_no = btn_no + 1
                if len(str(btn_names[btn_no])) > 20:
                    raise AttributeError('Текст на кнопке не должен быть длиннее 20 символов, включая пробелы и знаки препинания')
                btn = types.InlineKeyboardButton(btn_names[btn_no], callback_data = 'dlg_' + btn_names[btn_no] + '_' + str(user_id))
                btn_list.append(btn)
            return btn_list
        for i in range(row_count):
            keyboard.row(*fill_kb_row(buttons, btns_in_row))
        keyboard.row(*fill_kb_row(buttons, surplus))
        return caption, keyboard

    Использование:
    caption, keyboard = message_dialog('⚠️ Выберите вариант:', message.from_user.id, 'Да', 'Нет', 'Может быть', 'Отмена')
    bot.send_message(message.chat.id, caption, reply_markup = keyboard)
    Ответ написан
    Комментировать
  • Как сделать таймер обратного отсчёта в обычном telegram боте?

    @EugeneVKruglov
    Можно по таймеру изменять сообщение бота: выводить время с помощью bot.edit_message_text(). Но в Телеграм, насколько я знаю, существуют ограничения для ботов - не более 30 сообщений в минуту. А зачем это нужно?
    Ответ написан
    Комментировать
  • Как узнать и зафиксировать время, когда пользователь нажал inline-кнопку?

    @EugeneVKruglov Автор вопроса
    Сделал тупо, но просто: после первого сообщения пользователя извлекаю из сообщения время Телеграм, определяю локальное время системы через time. time() и при необходимости ввожу поправку. Для абсолютного большинства задач вполне достаточно.
    Ответ написан
    Комментировать
  • Как выделить работе функции определенное время?

    @EugeneVKruglov
    Запустить второй процесс, где по таймеру через 20 секунд устанавливать переменную, например, в True. В цикле функции проверять этот флаг. Если этот флаг равен True, прекращать работу функции.
    Ответ написан
  • Как проверить, что строка состоит лишь из цифр?

    @EugeneVKruglov
    S = '1234890'
    if not any(map(str.isalpha, S)):
        print('Строка состоит только из цифр')
    else:
        print('Строка содержит не только цифры')
    Ответ написан
    Комментировать
  • Как продолжить работу бота?

    @EugeneVKruglov
    Запишите хэндлер так
    yes1_btn = types.InlineKeyboardButton(text="ДА", callback_data="yes1")
    
    @bot.callback_query_handler(func=lambda call: call.startswith('yes1'))
    def SC_solvent(call):
        markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
            first = types.KeyboardButton('1')
            second = types.KeyboardButton('2')
            markup.add(first, second)
            bot.send_message(call.message.chat.id, 'Выберите', reply_markup=markup)

    Аналогично для no1_btn
    Ответ написан
  • Как правильно импортировать файлы KMZ и KML в карту Гугл?

    @EugeneVKruglov Автор вопроса
    Частично решил проблему, разместив файлы иконок на стороннем хостинге и прописав путь к ним. Но с KMZ проблема не решена...
    Ответ написан
    Комментировать
  • Почему появляется ошибка 'list' object has no attribute 'to_dict'?

    @EugeneVKruglov Автор вопроса
    Решил проблему: всего-то надо было добавить звездочку перед btn_list для распаковки списка.
    keyboard.row(*btn_list)
    Ответ написан
    Комментировать