Ответы пользователя по тегу Telegram
  • Как открыть другой файл python и там в словарь перезаписать данные?

    Vindicar
    @Vindicar
    RTFM!
    mlt_melt, не городите велосипед, а используйте модуль json. Будет вам нормальное сохранение структурированных данных - до тех пор, пока их можно представить в виде набора часть-целое.
    А если связи более сложные, например, есть список юзеров и нужно хранить кто с кем в друзьях - то тут уже впору задуматься о реляционной БД.
    Ответ написан
    Комментировать
  • Как грамотно сформировать архитектуру чат бота?

    Vindicar
    @Vindicar
    RTFM!
    Посмотри в сторону Cogs в discord.py. Как следует из названия, либа для дискорда а не для телеги, но может получится сделать аналог? По мне так они довольно удобны.
    Ответ написан
    Комментировать
  • Нажатие кнопок в сообщении от Телеграм бота с помощью Python и Telethon?

    Vindicar
    @Vindicar
    RTFM!
    Быстрый гуглёж вывел на такой код:
    await messages[0].click(0)
    если messages - это коллекция сообщений (а название типа TotalList на это намекает!), то и впрямь нужно убедиться, что там есть хоть одно сообщение, и выбрать его.
    А также указать номер кнопки, которую кликаем.
    Ответ написан
    2 комментария
  • Как сделать проверку где писал user?

    Vindicar
    @Vindicar
    RTFM!
    В официальном FAQ есть же.
    How can I distinguish a User and a GroupChat in message.chat?
    Telegram Bot API support new type Chat for message.chat.
    Check the type attribute in Chat object:

    if message.chat.type == "private":
    	# private chat message
    
    if message.chat.type == "group":
    	# group chat message
    
    if message.chat.type == "supergroup":
    	# supergroup chat message
    
    if message.chat.type == "channel":
    	# channel message
    Ответ написан
  • Как выполняются декораторы в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Функции(как и методы) в питоне - это объекты первого рода, их можно сохранять в переменные, передавать как параметры и так далее. Соответственно, декоратор - это тоже функция, и тогда
    @decorator("params")
    def myfunc(func_params):
        pass

    это тоже, что и
    def myfunc(func_params):
        pass
    wrapper = decorator("params")
    myfunc = wrapper(myfunc)


    Никто не мешает decorator() и wrapper() в примере сохранять адрес оборачиваемой функции в какую-то структуру данных, используемую затем ботом для диспетчеризации поступающих событий. Пример без класса:
    registered_funcs = []
    
    def decorator(param):
      #вложенная функция - фактический декоратор
      def wrapper(func):
        global registered_funcs
        #запоминаем декорируемую функцию
        registered_funcs.append( (param, func) )
        return func #не забываем её вернуть
      #возвращаем wrapper, чтобы им можно было продекорировать целевую функцию
      return wrapper
    
    #пример использования декоратора
    @decorator("foo")
    def myfunc(x):
      print("Hello from myfunc(), ", x)
    
    print(registered_funcs)
    #>>> [ ("foo", <function myfunc at 0xdeadf00d>) ]
    #и мы можем этим списком пользоваться, например:
    for arg, func in registered_funcs:
      func(arg)
    Ответ написан
    1 комментарий
  • Как реализовать разные скрипты Telegram bot'а в нескольких файлов?

    Vindicar
    @Vindicar
    RTFM!
    Проблема в том, что тебе нужно продекорировать функции через @bot.чтототам, но другие файлы ничего не знают о боте, так как он описан в главном файле. Так?
    Нужно учесть, как работает декоратор. Код вроде
    @bot.message_handler(commands=['anketaone'])
    def null_anketa_step(message):
        pass

    на самом деле работает примерно так:
    temp_wrapper = bot.message_handler(commands=['anketaone'])
    def null_anketa_step(message):
        pass
    null_anketa_step = temp_wrapper(null_anketa_step)

    Т.е. иными словами, декоратор - это просто вызов функции, в которую передаётся функция или класс!
    Тогда самый простой способ будет таким:
    def null_anketa_step(message):
        pass
    #какой-то другой обработчик
    def some_other_handler(message):
        pass
    
    def init_bot(bot):
        #а в этой функции мы регистрируем обработчики
        bot.message_handler(commands=['anketaone']) (null_anketa_step)
        #обрати внимание на две пары скобок. Вызов bot.message_handler() возвращает функцию (wrapper),
        #и мы эту функцию тут же вызываем, передавая в неё обработчик
        bot.message_handler(commands=['somethingelse']) (some_other_handler)

    Тогда в главном файле ты делаешь примерно так:
    bot = ........ #создаём бота
    from second_file import init_bot as init_second #импортируем второй файл
    #функцию импортируем под другим именем, чтобы не было коллизий между файлами
    init_second(bot) #вызываем функцию регистрации init_bot()
    
    if __name__=='__main__':
        bot.polling(none_stop=True)
    Ответ написан
    5 комментариев
  • Есть ли коги или что-то им подобное в Telegram?

    Vindicar
    @Vindicar
    RTFM!
    Можно сделать самому.
    Смотри, ключевая возможность в большинстве библиотек для ботов - это регистрация реакции бота на события. И чаще всего она выполняется декоратором, типа @bot.command в discord.py или его эквивалент в aiogram.
    Но что такое декоратор? Если он не имеет параметров, то тогда
    @some_decorator
    def some_func():
        pass

    это то же самое, что и
    def some_func():
        pass
    some_func = some_decorator(some_func)

    Для декораторов с параметрами чуть-чуть сложнее
    @some_decorator(params)
    def some_func():
        pass

    превратится в
    def some_func():
        pass
    wrapper = some_decorator(params)
    some_func = wrapper(some_func)

    Отсюда вывод. Декоратор - это функция, и его можно сохранять в переменные, вызывать и так далее.
    Тогда можно сделать такой трюк: написать декоратор-прокси, который запоминает, что за метод мы декорируем, и чем. Примерно так:
    def proxy(storage, *args, **kwargs):
        def wrapper(func):
            storage.append((func.__name__, args, kwargs))
            return func
        return wrapper

    И применять его примерно так:
    class MyCustomCog:
        methods = []
        def __init__(self, bot):
            #задача конструктора - прочитать список отмеченных методов класса, 
            #и отдекорировать методы своего экземпляра класса (не одно и то же)
            for fn, args, kwargs in self.methods:
                #а тут вызываем декоратор вручную
                #что там вместо bot.event? можно сделать несколько прокси, или добавить еще один параметр
                decorator = bot.event(*args, **kwargs) 
                decorator(getattr(self, fn)) #теперь бот знает про наши обработчики событий
        #декоратор-прокси запоминает все декорированые методы в список methods
        #это можно реализовать и по другому, не суть. Главное, что мы запоминаем,
        #с какими параметрами потом вызывать декоратор реального бота - всё, что после methods
        @proxy(methods, "параметры", for="декоратора бота")
        async def some_handler(self, params):
            pass #обработчик того или иного события

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

    Vindicar
    @Vindicar
    RTFM!
    0. Ставишь aiogram и читаешь Quick start, чтобы понять, как в целом будет устроен бот.
    1. Создаёшь и ведёшь базу пользователей бота, например, в sqlite3. Как её наполнять, это уже второй вопрос. Также может потребоваться отдельная таблица напомнинаний, но тебе виднее что за напоминания будут.
    2. В боте создаёшь через asyncio.create_task() бесконечную задачу, которая
    - проверяет время
    - если сейчас подходящее время (скажем, полдень, 1е число месяца, плюс-минус 30 секунд), вызывает корутину уведомления пользователей,
    - засыпает на минуту с помощью await asyncio.sleep() (ни в коем случае не time.sleep()).
    3. Корутина уведомления пользователей должна извлекать из твоей базы уведомления, которые нужно отправить и id пользователей, которым эти уведомления нужно отправить (см. доки по sqlite3 как извлекать данные из БД запросом SELECT). Затем для каждого пользователя она должна отправить текст (см. доки по aiogram) и обработать возможное исключение (например, если пользователь заблокировал бота).
    4. Может потребоваться пара обработчиков команд, чтобы добавлять/менять текст напоминаний.
    Ответ написан
  • Почему телеграм бот долго реагирует на команды?

    Vindicar
    @Vindicar
    RTFM!
    async with pool.acquire() as conn:
    async with conn.cursor() as cursor:

    Как по вашему, что делают эти строки?
    Такое ощущение, что он каждый раз подключается к бд, прежде чем выдать ответ.
    Ответ написан
  • Как сохранять файлы в aiogram Python?

    Vindicar
    @Vindicar
    RTFM!
    > хотел бы узнать как
    Читай доки на aiogram. Для начала Quick Start. Потом осознаёшь, как использовать фильтры для обработки разных входящих сообщений. Когда осознаешь - смотришь в сторону ContentTypeFilter и ищешь примеры его использования.
    Ответ написан
  • Как получить число и подставить в путь файла в aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Ты ошибку-то прочитал? Он прямо говорит, что указанный файл (изображение) не найден.
    Если ты уверен, что файл есть, читай дальше.
    Путь, который ты указал - относительный, поэтому отсчитывается относительно текущей рабочей директории (которая может совпадать или не совпадать с директорией где лежит скрипт, смотря как его запускаешь).
    Так что используй pathlib, чтобы сформировать абсолютный путь к изображению - т.е. начинающийся с корня диска. Если искомый файл лежит неподалёку от каталога бота, то можешь воспользоваться тем фактом, что sys.argv[0] (модуль sys) содержит путь к скрипту бота.
    Ответ написан
    5 комментариев
  • Как циклически просматривать записи из БД в телеграм боте?

    Vindicar
    @Vindicar
    RTFM!
    Храни для каждого пользователя id/номер записи, на которой он остановился.
    Есть несколько corner-case'ов, например, добавление новой записи после того как просмотр начался... но в целом не должно быть очень сложно.
    Ответ написан
    Комментировать
  • Как сделать завершение команды?

    Vindicar
    @Vindicar
    RTFM!
    > message.from_user.id != [905259209, -1001486872541]:
    Выучи основы питона сначала, а? Потом уже возьмёшься за ботописание.

    Проверка вхождения значения в коллекцию выполняется оператором in. Для проверки не-вхождения есть оператор not in.
    message.from_user.id not in [905259209, -1001486872541]:
    Ответ написан
    8 комментариев
  • Куда отправляется информация из телеграмм ботов?

    Vindicar
    @Vindicar
    RTFM!
    Заведи приватный телеграм канал, куда имеют доступ только менеджеры, пусть бот постит туда.

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

    Vindicar
    @Vindicar
    RTFM!
    Ну очевидно, бот должен запоминать, какие пользователи ввели команду, и если сообщение не от одного из них - то игнорировать это сообщение и ждать снова.

    С другой стороны, подумай - может, можно вообще уйти от этой системы со 100500 сообщений, и обойтись параметрами команды?
    Ответ написан
    Комментировать
  • Как осуществить шифр цезаря в Telegram боте?

    Vindicar
    @Vindicar
    RTFM!
    Причем тут вообще input()? Эта функция занимается только вводом из консоли.
    То же самое с print(), это исключительно консольный вывод.

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

    Иначе нужно будет разобрать входящее сообщение (оторвать от начала команду), и шифровать его.
    Ответ написан
  • Как заставить бота отправлять сообщение раз в 30 секунд, Python Aiogram?

    Vindicar
    @Vindicar
    RTFM!
    Ну во-первых, зачем тебе 2 main-блока?
    При этом обрати внимание, что первый main-блок не закончит работу, пока не закончит работу твоя корутина helloworld(), так как ты используешь метод run_until_complete(). А твоя корутина никогда не закончит работу.
    Используй loop.create_task(), чтобы запланировать выполнение корутины "в свободное время" работы системы и продолжить работу.
    if __name__ == '__main__':
      loop.create_task(helloworld())
      executor.start_polling(dp, skip_updates=True)


    Во-вторых, длительные синхронные операции в корутине блокируют её работу, и работу остальных корутин. Это основы асинхронного прогарммирования, блин!
    Поэтому твой time.sleep() вешает всего бота. Используй await asyncio.sleep(), она отдаст управление другим корутинам бота на время сна текущей корутины.
    Ответ написан
    Комментировать
  • Рандом телеграм бот генерирует результат, а потом ленится и выдает повтор, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    random_team0 = random.choice(man) + ' из ' + random.choice(place)
    random_team1 = random.choice(prilag) + ' ' + random.choice(such)
    team_name = [random.choice(team), random_team0, random_team1]

    Этот код выполняется один раз при запуске бота, а не каждый раз при выполнении team(). Внеси его внутрь подпрограммы team().
    Ответ написан
    Комментировать
  • Как сделать проверку ссылки в телеграм боте?

    Vindicar
    @Vindicar
    RTFM!
    Если вы не знаете, как искать наличие подстроки в строке (либо через оператор in, либо через метод index()), или как пользоваться регулярными выражениями, то вам рано браться за ботов. Начните с упражнений попроще, потом вернётесь к теме.

    Вот кроме шуток. Это основы стандартной библиотеки языка. Прежде чем бросаться что-то разрабатывать - их надо знать, хотя бы на уровне возможностей, т.е. "я не помню, как называется метод для перевода строки в нижний регистр, но я точно знаю, что он есть, пойду поищу".
    Ответ написан
    Комментировать
  • Какая-то проблема с кодом, поможете?

    Vindicar
    @Vindicar
    RTFM!
    Включить голову. Твой код, по сути, делает ровно то, что ты от него просишь:
    1. Если сообщение в личку, то в зависимости от слова, скинуть ту или иную фотку. Если не одно слово не подошло, то ничего не делать.
    2. Если сообщение не в личку, ответить, что на групповые сообщения не отвечает.

    Т.е. он всегда будет реагировать на не-личные сообщения по else. Не нравится? Убери этот else вместе со всем содержимым.
    Ну и да, основные алгоритмические конструкции.
    Ответ написан
    Комментировать