
ataraxia Handbook
Установка через uv, веб-вход, встроенные команды и Python через .e. Инлайн-бот работает по MTProto, а модули можно грузить с любого URL.
Что такое юзербот
Обычного бота создают через @BotFather, и он пишет от своего имени. Юзербот устроен иначе: программа входит в Telegram под вашим аккаунтом и реагирует на ваши же сообщения. Например, .ping покажет задержку. Команды можно отправлять в Избранном, личке или группе, но доступ зависит от прав в конкретном чате.
ataraxia это модульный юзербот для разработчиков, которым нужен полный контроль над своим Telegram-клиентом. Внутри стоит библиотека ataraxia-tl, форк Telethon с актуальным слоем протокола. Версия определяется кодовым именем Rise, ветка и хеш коммита берутся из git при запуске. Лицензия AGPLv3.
Что она умеет из коробки
- Команды с точкой в любом чате: пинг, инфо, перевод, Python прямо в сообщении
- Модули: встроенные плюс горячая загрузка внешних с любого URL через
.dlm - Инлайн-бот на MTProto: формы и списки со страницами; Бот-АПИ-подобный фасад
self.inline.bot - Гостевые команды:
@имя_бота командаиз чатов, где бота нет - Rich messages: заголовки, цитаты и таблицы от вашего аккаунта, с запасным обычным текстом
- Права по битовой маске: OWNER, админы группы, PM, EVERYONE, точечные правила
- Шифрованные бинарные сессии, бесполезные без
ataraxia.key - Веб-установка: вход в браузере, QR-код, SSH-туннель для удалённого сервера
- i18n на YAML-пакетах с цепочкой фолбэков; русский и английский в комплекте
- Ноль pip: всеми зависимостями управляет uv,
pyproject.tomlединственный источник правды
Где живут данные
При обычной установке в папке репозитория после входа появляются: config.json с API-ключами, ataraxia.key с мастер-ключом сессий, ataraxia-<id>.atsession с шифрованной сессией, JSON-база аккаунта и loaded_modules/ со сторонними модулями. В Docker данные лежат в /data; путь меняется флагом --data-root. Копируй их только в защищенное место.
Честно о минусах
- Пока выключен сервер или компьютер, бот не отвечает. Ему нужно место, где он крутится постоянно
- Внешние модули работают без песочницы: тот же процесс, доступ к сессии и ключу. Ставьте только проверенный код
- Telegram формально не поощряет автоматизацию аккаунтов. Пользуйтесь головой, не спамьте
- ataraxia-tl следит за git HEAD и не закреплен версией: обновление может сменить библиотеку вместе с ядром
Главное правилоСессия зашифрована AES-256-GCM, но
ataraxia.keyлежит рядом. Кто получит оба файла, тот получит аккаунт. Не отправляй их посторонним и не добавляй в публичный репозиторий, никогда не бэкапь ключ вместе с сессиями.
Как читать этот handbook
Начни с установки и входа, затем загляни в основы и справочник команд. Отдельные страницы посвящены файлам, повседневным задачам, правам и API сообщения r. Страница про свой модуль объясняет декораторы, ватчеры и гостевые команды.
Все команды в тексте показаны с точкой, потому что она префикс по умолчанию. Смените префикс, и везде подставляйте свой.
Установка
Клонировать, запустить uv run -m ataraxia. uv сам разрешит зависимости из pyproject.toml и запустит бота.
Что понадобится
- Python 3.10 или новее
- uv, единственный менеджер пакетов проекта: ни pip, ни ручного venv
- git: апдейтер работает через
git pull, поэтому клонируй репозиторий, а не скачивай архив
Где вообще держать бота
ataraxia это процесс на вашей машине. Закрыли терминал, выключили ПК, перезагрузили VPS, бот замолчал. Поэтому первый вопрос не «как ставить», а «где он будет жить».
| Место | Кому подходит | Нюанс |
|---|---|---|
| VPS с Linux | Всем, кто хочет бот 24/7 | Стоит от пары долларов, понадобится ssh |
| Домашний ПК | Попробовать и поиграться | Работает пока не выключен |
| Raspberry Pi | Постоянный тихий хост | Понадобится отдельное устройство |
| Docker | У кого всё в контейнерах | Данные в volume /data, порт 8080 |
Linux и macOS
Скопируйте весь блок одной командой:
git clone https://git.break.wtf/xenside/ataraxia
cd ataraxia
uv run -m ataraxia
Первая строка скачивает репозиторий, вторая заходит в него, третья разрешает зависимости и запускает программу. При первом запуске uv скачает ataraxia-tl и остальные пакеты, это займет пару минут.
Docker
docker build -t ataraxia .
docker run -d -p 8080:8080 -v ataraxia-data:/data --name ataraxia ataraxia
Образ собирается на python 3.14-slim: внутри уже есть uv, node для .enode, git, ffmpeg, gcc и g++. Данные живут в volume /data, поэтому переживают пересоздание контейнера. Веб-интерфейс слушает порт 8080.
Флаги запуска
| Флаг | Что делает |
|---|---|
--port | Порт веб-интерфейса. По умолчанию свободный случайный, в Docker всегда 8080 |
--no-web | Отключить веб-интерфейс, вход через терминал |
--data-root | Путь для файлов сессий и данных |
--phone, -p | Номер телефона для входа, можно указывать несколько раз |
--no-auth | Не запрашивать аутентификацию и API-ключи, выйти при необходимости |
--proxy-host, --proxy-port, --proxy-secret | MTProto-прокси |
--proxy-pass | Открыть SSH-туннель при старте |
--sandbox | Умирать вместо перезапуска |
--no-tty | Без цветного ANSI-вывода |
Как запускать после перезагрузки
Одна строка из папки с ботом:
uv run -m ataraxia
Чтобы бот жил после закрытия терминала, запустите его внутри screen или tmux:
sudo apt install screen -y
screen -S ataraxia
uv run -m ataraxia
Затем Ctrl+A и D, окно отсоединится, процесс останется. Вернуться: screen -r ataraxia. Перезапуск изнутри Telegram (команды .restart и .update) работает через os.execvp("uv", ...), внешний процесс не нужен.
Готово, еслиВ терминале нарисован баннер ataraxia, а рядом ссылка на веб-интерфейс. Дальше смело идите в раздел про вход.
Вход и веб-интерфейс
При первом запуске ataraxia открывает веб-интерфейс: вход по QR или телефону, ввод API-ключей и двухфакторки, всё в браузере.
API ID и API hash
Два ключа, без которых ataraxia не войдет в Telegram. Берутся бесплатно на официальном сайте.
- Зайдите на my.telegram.org, войдите по номеру. Код придет в чат Telegram, не по СМС
- Откройте пункт API development tools и создайте приложение
- Со страницы скопируйте App api_id (число) и App api_hash (строка из 32 символов)
В веб-интерфейсе есть и другой путь: готовые пресеты Telegram Desktop и Telegram for Android подставляют свои api_id и api_hash, а профиль устройства (платформа, версия приложения) генерируется случайно из правдоподобного набора. Свои ключи при желании можно задать переменными окружения api_id и api_hash или файлом api_token.py; приоромитет у config.json, куда они сохраняются после ввода.
СекретAPI hash не показывайте в скриншотах и не отдавайте никому под предлогом «а мне для настройки».
Вход: QR или телефон
- QR. В веб-интерфейсе нарисуется код, перерисовывающийся по мере устаревания. На телефоне: Настройки, Устройства, Привязать устройство, навести камеру. Удобно, когда телефон рядом
- Телефон. Номер в международном формате, например
+79001234567. Затем код из чата Telegram. Способ удобнее по ssh, когда камерой никуда не наведешь
Если включена двухэтапная проверка, попросит облачный пароль: и в вебе, и в терминале. После входа сессия сохраняется зашифрованной в ataraxia-<ваш_id>.atsession. Все последующие запуски подхватывают её сами.
Веб-интерфейс
Собран на aiohttp и jinja2, шаблоны в web-resources/. Через него проходят: ввод и смена API-ключей, отправка кода, QR-вход, двухфакторка, управление аккаунтами. Флагом --no-web он отключается, тогда вход идет в терминале.
Если бот стоит на VPS без браузера, команда .weburl открывает SSH-туннель через serveo.net или localhost.run и присылает публичную https-ссылку на интерфейс. В группе команда сначала спросит подтверждение: ссылка раскрывает интерфейс перед чатом. Туннель можно поднять и при старте флагом --proxy-pass.
Несколько аккаунтов
ataraxia мультиклиентная: несколько сессий работают в одном процессе, у каждой своя база, свои модули и свои логи. Добавить аккаунт можно из веб-интерфейса или командой .addacc в Telegram: бот пришлет инлайн-форму с вводом номера и кода, а после успешного входа перезапустится. Вход для чужого аккаунта требует подтверждения или суффикса force_insecure.
Что произойдет после входа
- Создается приватный канал с форумом: темы Assets для медиа и Backups для бэкапов. Это служебное хранилище, не удаляйте его
- Инлайн-бот пришлет приветствие с выбором языка и предложением настроить период резервных копий
- Инлайн-бот закрепляется в папке чатов с именем ataraxia, если такая папка есть
ПроверкаОткройте Избранное и отправьте
.ping. Сообщение превратилось в карточку с задержкой и аптаймом, значит всё работает.
Файлы, бэкап и перенос
После входа ataraxia хранит авторизацию и настройки на диске. Вот что стоит сохранить перед переездом, а что можно поставить заново.
Что лежит в папке ataraxia
| Путь | Содержание | Переносить? |
|---|---|---|
config.json | API ID, API hash и порт веб-интерфейса | Да, держи закрытым |
ataraxia.key | Мастер-ключ сессий, 32 байта hex, права 0600 | Да, отдельно от сессий |
ataraxia-<id>.atsession | Зашифрованная бинарная сессия, AES-256-GCM | Да, вместе с ключом |
db-*.json | JSON-база настроек и данных модулей аккаунта | Да |
loaded_modules/ | Сторонние модули и кеш .dlm | Да, если модули ставились файлами |
ataraxia-...-bot.atsession | Сессия инлайн-бота, тот же ключ | Да |
.venv/, кеш uv | Установленные зависимости Python | Нет, uv пересоберет на новом сервере |
База пишется атомарно: сначала во временный файл, потом fsync и os.replace. Сериализация orjson, никакого стандартного json и никакого Redis.
Перенос на другой сервер
- Останови ataraxia на старой машине. Одна и та же сессия не должна работать одновременно в двух местах
- Скопируй папку проекта вместе с
config.json,ataraxia.key, файлами.atsession, базами иloaded_modules/по защищённому соединению - На новом сервере поставь uv и запусти
uv run -m ataraxia: зависимости подтянутся сами - Отправь
.pingв Избранном и проверь.ataraxia: ветка и коммит должны совпасть со старым сервером
Через .backupall можно сохранить базу, модули и pip-зависимости в служебный форум. Этот архив не заменяет файл сессии и ключ. Если переносишь только бэкап, Telegram попросит войти заново.
Где искать резервные копии
ataraxia создаёт приватный форум-канал с темой Backups. Команды .backupdb, .backupmods и .backupall отправляют файлы туда и отвечают ссылкой. Период автоматического бэкапа задает .set_backup_period в часах, 0 отключает.
Не пересылай сессиюАрхив сессии и база аккаунта содержат личные данные. Для помощи в чате поддержки обычно нужен лог ошибки, а не
.atsessionи неconfig.json.
Основы
Как подаются команды, куда их писать и что делать, если точка мешает переписке.
Анатомия команды
Команда это обычное сообщение, начинающееся с префикса. По умолчанию это точка. Дальше идет имя команды, потом аргументы через пробел.
.setlang ru
^ ^^
| |
| аргументы
имя команды
префикс
Имена команд регистрируются в нижнем регистре; если сомневаешься, пиши так, как показано в .help. В справке обязательные аргументы пишут в угловых скобках <так>, необязательные в квадратных [так].
Куда писать
Для первых команд удобно Избранное: там ты никому не мешаешь. В группах команды работают, если у аккаунта есть нужные права; по умолчанию в группах команда требует упоминания твоего юзернейма, но это отключается настройкой NoNick. Исходное сообщение команды могут успеть увидеть другие участники.
Экранирование и раскладка
Двойной префикс в начале экранирует команду: сообщение ..привет отправится как обычный текст «.привет». Диспетчер еще и переводит раскладку: команду, набранную в английской раскладке как .ру, распознает как .ru-вариант из русской, поэтому опечатки раскладкой не ломают команды.
Реплай как аргумент
Некоторые команды берут объект для работы из реплая. Ответьте на чей-то текст и напишите команду без аргументов: работать будет именно он. Команда .e дает доступ к сообщению из реплая через переменную r.
Сменить префикс
.setprefix !
После этого команды можно писать с ! вместо точки. Префикс из одного символа ставится сразу; длинный, эмодзи или премиум-эмодзи требует настройки allow_nonstandart_prefixes через .config. Префикс s запрещен. Есть и персональные префиксы: .setprefix ! 123456789 выдаст свой префикс пользователю, у которого уже есть права (совладельцу, участнику группы безопасности или точечного правила).
Алиасы
Короткая кличка для команды, которую вы часто пишете:
.addalias п ping
.п
.aliases
.delalias п
Первая строка создает алиас, вторая уже работает как .ping. Третья показывает все ваши алиасы, четвертая удаляет один.
Выключать ненужное
Команда или модуль надоедают, а удалять жалко: .togglecmd ping гасит одну команду, .togglemod Settings целый модуль. Те же команды возвращают всё обратно. Имя модуля берется из .help.
Тумблеры и grep
Команда .settings открывает меню общих переключателей: NoNick (команды без упоминания), Grep и другие. Grep разрешает фильтровать вывод команд конвейером | grep слово, когда включен.
Две команды, с которыми не шутят
.eисполняет Python,.terminalвыполняет команды на сервере. Даже одна своя строка может изменить данные или удалить файл, а чужой код тем более не стоит запускать, пока не разобрался, что он делает.
Повседневные задачи
Не надо заучивать весь список команд. Вот несколько сценариев, с которыми проще освоиться после первого .ping.
Найти нужную команду
Вызови .help, выбери модуль и посмотри его команды. Флаги уточняют список: .help -c только встроенные модули, .help -l только внешние, -f показывает и скрытые. Если знаешь команду, но не помнишь синтаксис, справка модуля подскажет аргументы.
Поставить модуль
Команда .dlm покажет каталоги доступных модулей, .dlm имя найдет и установит модуль из репозитория, .dlm ссылка поставит с любого URL: github/gitlab blob-ссылки превращаются в raw автоматически. Если прислали Python-файл, ответь на него командой .lm. Появился ли модуль, проверь через .help.
Посмотреть ошибку
Напиши .logs и выбери уровень: Error, Debug или числовой. Команда .logs debug -f отправит лог без отдельного предупреждения. Перед тем как передать файл кому-то ещё, просмотри содержимое: ataraxia маскирует известные секреты, но сторонний модуль может написать в лог что-то своё.
Обновить и сохранить данные
Сначала .backupall, затем .update. Апдейтер делает git pull в текущей ветке, затем uv sync -U для зависимостей, и показывает карточку с текущим и будущим коммитом. Флаг -f пропускает подтверждение. Если синхронизация зависимостей упала, код на диске уже новый, а работающий старый: бот предложит повторить, не перезапускаясь. Если нужна только перезагрузка без обновления, есть .restart.
Остановить мешающий модуль
.togglemod ИмяМодуля отключит его, повторная команда включит обратно. Если мешает только слежение за сообщениями в одном чате, попробуй .watcherbl ИмяМодуля прямо в этом чате. Для одной команды есть .togglecmd имя.
Дать доступ другому человеку
Для одной команды на ограниченное время используй точечное правило, например .tsec user @username ping 1h. Для более широких прав есть .security и группы безопасности. .owneradd выдаёт совладение, поэтому для простого доступа к пингу оно избыточно.
Зайти в веб-интерфейс с телефона
Команда .weburl поднимает SSH-туннель и присылает ссылку. Если бот стоит на VPS, а браузер под рукой только на телефоне, это самый короткий путь до форм входа и управления аккаунтами.
Команды
Это встроенные команды ataraxia. Команды загруженных модулей сюда не входят, смотри их через .help. Суффиксы в скобках это алиасы, то есть короткие имена той же команды.
Ядро и настройки
| Команда | Что делает |
|---|---|
.ataraxia | Покажет версию, слой ataraxia-tl, ветку и коммит со ссылкой |
.info | Карточка юзербота: владелец, аптайм, CPU, RAM, ОС. Текст настраивается плейсхолдерами |
.ping | Покажет задержку и аптайм |
.setprefix <знак> [id] | Сменит префикс. С id или юзернеймом выдаст персональный префикс |
.aliases | Покажет пользовательские алиасы |
.addalias <короткое> <команда> | Добавит алиас. Например, .addalias п ping даст команду .п |
.delalias <имя> | Удалит алиас |
.settings | Откроет меню общих переключателей |
.togglecmd <команда> | Выключит или включит отдельную команду |
.togglemod <модуль> | Выключит или включит весь модуль |
.clearmodule <модуль> | Сотрет данные конкретного модуля из базы |
.cleardb | Сбросит всю базу настроек. Перед сбросом бот спросит подтверждение |
.setlang <язык> | Сменит язык интерфейса. В комплекте en и ru |
.dllangpack <ссылка> | Добавит внешний YAML-языковой пакет |
Справка
| Команда | Что делает |
|---|---|
.help [модуль] | Покажет модули и команды. Флаги: -c встроенные, -l внешние, -f показать скрытые |
.helphide <модуль> | Скроет или вернет модуль в общем списке справки |
.support | Пришлет ссылки на чаты поддержки |
Загрузчик модулей
| Команда | Что делает |
|---|---|
.dlm (.dlmod) | Без аргументов покажет каталоги репозиториев; с именем или URL найдет и установит модуль. Через пробел можно перечислить несколько имен |
.lm (.loadmod) | Загрузит Python-файл из реплая или из вложения к самой команде |
.ulm <класс> (.unloadmod) | Выгрузит модуль. Имя класса смотри в .help; можно перечислить несколько через запятую или с новой строки |
.clearmodules | Удалит все загруженные сторонние модули после подтверждения |
.addrepo <ссылка> | Добавит репозиторий модулей, если по адресу доступен непустой full.txt |
.delrepo <ссылка> | Удалит репозиторий из списка |
.ml <модуль> | Отправит исходный файл модуля |
Скачанный код кешируется в loaded_modules/.dlm_cache/<id>/ снимком по хешу URL: при следующей установке с того же адреса берется он, а не сеть. Репозитории поддерживают basic-auth через настройку basic_auth загрузчика. Пакеты из # packages: ставятся через системный менеджер пакетов, если он найден на хосте.
Ватчеры и NoNick
| Команда | Что делает |
|---|---|
.watchers | Покажет активные ватчеры и отключенные |
.watcherbl <модуль> | Выключит ватчер модуля в текущем чате; повторный вызов включит обратно |
.watcher <модуль> | Включит или выключит ватчер целиком. Флаги -c, -p, -o, -i ограничивают его чатами, личкой, исходящими или входящими |
.nonickuser | В ответ на сообщение переключит NoNick для его автора |
.nonickchat | Переключит NoNick в текущем групповом чате |
.nonickcmd <команда> | Переключит NoNick для команды |
.nonickusers, .nonickchats, .nonickcmds | Покажут соответствующие списки |
Обновление
| Команда | Что делает |
|---|---|
.update | Обновит ataraxia: git pull, затем uv sync. Покажет карточку со старым и новым коммитом |
.update -f | Обновление без подтверждения |
.restart | Перезапустит ataraxia, настройки сохранятся |
.source | Пришлет ссылку на исходный код |
Перезапуск изнутри работает через os.execvp("uv", ...): процесс заменяет сам себя, внешние обертки не нужны. В Docker и на Windows завершение и перезапуск идут через atexit.
Исполнение кода
| Команда | Язык | Что требуется |
|---|---|---|
.e (.eval) | Python | Есть в комплекте, отдельный компилятор не нужен |
.ecpp | C++ | g++ |
.ec | C | тот же g++ |
.enode | JavaScript | node |
На команды с компиляторами можно ответить реплаем с кодом. Таймаут исполнения 10 секунд. Подробнее про Python и реплай в разделе про .e.
Терминал
| Команда | Что делает |
|---|---|
.terminal <команда> (.exec) | Выполнит команду shell на машине, где работает ataraxia. Вывод стримится в сообщение по мере поступления |
.terminate | Отправит группе процессов SIGTERM. Используй реплай на сообщение с выводом процесса |
.terminate -f | Принудительно убьет процесс (SIGKILL) |
Если команда просит пароль sudo, бот пришлет в Избранное сообщение-форму: введенный в него пароль уйдет в stdin процесса. Неверный пароль и блокировка после нескольких попыток распознаются и показываются отдельно. Рабочая папка процесса это базовая директория ataraxia.
Логи и диагностика
| Команда | Что делает |
|---|---|
.logs [уровень] | Покажет меню уровней логов и отправит выбранный лог файлом. Уровень можно задать именем или числом |
.logs debug -f | Выгрузит debug-лог без предупреждения о приватном содержимом |
.clearlogs | Очистит буферы обработчиков логов |
.suspend <секунды> | Поставит процесс на паузу на указанное время |
.api_fw_protection | Включит или выключит ограничитель частоты API-запросов |
.suspend_api_protect <секунды> | Временно приостановит ограничитель |
Ограничитель следит за частотой вызовов: при превышении порога в окне выборки ждет сам, вместо того чтобы ловить FloodWait от Telegram. Отдельные методы вроде joinChannel и importChatInvite можно запретить совсем, настройка forbidden_methods; такие запросы молча выкидываются из вызова.
Резервные копии
| Команда | Что делает |
|---|---|
.backupdb | Сохранит базу настроек |
.restoredb | Восстановит базу из файла в реплае |
.backupmods | Сохранит установленные модули |
.restoremods | Восстановит модули из файла в реплае |
.backupall | Сохранит базу, модули и pip-зависимости одним архивом |
.restoreall | Восстановит полный комплект |
.set_backup_period <часы> | Задаст интервал автоматического бэкапа. 0 отключает, максимум 199 часов |
Права и безопасность
| Команда | Что делает |
|---|---|
.security [команда] | Откроет глобальную настройку прав или права выбранной команды |
.inlinesec [команда] | Настроит права для инлайн-команды |
.querysec | Разрешит или запретит чужим пользоваться инлайн-запросами |
.owneradd <пользователь> | Добавит совладельца |
.ownerrm <пользователь> | Уберет совладельца |
.ownerlist | Покажет совладельцев |
.newsgroup <имя> | Создаст группу безопасности |
.sgroups | Покажет группы |
.sgroup <имя> | Покажет или настроит выбранную группу |
.sgroupadd <группа> <пользователь> | Добавит пользователя в группу |
.sgroupdel <группа> <пользователь> | Уберет пользователя из группы |
.delsgroup <имя> | Удалит группу |
.tsec | Покажет точечные правила доступа |
.tsecrm | Удалит точечное правило |
.tsecclr | Очистит правила выбранного типа |
Точечное правило может выдать доступ к одной команде на время. Например, .tsec user @username ping 1h предложит подтвердить доступ на час. Правила бывают для команды, модуля или инлайн-команды, а целью может быть пользователь, чат или группа безопасности.
Инлайн-бот, веб и аккаунты
| Команда | Что делает |
|---|---|
.ch_ataraxia_bot <имя> | Сменит имя персонального инлайн-бота. Без аргумента сгенерирует случайное |
.ch_bot_token <токен> | Подключит токен готового бота вместо автоматически созданного |
.weburl | Откроет SSH-туннель и пришлет ссылку на веб-интерфейс |
.addacc <пользователь> | Начнет вход в ещё один Telegram-аккаунт через инлайн-форму; можно указать пользователя реплаем |
.config (.cfg) | Откроет меню настроек модулей и библиотек |
.fconfig (.fcfg) | Задаст значения напрямую: .fconfig Модуль поле значение, изменения соединяются через &&. Без значения возьмет текст реплая |
Полный список конкретного модуля всегда доступен командой .help ИмяМодуля. Эта справка относится только к ядру, модуль из каталога может добавлять сколько угодно своих команд.
Права и безопасность
Каждая команда имеет битовую маску: кто её может вызывать. Инлайн-кнопки наследуют права команды, которая их создала.
Битовая маска
Владелец проходит всегда. Дальше биты складываются: группа безопасности добавляет свои, права в конкретном чате дают GROUP_*, личная переписка с ботом дает PM, а EVERYONE открывает команду всем. По умолчанию у команды только OWNER. В .security тумблеры выключают биты: выключенный глобально бит выключен для всех команд.
| Бит | Кто получает |
|---|---|
OWNER | Владелец и совладельцы из группы owner |
GROUP_OWNER | Создатель группы |
GROUP_ADMIN_* | Админы группы по конкретному праву: добавлять, менять инфо, банить, удалять, закреплять, приглашать |
GROUP_ADMIN | Любой админ группы |
GROUP_MEMBER | Любой участник группы |
PM | Любой в личке с аккаунтом |
EVERYONE | Все, включая инлайн-запросы |
В модулях то же самое делается декораторами: @loader.owner, @loader.group_admin, @loader.pm, @loader.unrestricted и отдельные для каждого админского права.
Точечные правила и группы
.tsec user @username ping 1h предложит выдать пользователю команду ping на час. Можно выдавать доступ к целому модулю или инлайн-команде, а целью делать пользователя, чат либо группу безопасности. Посмотреть действующие правила поможет .tsec без аргументов. Группы безопасности это именованные списки пользователей с наборами прав: .newsgroup, .sgroupadd, .sgroupdel.
Инлайн-бот и кнопки
Инлайн-бот обслуживает формы и кнопки, и он же второй MTProto-клиент: сессия ataraxia-<id>-bot.atsession лежит рядом с вашей, под тем же ключом. Бот создается через @BotFather при первом старте, если не задан свой токен. Через него работают меню .config, подтверждения и списки.
Кнопки форм наследуют безопасность вызвавшей команды. Модуль может изменить это параметрами force_me (только владелец), always_allow (список добавленных пользователей) или disable_security (без проверок). Формы живут по умолчанию сутки, потом кнопки с колбэками перестают работать; url-кнопки продолжают. .querysec переключает, могут ли посторонние пользоваться инлайн-запросами.
Ограничения для внешних модулей
Песочницы нет, но несколько защит есть. Модуль с allow_paid_stars = False не сможет отправлять платные запросы со звездами: попытка кидает PermissionError. Импорт aiogram отклоняется при загрузке: инлайн-бот уже есть как self.inline, и aiogram никогда не установится из # requires:. Импорты telethon и herokutl внутри модулей перенаправляются на ataraxia-tl, поэтому старый код часто работает без правок, но проверять всё равно стоит.
Защита от FloodWait
Диспетчер считает команды на пользователя и на чат в единицу времени; при превышении лимита команда не выполняется. Владельца лимит не касается. Ограничитель API дополнительно троттлит сами MTProto-запросы: настройка local_floodwait определяет, сколько секунд ждать локально при угрозе FloodWait, до 3600.
Совладение
.owneraddдаёт широкие права. Для доступа друга к паре команд начни с.tsecили настрой права этих команд отдельно.
.e: Python прямо в чате
.e это Python-консоль в Telegram. Написали выражение, ataraxia выполнила его и вернула результат сообщением. Код исполняется настоящим интерпретатором Python.
Как работает .e
ataraxia передает ваш код библиотеке meval, которая вычисляет Python-выражение внутри уже работающего процесса юзербота. Поэтому код видит Telegram-клиент, сообщение-команду, реплай, базу и функции ataraxia. Не надо импортировать их вручную.
Пишите команду, после неё обычный Python. Значение выражения выводится автоматически. print() тоже перехватывается и показывается отдельно. Можно использовать await прямо в строке, например для запроса к Telegram.
.e 2 + 2
.e "hello".upper()
.e await client.get_me()
.e print("строка вывода")
.e await message.edit("готово")
Первая команда вернет 4. Вторая строку HELLO. Третья запросит профиль текущего аккаунта. Четвертая покажет напечатанный текст. Последняя отредактирует ваше сообщение-команду.
Важно: это не песочницаКод в
.eисполняется внутри ataraxia с правами процесса. Он может отправлять сообщения, читать базу и обращаться к файлам сервера. Не запускайте код от незнакомых людей, даже если он выглядит как пара безобидных строк.
Что уже доступно в коде
| Имя | Что внутри | Пример |
|---|---|---|
message, m, event | Ваше сообщение с командой | message.text |
r, reply | Сообщение, на которое вы ответили | r.text |
client, c | Подключенный Telegram-клиент | await c.get_me() |
chat | Адресат сообщения команды (message.to_id), не объект чата с названием и участниками | chat |
utils | Утилиты ataraxia | utils.get_chat_id(message) |
db | База данных | db.get("MyMod", "key") |
lookup | Найти загруженный модуль | lookup("LoaderMod") |
self | Сам модуль Executor | self.get("key") |
ataraxiatl, telethon, herokutl | Клиентская библиотека, три имени на один пакет | ataraxiatl |
SendMessageRequest и другие TL-имена | Функции и типы Telegram доступны прямо по имени, подгружаются лениво по упоминанию в коде | SendMessageRequest |
В окружении также есть loader и main. Переменная db во время исполнения обернута защитой: запись db.set("ataraxia.security", "owner", ...) запрещена, сменить владельца через eval не выйдет.
Что такое r
r и reply указывают на одно и то же сообщение, если ты отправил .e реплаем. ataraxia получает его через await message.get_reply_message(). Если реплая нет, оба имени равны None; обращение к r.text тогда даст ошибку. Для свойств не нужен await: пиши r.sender_id, но метод вызывай как await r.get_sender().
Ниже свойства и публичные методы объекта Message из ataraxia-tl, форка Telethon. Примеры с медиа и файлами рассчитаны на сообщение, где вложение действительно есть.
Текст, автор и чат
| Свойство r | Что возвращает |
|---|---|
text | Текст, восстановленный с форматированием в режиме клиента; у ataraxia это обычно HTML |
raw_text, message | Исходный текст без вставленных тегов. У служебного сообщения может быть None |
entities | Объекты разметки: жирный текст, ссылки, код и другие |
id | Номер сообщения. r.message_id не используй: у этого класса подтверждено поле id |
date, edit_date | Дата отправки и, если сообщение редактировали, дата правки |
sender_id, sender | Id отправителя и его объект, если он уже загружен |
input_sender, from_id | Адресат для Telegram API и сырой объект отправителя. Для анонимного сообщения могут отсутствовать |
chat_id, chat | Числовой id чата и объект чата, если он есть в кеше |
input_chat, peer_id, to_id | Варианты адресата для запросов к Telegram. Это не название чата |
is_private, is_group, is_channel | Тип чата. Для супергруппы is_group и is_channel могут оба быть True |
out, post, mentioned | Исходящее ли сообщение, является ли постом канала и упоминает ли тебя |
is_reply, reply_to_msg_id, reply_to | Ответ ли это сообщение, id исходного сообщения и сырой заголовок реплая |
reply_to_chat, reply_to_sender | Чат и отправитель оригинала при ответе через границу чатов, если данные доступны |
r.sender и r.chat читают уже известные данные и могут быть пустыми. Если объект нужен для дальнейшей работы, попробуй await r.get_sender() или await r.get_chat(): эти методы при необходимости запросят данные у Telegram, но тоже могут вернуть None. Один только id проще брать из r.sender_id или r.chat_id.
Медиа, файл и кнопки
| Свойство r | Что возвращает |
|---|---|
media, file | Сырой объект вложения и удобную обёртку для фото или документа. Для опроса либо сообщения без файла file будет None |
photo, document | Фото или документ Telegram, если он есть |
video, video_note, gif | Видео, кружок или анимацию. Каждый вариант определяется атрибутами документа |
audio, voice, sticker | Аудиофайл, голосовое или стикер |
web_preview, contact, geo | Превью сайта, карточку контакта либо координаты |
venue, poll, dice, game, invoice | Место, опрос, кубик, игру или счёт |
buttons, button_count, reply_markup | Кнопки по рядам, их количество и сырой объект разметки. buttons может быть None |
media_unread, grouped_id | Статус прочтения медиа и id альбома, если сообщение входит в альбом |
via_input_bot, via_bot_id | Адресат инлайн-бота для API и его числовой id, если сообщение отправлено через бота |
Если r.file существует, у него доступны name, ext, mime_type, size, width, height, duration, title, performer, emoji, sticker_set и id. Не все атрибуты подходят каждому типу файла: у картинки не будет названия песни.
.e r.file.name if r.file else "Файла нет"
.e r.file.size if r.file else None
.e bool(r.voice)
.e r.button_count
Пересылка, реакции и служебные поля
| Свойство r | Что означает |
|---|---|
forward, fwd_from | Удобная обёртка и сырой заголовок пересланного сообщения |
views, forwards, replies | Просмотры, число пересылок и данные об ответах, если Telegram их прислал |
reactions, pinned | Реакции и статус закрепления |
post_author, silent, noforwards | Подпись автора поста, тихая отправка и запрет пересылки |
action, action_entities | Действие служебного сообщения, например изменение состава чата, и связанные участники |
ttl_period, restriction_reason | Время автоудаления и причины ограничения, если заданы |
client | Клиент Telegram, которым получено сообщение |
В Message есть и другие сырые поля Telegram: saved_peer_id, from_scheduled, legacy, edit_hide, invert_media, offline, effect, factcheck, suggested_post и rich_message. Они появляются только в подходящих типах сообщений и зависят от версии ataraxia-tl. Для повседневных команд обычно хватает свойств из таблиц выше.
Методы r
Методы ниже асинхронные, поэтому в .e перед ними нужен await. Исключение в этом списке одно: get_entities_text() вызывается без await.
У click можно указать i, j, text, filter или data; для кнопок запроса контакта, геолокации и 2FA предусмотрены share_phone, share_geo и password. У pin есть notify и pm_oneside, у react есть big, add_to_recent, keep_existing, а у link есть grouped и thread. Это параметры методов Message, а не отдельные команды ataraxia.
| Метод | Что делает |
|---|---|
get_sender(), get_input_sender() | Получают отправителя или пригодный для API адресат. Могут обратиться к Telegram, если данных нет в кеше |
get_chat(), get_input_chat() | Получают чат либо адресат для запросов к нему |
get_reply_message() | Возвращает сообщение, на которое отвечает сам r, если оно доступно |
respond("текст"), reply("текст") | Отправляют сообщение в тот же чат; reply создаёт реплай на r |
forward_to("me") | Пересылает сообщение в Избранное |
edit("текст"), delete() | Редактируют или удаляют при наличии прав. Чужое сообщение просто так не отредактировать |
download_media() | Скачивает вложение на машину, где работает ataraxia. Без вложения результата может не быть |
get_buttons() | Получает кнопки, если свойство buttons не смогло собрать их из кеша |
click(0), click(text="Да") | Нажимает кнопку или голосует в опросе. Позиции начинаются с нуля; можно указать строку и колонку click(0, 1) |
mark_read() | Отмечает сообщение прочитанным |
pin(), unpin() | Закрепляет или открепляет сообщение при наличии прав |
react("👍") | Отправляет реакцию, если она разрешена в чате |
link() | Получает ссылку на сообщение с учётом типа чата |
translate("en") | Возвращает перевод сообщения на указанный язык через метод клиента; доступность зависит от Telegram и типа сообщения |
get_entities_text() | Без await возвращает пары «объект разметки, соответствующий текст» |
Примеры .e и ловушки
.e len(r.raw_text or "")
.e len((r.raw_text or "").split())
.e (await r.get_sender()).first_name
.e await r.reply("Получил")
.e await r.forward_to("me")
.e await r.link()
.e await r.react("👍")
.e await r.download_media()
.e r.file.name if r.file else "Вложения нет"
r.raw_text может быть None, поэтому в подсчёте стоит or "". r.file.name вызовет ошибку, если файла нет. r.sender бывает не загружен: для имени попробуй await r.get_sender(). Если Telegram не вернул отправителя, проверяй результат на None. Методы изменения чужих сообщений ограничены правами Telegram.
Кнопки через r.click(...) нажимай только на доверенных сообщениях. Некоторые кнопки запрашивают телефон, геолокацию или пароль 2FA; для них API требует явно указать соответствующие аргументы. Обычный клик можно выбрать по индексу click(0) или точному тексту click(text="Да").
Если написать просто .e реплаем на сообщение, содержащее код, Evaluator попробует исполнить текст реплая. Проверь, что там написано, до запуска.
Вывод, ошибки и флаги
- Результат последнего выражения показывается автоматически
- Текст из
print()перехватывается, после результата показывается время исполнения - При ошибке ataraxia присылает traceback, смотри последнюю строку, там обычно причина
- Номер телефона, строка сессии, токены и ключи маскируются в выводе. Это страховка от случайного показа, а не повод выводить секреты
- Длинный вывод превращается в постраничную инлайн-форму или файл
Если нужен не Python
.ecpp запускает C++ через g++, .ec C через тот же g++, .enode JavaScript через node. Эти компиляторы и рантаймы должны быть установлены отдельно. Можно передать код после команды или ответить командой на сообщение с кодом.
Rich messages
Telegram умеет рисовать богатые сообщения: заголовки, таблицы, цитаты, раскрывающиеся блоки. ataraxia отправляет их двумя способами: markdown от вашего аккаунта и HTML-экраны через инлайн-бота.
Два пути, одна цель
| Способ | От кого | Что дает | Кому доступно |
|---|---|---|---|
rich="markdown" | От вашего аккаунта | Заголовки, таблицы, вложенные списки, блоки кода | Всем, премиум не нужен |
Экран Screen | Через инлайн-бота | Всё то же плюс кнопки внутри текста и нижняя клавиатура | Всем, но кастомные эмодзи только с премиумом |
Оба способа рендерит сам Telegram: вы отправляете исходник, а клиент рисует. Если чат или клиент формат не принял, ataraxia сама упадет на обычный текст с кнопками внизу, сообщение не потеряется.
Markdown от аккаунта
Проще всего через utils.answer: параметр rich принимает markdown-исходник, и сообщение уходит от вашего аккаунта, а не от бота.
await utils.answer(
message,
rich=(
"# Отчёт\n"
"| Метрика | Значение |\n"
"|---|---|\n"
"| Пинг | 42 мс |\n"
"| Аптайм | 3 дня |\n\n"
"- **CPU**: 12%\n"
"- **RAM**: 210 MB\n"
),
)
Параметр markdown= у utils.answer это то же самое, что rich=. Разница появляется только в инлайн-формах: там markdown уходит от бота, а rich от аккаунта.
Поддерживаемый markdown: заголовки #, таблицы, вложенные списки, блоки кода, цитаты. Telegram сам превращает исходник в богатое сообщение, поэтому текст не парсится и не режется на страницы: что написали, то и уйдет целиком.
Экраны Screen
Когда нужны кнопки внутри текста, соберите экран. Screen это конструктор rich HTML: тело набирается фрагментами, а тапы в тексте регистрируются как обычные колбэки формы, с той же проверкой прав.
from ..inline.screens import Screen
def build_screen(self) -> Screen:
k = self.inline.screen() # экран, aware премиума владельца
k.add(
f"{k.icon('settings')} Меню {k.badge('3 пункта', 'primary')}",
k.quote("Описание меню"),
)
k.add(
k.details(
f"{k.icon('module')} Разделы · 2",
"\n".join(
k.tap(name, self.section_cb, name) + f" {k.badge(n)}"
for name, n in [("Основное", 5), ("Прочее", 2)]
),
)
)
k.add(
k.table([
["Параметр", "Значение"],
["Язык", "ru"],
["Префикс", "."],
])
)
k.keyboard(
[k.input("Добавить", self.add_input, "Что добавить?", icon="add")],
k.footer(self.back_home),
)
return k
@loader.command()
async def menucmd(self, message):
"""Открыть меню"""
await self.inline.form(message=message, rich_html=self.build_screen())
Фрагменты тела
| Метод | Что рисует |
|---|---|
k.tap(label, cb, *args) | Кнопка внутри текста; колбэк получает call и аргументы. Стили: primary, success, danger, link |
k.copy(label, value) | Кнопка копирования, до 256 символов значения |
k.badge(text, style) | Неактивная плашка, например счетчик |
k.row(*buttons, align=) | Ряд из нескольких кнопок, до 8 в ряду |
k.details(summary, body, open=) | Раскрывающийся блок |
k.table(rows, keys=) | Таблицу; первая строка по умолчанию заголовок |
k.quote(body, expandable=) | Цитату, обычную или раскрывающуюся |
k.image(url) | Картинку |
k.icon("settings") | Иконку: с премиумом кастомный эмодзи, без него обычный |
Нижняя клавиатура и ввод
| Метод | Что делает |
|---|---|
k.button(label, cb, *args) | Обычная кнопка внизу |
k.input(label, handler, prompt) | Кнопку, запрашивающую значение: handler(call, value) |
k.copy_button(label, value) | Кнопку копирования внизу |
k.back(cb), k.close() | «Назад» и «Закрыть» |
k.footer(back_cb) | Готовый ряд «Назад + Закрыть» |
k.pager(cb, page, pages) | «‹ 1 / N ›»; cb(call, page=...). Страницы режет k.page(items, page, size) |
k.reply(handler) | Разрешает ответить текстом на сообщение-экран: handler(call, text). Ответное сообщение удаляется |
Экран редактируется как обычная форма: await call.edit(rich_html=another_screen). Хелпер await self.inline.show(call, screen) делает то же и заодно показывает тост: присвойте screen.toast = "Сохранено" перед показом, а screen.alert = True сделает его всплывающим окном. Для предупреждения в теле есть k.warn(text).
Запасной вывод
Старый клиент, чат без поддержки или ошибка отправки не ломают сообщение. При сбое rich-формы ataraxia перегоняет экран в обычный Telegram HTML: таблицы становятся строками «ключ: значение», кнопки-тапы переезжают в нижнюю клавиатуру, раскрывающиеся блоки разворачиваются. То же самое происходит в utils.answer: markdown уходит как есть, а при ошибке повторяется обычным текстом.
Один нюанс: rich HTML нельзя совместить с медиа в одной форме, параметры photo, gif, file, video и прочие с rich_html не сочетаются. Картинку в rich-сообщении добавляет <img> в самом HTML.
Свой модуль
Модуль это Python-файл с классом-наследником loader.Module. Отправляешь файл в Telegram и отвечаешь на него .lm, или кладёшь в loaded_modules/. Перезапускать ataraxia обычно не приходится.
Минимальный пример
from ataraxia import loader, utils
@loader.tds
class HelloMod(loader.Module):
"""Отвечает приветствием"""
strings = {"name": "Hello"}
@loader.command()
async def hello(self, message):
"""Поздороваться"""
await utils.answer(message, "Привет")
В .help появится модуль Hello и команда .hello. Строка в тройных кавычках под методом служит описанием команды. Другой способ регистрации: назвать метод hellocmd, тогда суффикс cmd будет отброшен.
Работа с сообщениями
В message приходит само сообщение с командой. utils.get_args_raw(message) вернет весь текст после команды, а utils.get_args(message) разобьет аргументы на слова. Реплай получаешь через await message.get_reply_message().
await utils.answer(message, "текст") отвечает в тот же чат. Есть и rich-режим: await utils.answer(message, rich="markdown") отправит от вашего аккаунта богатое сообщение Telegram с заголовками, таблицами и вложенными списками, а если клиент или чат не поддержит формат, упадет на обычный текст.
Настройки и сохранение данных
Если пользователю надо менять параметр через .config, объяви его в конструкторе:
def __init__(self):
self.config = loader.ModuleConfig(
loader.ConfigValue(
"greeting", "Привет", "Текст ответа",
validator=loader.validators.String(),
),
)
Читается как self.config["greeting"]. Валидаторы проверяют тип: есть Boolean, Integer, Float, Choice, MultiChoice, Series, Link, Hidden и другие. Если нужно просто запомнить значение для самого модуля, есть self.set("ключ", значение) и self.get("ключ", значение_по_умолчанию). Эти данные переживают перезапуск, а self.pointer возвращает список или словарь, сохраняющий изменения автоматически.
Ватчер и фоновый цикл
Команда срабатывает по запросу владельца. Ватчер вызывается при сообщениях и может реагировать сам. Теги отбирают нужные события:
@loader.watcher("in", "only_messages", "no_commands")
async def watcher(self, message):
if "привет" in (message.raw_text or "").lower():
await message.reply("Привет")
@loader.loop(interval=300, autostart=True)
async def ticker(self):
await self.client.send_message("me", "Прошло пять минут")
in оставляет входящие сообщения, only_messages убирает служебные события, no_commands исключает команды юзербота. Полный набор тегов шире: out, only_media, no_pm, only_groups, regex, contains, startswith, from_id, chat_id и другие; их можно комбинировать прямо в @loader.watcher(...). loader.loop запускает метод по интервалу в секундах. Не стоит делать ватчер, который отвечает на каждое сообщение без ограничений: так недолго поймать FloodWait.
Для сырых TL-апдейтов есть @loader.raw_handler(UpdateType): реак-ции, бусты, бизнес-события и прочее приходят как чистые объекты, а обработчик снимается при выгрузке модуля, зомби-хендлеров не остается.
Меню на кнопках
Их отправляет персональный инлайн-бот, который создается при первом входе:
async def pressed(self, call):
await call.answer("Готово")
await call.edit("Кнопка сработала")
@loader.command()
async def menucmd(self, message):
"""Открыть меню"""
await self.inline.form(
text="Меню",
message=message,
reply_markup=[
{"text": "Нажать", "callback": self.pressed},
{"text": "Закрыть", "action": "close"},
],
)
Колбэк получает call. Через него можно ответить на нажатие, изменить сообщение, удалить или выгрузить форму. У кнопок бывают callback, url, input, data, web_app, copy, готовые действия вроде close, а также style (primary, success, danger, link) и emoji_id. Для списков со страницами есть self.inline.list(...).
Когда клиент готов
В client_ready можно делать запросы к Telegram. config_complete вызывается после загрузки конфигурации, on_unload при выгрузке, on_dlmod при первой установке файла. Если в client_ready бросить loader.LoadError("причина"), пользователь увидит причину отказа. loader.SelfUnload тихо выгрузит модуль, если условие не выполнено.
async def client_ready(self):
self.me = await self.client.get_me()
Что уже есть на self
| Имя | Для чего |
|---|---|
self.client | Telegram-клиент |
self.db | База данных всех модулей |
self.get, self.set, self.pointer | Данные этого модуля; pointer автоматически сохраняет изменения списка и словаря |
self.inline | Формы и списки |
self.inline.bot | Бот-АПИ-подобный фасад инлайн-бота, работает поверх MTProto |
self.lookup("Имя") | Другой загруженный модуль |
self.tg_id | Telegram id текущего аккаунта |
self.get_prefix() | Текущий префикс команд |
self.import_lib(url) | Загрузить внешнюю библиотеку с классом loader.Library |
Инлайн-бот как Bot API
self.inline.bot это фасад в стиле Bot API: send_message, edit_message_text, send_photo, send_media_group, answer_inline_query, answer_callback_query, set_my_commands, get_chat_member, get_file и далее по списку. Внутри он делает настоящие MTProto-запросы от имени бота, поэтому download_file работает без лимитов размеров. Чего фасада не хватает, добывается напрямую: await self.inline.bot.invoke(functions.SomeRequest(...)). Объекты он принимает и возвращает обычные, словари тоже работают, а ошибки это TelegramBadRequest, TelegramForbiddenError, TelegramRetryAfter с полем retry_after.
Гостевые команды
Гостевая команда вызывается как @имя_бота команда аргументы из любого чата, даже где бота нет: Bot API guest mode. Метод помечается @loader.guest_command() или называется <cmd>_guest_handler, получает (message, args) и отвечает через self.inline.answer_guest(message, ...):
@loader.guest_command()
async def ask(self, message, args):
await self.inline.answer_guest(message, "ответ из чата, где бота нет")
Вызывать может только владелец или участники группы owner. Пустое упоминание или неизвестная команда остаются без ответа. Встроенных гостевых команд нет, это функция внешних модулей. Ответ возвращает редактируемый InlineMessage; кнопки в гостевых чатах по умолчанию открыты всем, если не передать force_me или always_allow.
Шапка файла и совместимость
Загрузчик читает несколько строк в начале модуля. Например:
# meta developer: @username
# requires: requests
# packages: ffmpeg
# scope: ataraxia 0.1.0
__version__ = (1, 0, 0)
Автор попадет в справку, пакет из requires загрузчик попробует поставить через uv, пакет из packages через системный менеджер, а scope не даст поставить модуль на несовместимое ядро. Спецстроки # scope: ffmpeg и # scope: inline требуют наличия ffmpeg и настроенного инлайн-бота. Импорты telethon и herokutl внутри сторонних модулей ataraxia перенаправляет на ataraxia-tl. Поэтому старые модули часто работают без правок, хотя проверять всё равно стоит.
Рабочие примеры находятся в папке ataraxia/modules/. Начни с translations.py и test.py: там хорошо видно, как команда получает сообщение и как отвечает.
Если одной страницы мало
loader.Module даёт доступ к Telegram-клиенту, базе и инлайн-менеджеру. Для перевода строк интерфейса модуль может задать strings_ru и другие суффиксы: нужный вариант выбирается по текущему языку, а фолбэк общий strings. Внешние общие библиотеки подключаются через self.import_lib(url), библиотечный класс наследует loader.Library и оканчивается на Lib. Удобные методы вроде utils.escape_html и utils.get_chat_id лежат в ataraxia/utils/. Подписи аргументов и примеры вызывающих модулей смотри в исходниках.
Если что-то не работает
Начни с терминала и .logs. Последняя строка ошибки обычно полезнее, чем скриншот главного меню.
ataraxia-tl is required, use uv sync
Зависимости не разрешены. Запусти uv sync в папке проекта, затем uv run -m ataraxia. Если uv нет, поставь его: curl -LsSf https://astral.sh/uv/install.sh | sh.
Запуск как скрипт не работает
ataraxia нельзя запускать файлом. Только как пакет: uv run -m ataraxia из корня репозитория.
Сессия не читается, SessionDecryptError или SessionKeyMissing
Файл ataraxia.key потерялся или не совпадает с сессией. Без ключа сессии бесполезны: придется войти заново. Проверь, не скопировал ли ты файлы проекта без ключа.
Веб-интерфейс не открывается
Порт по умолчанию случайный, смотри баннер при старте или задай свой флагом --port. На VPS используй .weburl или --proxy-pass: туннель даст публичную https-ссылку. Полностью без веба есть --no-web.
Telegram выдал FloodWait
Это лимит Telegram, не ошибка установки. В сообщении указано, сколько ждать. Не повторяй попытки входа одну за другой, так ожидание может вырасти. Ограничитель .api_fw_protection ждёт локально и не доводит до FloodWait.
Инлайн-бот не создался
У аккаунта может быть лимит ботов в @BotFather или временное ограничение на их создание. Можно выбрать готового бота через .ch_ataraxia_bot <имя> и .ch_bot_token <токен>. Держи токен в тайне.
Команды молчат
Проверь, работает ли процесс, затем отправь команду от того же аккаунта, под которым авторизована ataraxia. В группе команда по умолчанию требует упоминания твоего юзернейма: отключается NoNick (.nonickchat в этом чате). Возможно, ты сменил префикс или внес чат в черный список.
Модуль не загрузился
Открой .logs. Там будет конкретная причина: отсутствие библиотеки, несовместимая версия ataraxia, ошибка самого модуля или не настроенный инлайн-бот. Модули с aiogram отклоняются сразу: используй self.inline. Если проблема касается одного модуля, сначала отключи его, а не сбрасывай весь бот.
Обновление упало на зависимостях
git pull уже прошел, код на диске новый, а работающий старый. Бот не перезапустится и предложит повторить синхронизацию кнопкой. Проверь вывод ошибки: обычно это сеть или недоступный git.break.wtf для ataraxia-tl.
Хочу начать с нуля
Сначала сохрани нужные данные через .backupall. Для сброса базы используй .cleardb; сессии и ключ удаляются вручную из папки проекта, после чего следующий запуск предложит вход заново.
Куда писать за помощью
Канал проекта: @ataraxia_ub, чат: @ataraxia_talks. Команда .support пришлет те же ссылки. Перед отправкой .logs посторонним прочитай файл: некоторые сторонние модули пишут в лог собственные секреты.