• Можно ли создать сообщение с инлайн кнопкой, как ответ на другую инлайн кнопку?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Можно. В обработчике inline-кнопки вызываем стандартный метод API sendMessage, содержащий новую inline-клавиатуру, и пользователь получит ещё одно сообщение с другими кнопками.

    Как вариант, можно отредактировать (editMessage) исходное сообщение (его идентификатор прилетает в inline-обработчик), так тоже часто делают.
    Ответ написан
    Комментировать
  • Бот не реагирует на команды ранее все работало поменял токен не помогло Поможете?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Лучше увеличить интервал, 1 секунда это мало, и при любой ошибке ты скорее всего очень быстро сделаешь второй запрос, который и вызовет подобное поведение. Дефолтные 30 секунд это норма, не надо их менять без очень веских причин.

    Long polling так и работает: запрос длится 30 секунд, если приходит событие - запрос завершается досрочно. Это позволяет и события получать быстро, и сервер слишком часто не дёргать.
    Ответ написан
    Комментировать
  • Почему ссылка работает в хром но не работает через href в html?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Потому что символ & (как и некоторые другие символы) в HTML должен экранироваться как &

    upd: Проблема была в чём-то другом. См. комментарии.
    Ответ написан
    5 комментариев
  • Может ли физ лицо создавать интернет-проекты?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Создавать сайт не запрещено, и на это не нужно никаких специальных разрешений, получения лицензий или ещё каких-то бессмысленных телодвижений. Это же не медицинская деятельность, производство продуктов питания, строительство или банковское дело.

    Квалификация данных как персональных очень разнообразна, в некоторых странах под них подапают IP-адреса, электронная почта, куки итд. Также сложно сказать, что именно решит судья в тех случаях, когда сайт будет ответчиком или иной стороной в судебном деле. В России так особенно сложно.

    Для того, чтобы не получать формальных претензий от властей разных стран (в первую очередь ЕС, который требует соблюдать GDPR и другие нормативные акты по отношению к своим гражданам безотносительно места предоставления им услуг), сейчас много кто начал показывать на всякий случай предупреждение о куках и выкладывать формальную политику конфиденциальности (которая всё равно по большому счёту декларация о намерениях). Публиковать свои собственные личные данные в ней необязательно. Достаточно просто указать в ней адрес электронной почты или ссылку на онлайн-форму для связи, с помощью которой можно обратиться с запросом на удаление данных. Ну и стандартные ля-ля об использовании электронной почты для предоставлению пользователю дополнительных услуг, требующих его идентификации и всё такое.

    Кроме того, в некоторых случаях политика конфиденциальности требуется не для соответствия законам, а по правилам тех или иных сайтов и сервисов. Например, для прохождения review приложения в Facebook у него обязательно должна быть опубликована политика конфиденциальности. Когда мне потребовалось пройти этот квест (по работе), я взял текст с сайта своей компании и немного отредактировал, даже гуглить примеры не потребовалось.
    Ответ написан
    Комментировать
  • Как сделать проверку базы данных, на наличие новых записей?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Заводим в базе поле навроде created_at, в которое вставляем NOW() для всех новых записей (или задаём значение по умолчанию CURRENT_TIMESTAMP, чтобы оно заполнялось автоматически). В ежеминутном запросе выбираем записи с created_at больше максимального created_at при прошлой проверке. Либо можно использовать монотонный идентификатор (auto_increment), помнить последний известный и выбирать новые записи больше последнего. Ещё иногда добавляют поле статуса события, в котором отмечают процесс обработки. Например, 0 - ещё не обработано, 1 - обрабатывается, 2 - обработано.

    Идея из соседнего ответа использовать брокер очереди тоже неплоха, но ради такой простой задачи без высоких требований по скорости, надёжности, высоким объёмам, отказоустойчивости и масштабируемости это для простого бота будет чересчур. Можно иметь в виду и в какой-нибудь другой раз (когда это будет более осмысленно) воспользоваться советом.
    Ответ написан
  • Как называется специальная ячейка памяти в pytelegrambotapi?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Думаю, речь не про "ячейку памяти", а про register_next_step_handler.
    Ответ написан
  • Как исправить ошибку No module?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Разумеется, если в sys.path добавить каталог flaskr/live, то это не поможет найти в нём web. Надо добавлять flaskr.

    Проще запускать скрипт из вышестоящего каталога (python live/LiveScanner.py).

    upd: Посмотрел внимательнее, flaskr/web вообще не содержит подкаталогов, а live/apiLiveData.py находится в flaskr/, а не в flaskr/web. Думаю, надо начать с наведения порядка в этом хозяйстве.
    Ответ написан
    5 комментариев
  • Как сделать так, чтобы бот игнорировал ошибку, связанную с лс, и продолжал выполнять команду?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Как и всегда, исключение можно поймать и обработать, например, проигнорировать или выполнить какие-то альтернативные действия.

    try:
        await member.send("Привет!")
    except disnake.ext.commands.errors.CommandInvokeError:
        print(f"Написать {member} не удалось")


    Но вообще спамить в ЛС - это ненормальный сценарий использования Discord API, и за это бота могут заблокировать. Правильнее писать в каналы, для чего имело смысл с самого начала заложить в бота понятие "канал для уведомлений", чтобы все пользователи бота его заранее настроили на своих серверах.
    Ответ написан
    1 комментарий
  • Почему не работает aiogram, когда создаёшь виртуальное окружения?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Потому что в виртуальном окружении по умолчанию ничего (почти) нет. Надо доустановить с помощью pip всё необходимое.
    Ответ написан
  • Telegram: как передать текст в callback?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Общий принцип - нужно запомнить, что для данного конкретного chat_id изменилось состояние, и следующее событие именно в этом chat_id надо обработать иначе, не по умолчанию.

    Во многих библиотеках для этого есть поддержка FSM (FSM - Finite State Machine - конечный автомат). В php-библиотеках я не очень разбираюсь, но можно поискать в сторону "название библиотеки FSM", либо в библиотеке уже есть своё решение этой задачи, либо кто-то уже наверняка над этим задумывался раньше, так что можно найти примеры подобного. В конце концов, написать самому под свои задачи.
    Ответ написан
  • Телебот forward_message как скрыть автора?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Что мешает вместо форварда просто отправить такое же сообщение с идентичным содержанием от имени самого бота?

    В доках метод клиентского апи, не Bot API. Нетрудно видеть, что в Bot API нет аналогичного параметра https://core.telegram.org/bots/api#forwardmessage
    Ответ написан
  • Можно ли разместить 2 почтовых сервиса с разными доменами на одном хостинге/сервере?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Конечно можно, более того, можно размещать даже не десятки, а тысячи доменов, это вполне нормально и нередко делается. Например, почтовые сервисы от гугла, яндекса, мейла итд итп хостят почту кучи доменов на одних и тех же серверах, а не выделяют отдельный сервер каждому.
    Ответ написан
    Комментировать
  • Почему падает бот aiogram?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Так он пишет в чём проблема: одновременно делаются несколько вызовов getUpdates. Обычно это означает, что с одним токеном запущено больше одного бота.

    Хотя если судить по предыдущим ошибкам, возможно проблема сетевого доступа до Telegram.
    Ответ написан
  • На 25 строчке при 2-ом повторении выдаёт NonType, почему и как поменять на int?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо так делать. Метод append изменяет список (добавляет в него элемент) и не возвращает никакого значения (или, что то же самое, возвращает None). То есть в результате такой записи мы добавляем элемент в список, а дальше этот список моментально выкидываем на помойку.

    week[g] = week[g].append(subj[gm])
    Ответ написан
    Комментировать
  • Как искать шрифты CC0 1.0?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Я ввёл CC0 fonts в поисковик и на первой же странице нашёл сайт с поиском по лицензии:

    https://fontlibrary.org/en/search?license=CC-0&order=

    Думаю, поиск можно продолжать дальше.
    Ответ написан
  • Задача по математики из 5-го класса которая завела меня в ступор?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Ошибка в первой же строке: 97300+авто+2гаража не равно 355600, потому что на самом деле авто+гараж=355600. То есть тут в левой части фактически стоимость двух автомобилей написана была.

    Под арифметическим решением тут видимо подразумевается следующее: три гаража стоят 355600 минус 97300.
    Ответ написан
  • Почему тг бот обрезает сообщение?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Ответ, который уже помечен галочкой, конечно же поможет решить данную конкретную проблему, но его яркий недостаток в том, что автор вопроса так и не поймёт, в чём же именно проблема состояла. А это очень важно понимать, так как с такой же проблемой можно столкнуться и в других ситуациях.

    Проблема заключается в том, что & является разделителем аргументов GET-запроса. На первом же & в тексте будет считаться, что значение параметра text закончилось, а дальше идёт следующий параметр.

    Чтобы этого не происходило, надо заменять & на %26. Пробел надо менять на +, + менять на %2B, и это далеко не всё, с чем можно столкнуться. В частности, символ # в некоторых применениях является ссылкой на якорь на странице, и http-клиент (например, браузер) не будет передавать в запросе ничего, начиная с этого символа, если его не заменить на %23.

    Чтобы это решить в данном случае, наиболее удобный способ - это передать параметры отдельным аргументом params метода requests.get, чтобы библиотека requests сама грамотно разрулила все необходимые замены. Но если это недоступно для решения какой-то другой задачи - искать как выполнить соответствующее преобразование надо по ключевым словам urlencode/urldecode.
    Ответ написан
    Комментировать
  • Бот должен при команде /photo сохранять присланное после команды фото в одну папку, а при /photo1 в другую?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Не надо внутри одной функции объявлять другую. Это не будет работать, вообще никак! Результатом будет дописывание в список хендлеров новых обработчиков, а так как условия в них уже описаны в других обработчиках, то эти никогда вызваны не будут.

    Также при такой записи "внутренний" обработчик будет создаваться каждый раз заново. Короче, вытащить на верхний уровень, дать им другие имена и никогда так больше не делать.

    В данном случае для решения задачи нужно использовать FSM. В telebot есть очень простая в использовании реализация FSM на основе вызовов register_next_step_handler пример.
    Ответ написан
  • Как вызвать exception еще раз после его срабатывания?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Зачем так сложно? Делаем цикл по числу попыток, как только получаем успешный результат - делаем break и завершаем цикл досрочно. Можно даже обернуть это в функцию, тогда в основном коде не будет всей этой магии с циклом, код будет выглядеть более наглядным.

    def get_data(Китай, max_attempts=MAX_ATTEMPTS_DEFAULT):
        for attempt in range(1, max_attempts+1):
            try:
                submit = requests.post(Китай).json()
            except requests.exceptions.ConnectionError:
                continue
            if submit['success']:
                return submit
        return {'success':false, 'error':'attempts exceeded'}
    Ответ написан
    Комментировать
  • Что сделать, чтобы bot ловил handler в отдельном файле?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Зачем импортировать dp из всех файлов без разбору? В реальности будет импортирован последний, остальные будут импортированы впустую. Потому что следующий from импортирует другой dp и по имени dp будет доступен уже другой объект из другого модуля.

    Объект dp надо создать один раз в одном месте. В принципе, можно потом его потенциально импортировать куда угодно.

    Если хочется некоторой модульной структуры, то можно сделать в каждом модуле функцию навроде register_all_handlers(dp) и в ней делать https://docs.aiogram.dev/en/latest/dispatcher/inde.... Соответственно, после импорта всех модулей с хендлерами можно вызвать эту функцию от всех модулей:

    Примерно так
    import menu_commands
    import admin_commands
    import message_handlers
    
    dp = создаём_свой_Dispatcher
    
    menu_commands.register_all_handlers(dp)
    admin_commands.register_all_handlers(dp)
    message_handlers.register_all_handlers(dp)
    Ответ написан
    Комментировать