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

    Vindicar
    @Vindicar
    RTFM!
    smokedevil666, сделай глобальный словарь вида
    commands = { "Нажми": "python3 /foor/bar/baz" }
    И ищи в нём полученное сообщение. Если такого ключа нет, ругаешься на пользователя.
    Ответ написан
    8 комментариев
  • Как перенаправлять уведомления из группы Discord в Telegram?

    Vindicar
    @Vindicar
    RTFM!
    Используй комбинацию discord.py и aiogram. Придётся вчитаться в документацию, чтобы понять как запустить их вместе. Как поймешь - дальше просто, прописываешь обработчик сообщений от дискорда, проверяешь сообщение на предмет уведомление ли это, если да - переотправляешь в aiogram.

    А вообще, будет намного проще выделить в сервере отдельный канал для уведомлений, куда нельзя писать юзерам. Кому интересно - подпишутся на этот канал и поставят оповещения, кому не интересно - замутят.
    Ответ написан
    Комментировать
  • Как реализовать поиск в sqlite на python?

    Vindicar
    @Vindicar
    RTFM!
    Это называется "нечеткий поиск", и это непростая тема. Как говорится в одном анекдоте, "длина, ширина, высота и глубина - это совсем не то же, что длинка, ширинка, высотка и глубинка".
    Ответ написан
    6 комментариев
  • Value for header {} must be of type str or bytes, not Ошибка полностью ниже.?

    Vindicar
    @Vindicar
    RTFM!
    session_id = requests.post(
            "https://yug-krdr-itv04.svc.iptv.rt.ru/api/v2/user/sessions",
            headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "session_id": sess_id},
            json={"login": email, "login_type": "email", "password": "1234567"},
        ).json() # значение session_id может быть не только строкой, но и целым числом, словарём, списком или None
        return {"san": san, "session_id": session_id, "uid": ud} #в словарь оно пишется как есть
    
    
    def requestBuilderWink(url, data=None, params=None, json=None, method=None):
        register = regAccount()
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
            "session_id": register["session_id"], # а потом используется как заголовок - тоже как есть
            "x-rt-uid": register["uid"],
            "x-rt-san": register["san"],
        }
    Ответ написан
    Комментировать
  • Как реализовать мульти-поточность в боте Telegram (Aiogram)?

    Vindicar
    @Vindicar
    RTFM!
    Мешать многопоточность с асинхронностью - плохая идея.
    А вообще зависит от реализации server.status(). Если оно делает синхронный сетевой запрос, то конечно бот встанет на время его выполнения.
    Если нет асинхронной реализации, я бы запустил новый таск, который в цикле раз в минуту-две опрашивает сервер и запоминает текущий онлайн. А по команде отдавал бы только последнее запомненное значение.
    В принципе можно использовать loop.run_in_executor() для выполнения потока как асинхронной задачи. Это более-менее безопасно.
    Ответ написан
    Комментировать
  • Как задать время мута, бана в команде?

    Vindicar
    @Vindicar
    RTFM!
    get_args() → Optional[str]
    Судя по документации, get_args() возвращает строку, идущую после команды, или None. Разбор этой строки - уже твоя забота. Например, так:
    1. присвоить результат .get_args() переменной и убедиться, что это не None.
    2. ободрать пробелы с помощью .strip()
    3. превратить в int()/ float() и поймать исключение, если в строке не число
    4. использовать полученное значение.
    Ответ написан
    2 комментария
  • Как сделать телеграм бота многоязычным?

    Vindicar
    @Vindicar
    RTFM!
    1. Храни таблицу языков вида "ID пользователя - ID языка". Если записи для пользователя в таблице нет, то предлагаешь выбрать, или задаёшь какое-то значение по умолчанию.
    2. Храни все постоянные строки, которые отправляет бот, в некотором хранилище. Хранилище должно иметь вид "ID строки - ID языка - содержимое строки". Соответственно при отправке сообщения узнаёшь ID языка пользователя, с которым идёт обмен, и выбираешь нужную строку по ID строки.
    Ответ написан
    2 комментария
  • Как Удалить надпись, Бот заблокировал в чате?

    Vindicar
    @Vindicar
    RTFM!
    Смотришь метод Bot.send_message(), которым ты пользуешься.
    Там и впрямь есть параметр disable_notification, который можно передать.
    Так что просто передаёшь этот параметр по имени, как disable_notification=True.
    Ответ написан
    Комментировать
  • Как открыть другой файл 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 комментариев