tg-userbot
by meriler
README.md
# Юзербот
MCP-сервер, который даёт агенту (Claude Code, Codex и любому MCP-клиенту) руки
в вашем Telegram: не бот с отдельным именем и кнопкой «Start», а ваш обычный
аккаунт-человек. Агент читает те же чаты, что видите вы, пишет от вашего имени,
жмёт кнопки чужих ботов, качает вложения, ставит реакции, ведёт очередь рассылки
с человеческими паузами. Плюс, в том же сервере, тулы для YouTube, Reddit и
Instagram: ресёрч и переписка живут в одном месте.
Работает на Telethon (MTProto). 68 инструментов, из них 45 про Telegram.
## Чем это отличается от обычного бота
| Что | Bot API | Юзербот |
| --- | --- | --- |
| Кто пишет | бот с суффиксом `_bot` | вы, обычный аккаунт |
| Кому может написать первым | только тем, кто нажал Start | кому угодно |
| Что видит в группе | сообщения по privacy-настройке | всё, что видите вы |
| Читает историю чата | нет | да, всю |
| Жмёт кнопки других ботов | нет | да |
| Риск | бан бота | бан аккаунта, поэтому аккаунт отдельный |
## Что умеет
**Читать.** `get_messages` (с пагинацией, топиками форума, метаданными медиа,
просмотрами и реакциями), `search_messages` по истории, `get_message_by_id`,
`export_channel` — выгрузка канала целиком, `list_chats`, `list_forum_topics`,
`get_chat_info`, `get_pinned_message`, `get_chat_member_count`, `get_me`.
**Писать.** `send_message` (в том числе ответом на конкретное сообщение),
`send_file`, `send_album`, `send_contact`, `edit_message`, `delete_message`,
`pin_message`, `unpin_message`, `forward_message`, `copy_message` — репост чужого
поста без плашки «переслано от», `react` — реакции, `set_typing` — «печатает…».
**Рассылать не под баном.** `queue_messages` кладёт серию в фоновую очередь и
шлёт по одному с паузой 25–45 секунд, `queue_status` показывает, где она.
Это не украшение: см. раздел про PeerFlood ниже.
**Отложенное.** `send_message(..., schedule="+2h")` или `schedule="2026-09-10 09:00"`,
дальше `get_scheduled_messages`, `reschedule_scheduled`, `delete_scheduled`,
`send_scheduled_now`. Годится и как отложенный постинг, и как напоминалка себе.
**Общаться с чужими ботами как человек.** `list_inline_buttons`,
`press_inline_button`, `list_reply_buttons`, `press_reply_button`,
`read_bot_response`, `get_bot_info`. Отсюда же берётся трюк «создай себе бота
сам»: агент идёт в @BotFather, проходит диалог, ставит аватарку и команды.
**Медиа.** `download_media` (фото приходит картинкой прямо в контекст, видео и
файлы — на диск), `download_album`, `download_profile_photo`,
`get_sticker_set_emojis`.
**Администрировать.** `join_group`, `join_chatlist` — вступить во все чаты из
папки-ссылки, `add_chat_member`, `promote_admin` — выдать боту админку,
`create_folder`, `mute_chat`, `unmute_chat`.
**Ресёрч рядом.** YouTube (`yt_search`, `yt_video_info`, `yt_comments`,
`yt_captions`, `yt_channel_info`, `yt_playlist`, `yt_quota`), Reddit
(`reddit_search`, `reddit_hot`, `reddit_post`, `reddit_comments`,
`reddit_subreddit_info`, `reddit_user_posts`), Instagram (`ig_profile`,
`ig_posts`, `ig_reels`, `ig_post_comments`, `ig_hashtag`, `ig_search`),
плюс `browse_page`, `gdoc_read`, `gsheet_read` и `rate_limit_status`.
## Прежде чем ставить: как не потерять аккаунт
1. **Отдельный аккаунт и отдельный номер.** Не личный. Бан прилетает аккаунту
целиком, вместе с перепиской.
2. **Прогрейте его.** Заведите, залогиньтесь с телефона и просто поживите на нём
неделю: переписки, чтение каналов. Свежий аккаунт, который на второй день
начинает писать незнакомым, улетает быстро.
3. **Один IP — один юзербот.** Два аккаунта с одного адреса Telegram связывает
между собой: заблокируют один, найдут второй.
4. **Массовая отправка незнакомым — главный способ поймать бан.** Не FloodWait
(это секундная пауза, сервер её пересиживает сам), а PeerFlood: блокировка
отправки на сутки-двое всему аккаунту. Ловится объёмом плюс одинаковым текстом
встык. Поэтому серии — только `queue_messages`, тексты — разные.
5. **Реакции безопаснее слов.** `react` не считается рассылкой и годится как
прогрев активности.
Что сервер делает за вас: случайная пауза 2–5 секунд между вызовами, потолок
15 вызовов в минуту с автоматическим торможением, FloodWait пережидается со
сдвигом, entity кэшируются (без лишних resolve), fingerprint клиента — TDesktop
на Windows.
## Установка
Нужен свой сервер (проверено на Ubuntu 22.04 и 24.04, Python 3.10+; хватит
1 CPU и 1 ГБ памяти), Telegram-аккаунт из предыдущего раздела и телефон, на
котором этот аккаунт залогинен.
**1. Ключи приложения.** Зайти на `https://my.telegram.org` тем самым аккаунтом,
раздел API development tools, создать приложение. Оттуда `api_id` и `api_hash`.
Пара привязана к аккаунту, чужую не переиспользовать.
**2. Разложить код.**
```bash
mkdir -p /opt/tg-userbot && cd /opt/tg-userbot
git clone <репозиторий> app
python3 -m venv venv
venv/bin/pip install -r app/requirements.txt
```
**3. Войти в аккаунт.** Только на этом же сервере: логин с одного адреса и
работа с другого — повод для проверки со стороны Telegram.
```bash
cd /opt/tg-userbot/app && ../venv/bin/python scripts/login.py
```
Скрипт спросит `api_id`, `api_hash`, телефон и код. **Код приходит в само
приложение Telegram, а не по SMS, и живёт около пяти минут** — если провозились,
запустите заново. Есть двухфакторный пароль — спросит и его. В конце печатает
строку сессии.
**4. Настроить окружение.**
```bash
cp app/.env.example /opt/tg-userbot/.env
chmod 600 /opt/tg-userbot/.env
# заполнить TELEGRAM_API_ID, TELEGRAM_API_HASH, TELEGRAM_SESSION_STRING
```
Строка сессии равнозначна полному доступу к аккаунту: не в git, не в переписку,
права на файл 600. YouTube, Reddit и Instagram — по желанию, без ключей эти
тулы просто вернут понятную ошибку, Telegram работает.
**5. Политика исходящих** (подробности в следующем разделе). Пока файла нет,
переписка с людьми закрыта, а чтение и боты работают. Копируются оба файла:
```bash
cp app/policy.example.yaml /opt/tg-userbot/policy.yaml
cp app/assistant-gate.example.yaml /opt/tg-userbot/assistant-gate.yaml
```
Два места, куда стоит посмотреть сразу, а не потом:
- `live_channels` в примере пуст. Пока он пуст, агент может опубликовать в любой
ваш канал мгновенно. Есть канал с живой аудиторией — впишите его id сейчас.
- `human_gate.mode` в примере стоит `enforced`, стоп-лист берётся из
`assistant-gate.yaml`. Правьте копию под себя; правила в примере — заготовка,
а не канон. Осознанно не хотите проверки — ставьте `disabled` руками.
**6. Поднять сервисом.**
```bash
cp app/deploy/tg-userbot.service /etc/systemd/system/
systemctl daemon-reload && systemctl enable --now tg-userbot
systemctl status tg-userbot
```
**7. Подключить агента.** Сервер слушает `127.0.0.1:8765` и наружу не смотрит.
С рабочей машины пробрасывается туннель, поверх него подключается MCP:
```bash
ssh -N -L 8765:localhost:8765 root@ваш-сервер # держать поднятым
claude mcp add userbot --transport http http://127.0.0.1:8765/mcp -s user
```
Проверка живости: `claude mcp list`, затем попросить агента вызвать `get_me`.
## Политика исходящих
Агент, который пишет живым людям от вашего имени, рано или поздно пообещает
что-нибудь лишнее. Поэтому проверка отправки живёт в самом сервере
(`common/outbound_policy.py`), а не в клиентском хуке: её нельзя обойти
переключением approvals или другой моделью.
`policy.yaml` рядом с рабочей копией (не внутри неё — `git pull` не должен её
трогать) задаёт три вещи:
- `self.extra_targets` — ваши собственные аккаунты; сообщения туда не считаются
перепиской с посторонним. Аккаунт самого юзербота добавляется автоматически;
- `live_channels` — боевые каналы: туда разрешена только отложенная публикация
в будущее, мгновенная запрещена;
- `human_gate.mode` — `disabled` (писать людям свободно) или `enforced`
(тексты проходят через стоп-лист `assistant-gate.yaml`, пример лежит рядом).
Поведение при поломке — закрытое: файла нет вообще, значит переписка с людьми
блокируется с объяснением, что это разовая настройка; файл битый или режим
незнакомый, значит блокируется всё охраняемое. `delete_scheduled` работает
всегда: инструмент остановки отправки нельзя терять вместе с конфигом.
Фразы из `requires_confirmation` уходят только после вашего явного решения —
повтором того же вызова с `approved_by_owner=true`. Флаг не отменяет
`forbidden_phrases` и не разрешает мгновенную публикацию в боевой канал.
## Что этот предохранитель не закрывает
Честный список, чтобы не полагаться на него больше, чем он стоит:
- **Агент с shell-доступом на этом же хосте обходит политику несколькими
командами** — правит `policy.yaml`, подменяет путь, останавливает сервис.
Гейт защищает от неудачной формулировки и спешки, а не от агента,
которому вы дали root там же.
- `forward_message` и `send_scheduled_now` выпускают контент без проверки текста.
- Часть действий аккаунта (`join_group`, `mute_chat`, `set_typing` и ещё
несколько) вне политики вовсе.
- Очередь рассылки проверяет политику при постановке, а не в момент отправки.
- Строка сессии на диске сервера — это весь аккаунт. Хост держите свой.
## Эксплуатация
```bash
systemctl status tg-userbot # жив ли
journalctl -u tg-userbot -f # логи
systemctl restart tg-userbot # перезапуск
/opt/tg-userbot/app/deploy/update.sh # git pull, зависимости, рестарт
```
Несколько аккаунтов на одной машине: свой каталог, свой `USERBOT_PORT`, своя
копия юнита. Помнить про пункт «один IP — один юзербот».
Квота YouTube (10 000 единиц в сутки) считается на ключ, а не на инстанс: два
сервера с одним ключом делят её, а счётчики ведут раздельно и оба думают, что
она целая.
## Лицензия и здравый смысл
Юзербот-API не запрещён, но политика Telegram запрещает спам и массовые
рассылки. Всё, что вы отправите этим сервером, отправлено вашим аккаунтом и
вашими руками. Ответственность тоже ваша.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues