antitelega

Go userbot для Telegram, который массово сканирует чаты на наличие пользователей клиента Telega — форка Telegram от ВКонтакте, который незаметно регистрирует Telegram-аккаунты во внутренней инфраструктуре VK Calls. Тебе на руки приходит список «гадов» в Saved Messages, ничего никому не отправляется автоматически.
Это userbot = риск бана аккаунта. Не запускай с основного акка. Используй одноразовый номер, которым не жалко пожертвовать. Подробнее — Риски и предостережения.
Что такое Telega и зачем это сканировать
Telega — клиент Telegram, форкнутый и распространяемый ВКонтакте. При установке он подключает Telegram-аккаунт к бэкенду VK Calls (calls.okcdn.ru), и Telegram-id юзера попадает в OK-индексы. Подробнее — dontusetelega.lol.
Если коротко: установка Telega = твой Telegram-id «засвечен» во ВК. Этот проект позволяет проверить любой чат, где ты состоишь, и узнать, кто из участников засветился — по тому же самому методу, который используется в плагине detyect.json для exteraGram. Только не «один профиль за раз», а «весь чат на 700 человек за пару минут».
Быстрый старт
# 0. Зависимости (Debian/Ubuntu):
apt update && apt install -y git curl
# 1. Установи Go (если ещё нет): https://go.dev/dl/
curl -fsSL "https://go.dev/dl/go1.24.2.linux-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/armv.*/armv6l/').tar.gz" | sudo tar -C /usr/local -xz
export PATH=$PATH:/usr/local/go/bin
# 2. Собери
git clone https://github.com/CyberScoper/antitelega
cd antitelega
CGO_ENABLED=0 go build -o antitelega ./cmd/antitelega
# 3. Настрой
cp config.example.yaml config.yaml
# впиши свои api_id, api_hash, phone (см. ниже как получить)
# 4. Запусти (первый раз — интерактивно в терминале!)
./antitelega
# введи код из Telegram + облачный пароль (если есть 2FA)
# после: сессия сохранена, можно запускать через nohup
В Saved Messages напиши:
/scan @какой_то_чат
Через несколько минут получишь отчёт со списком найденных Telega-юзеров.
Как работает детект
В трёх шагах:
- Анонимный логин в OK —
POST https://calls.okcdn.ru/api/auth/anonymLogin с захардкоженным application_key=CHKIPMKGDIHBABABA. В ответ — session_key, который мы кладём в память на всё время работы бота.
- Запрос на каждый Telegram-id —
POST /api/vchat/getOkIdByExternalId с параметром externalId=<telegram_user_id> (просто число строкой, без обёрток).
- Парсинг ответа:
- Юзер пользуется Telega →
{"ok_id": 1125899910737868} (число — это его внутренний id во ВК)
- Юзер чист →
{"error_code": 300, "error_msg": "NOT_FOUND : No ok user found for external id: 12345; appId: 512001570726"}
Положительный результат означает, что в инфраструктуре OK существует mapping между этим Telegram-id и внутренним OK-юзером — то есть кто-то ставил Telega с этого аккаунта и его клиент засветился перед бэкендом VK Calls.
Установка
Всё описано в Быстром старте выше. Требования: Go 1.23+, git, curl. На чистом Debian/Ubuntu — apt update && apt install -y git curl перед началом.
Конфигурация
1. Получение api_id / api_hash
Идёшь на https://my.telegram.org/apps, логинишься своим номером, создаёшь приложение (название/тип любые — Telegram это не валидирует). Забираешь оттуда два значения:
api_id — целое число
api_hash — 32-символьная hex-строка
Это бесплатно, делается один раз, выдаётся за минуту.
2. config.yaml
cp config.example.yaml config.yaml
И впиши минимум три обязательных поля:
telegram:
api_id: 12345678
api_hash: "0123456789abcdef0123456789abcdef"
phone: "+79991234567"
Остальные поля имеют разумные дефолты — заходи в config.example.yaml, посмотри что есть.
3. Уровень риска (risk_level)
Управляет скоростью скана vs. незаметностью. Один параметр вместо ручной настройки worker_count/rate_limit/sleep:
scanner:
risk_level: "careful" # paranoid | careful | normal | aggressive | custom
| Уровень |
~Время на 700 чел. |
Workers |
req/s |
Page size |
Jitter |
paranoid |
~16 мин |
1 |
1 |
30 |
±50% |
careful |
~5 мин |
2 |
3 |
80 |
±40% |
normal |
~2.5 мин |
4 |
6 |
150 |
±30% |
aggressive |
~1.5 мин |
6 |
8 |
200 |
нет |
custom |
— |
по конфигу |
по конфигу |
по конфигу |
по конфигу |
По умолчанию — careful. Для ручной настройки выставь risk_level: custom и укажи параметры вручную (см. таблицу настроек ниже).
4. Через переменные окружения
Любое поле конфига переопределяется env-переменной вида ANTITELEGA_<SECTION>_<FIELD>:
ANTITELEGA_TELEGRAM_API_ID=12345678 \
ANTITELEGA_TELEGRAM_API_HASH=0123456789abcdef0123456789abcdef \
ANTITELEGA_TELEGRAM_PHONE=+79991234567 \
./antitelega --config /dev/null
Удобно для Docker / systemd / CI.
Первый запуск
Первый запуск — обязательно в интерактивном терминале (не через nohup/systemd), потому что потребуется ввести код и, возможно, пароль.
Запусти ./antitelega. Бот сначала залогинится в OK API (доли секунды), затем попросит код для Telegram:
$ ./antitelega
time=2026-04-10T20:06:59.719Z level=INFO msg="ok login ok"
Enter Code:
Код придёт в твоё Telegram-приложение от служебного аккаунта Telegram (не SMS). Введи 5 цифр прямо в терминал:
Enter Code: 92728
time=2026-04-10T20:08:39.280Z level=INFO msg="telegram client started" self=@username self_id=123456789
time=2026-04-10T20:08:39.280Z level=INFO msg="handlers registered, entering idle loop"
Если включена двухфакторная авторизация (облачный пароль)
После ввода кода бот дополнительно спросит пароль:
Enter Code: 92728
Enter Password:
Введи облачный пароль (тот, что в Telegram → Настройки → Конфиденциальность → Облачный пароль). Пароль не отображается при вводе. Если ошибёшься — будет до 3 попыток.
После успешного логина
Сессия сохраняется в ./data/antitelega.session. При следующих запусках код и пароль уже не нужны — вход моментальный. Теперь можно запускать в фоне:
nohup ./antitelega > data/antitelega.log 2>&1 &
Или через systemd/tmux/screen — на твой вкус.
Если кто-то убьёт сессию через Telegram → Настройки → Устройства, при следующем запуске бот снова попросит код. Это нормально.
Использование /scan
Все формы аргумента:
/scan — текущий чат, где ты пишешь команду
/scan @chatname — чат по @юзернейму
/scan -1001234567890 — чат по числовому id (включая префикс -100)
/scan https://t.me/chatname — чат по t.me-ссылке
По умолчанию команда ловится только когда ты сам её пишешь (любые твои исходящие сообщения). Это сделано специально, чтобы случайный участник чата не мог дёргать твой userbot. Если хочешь разрешить кому-то ещё — см. bot.accept_incoming и bot.allowed_user_ids ниже.
Поток выполнения:
- В исходном чате ты увидишь моментальный ack: «Сканирую
<title>… Отчёт придёт в Saved Messages.»
- Бот вытаскивает участников через
ChannelsGetParticipants (страницами, с паузой и jitter между страницами).
- Все собранные id проверяются по OK API через worker pool с rate-limiter'ом.
- По окончании — список найденных летит в Saved Messages, ack «Готово, найдено N» — в исходный чат.
Отчёт выглядит так:
AntiTelega scan: <chat title>
Всего проверено: 724, найдено: 16
OK-запросов: 724, из кэша: 0, заняло: 5m12.3s
1. Иван Иванов (@example_user_1) — tg://user?id=100000001
2. Алексей П. — tg://user?id=100000002
3. ...
Имена и tg://user?id=... ссылки кликабельны прямо в Telegram — тыкаешь и попадаешь в профиль.
Все настройки
| Поле |
По умолчанию |
Описание |
telegram.api_id |
— (обязательно) |
id с my.telegram.org |
telegram.api_hash |
— (обязательно) |
hash с my.telegram.org |
telegram.phone |
— (нужен на первом логине) |
в международном формате |
telegram.session_path |
./data/antitelega.session |
где хранить gotgproto-сессию |
telegram.device_model |
Desktop |
имя устройства, видимое Telegram |
telegram.system_version |
Windows 10 |
версия ОС, видимая Telegram |
telegram.app_version |
5.7.2 x64 |
версия приложения, видимая Telegram |
telegram.system_lang_code |
ru-RU |
язык системы |
telegram.lang_pack |
tdesktop |
семейство клиента (tdesktop/android/ios) |
telegram.lang_code |
ru |
язык интерфейса |
bot.command_prefix |
/ |
для userbot-стиля .scan тоже работает |
bot.accept_incoming |
false |
реагировать ли на /scan от не-себя |
bot.allowed_user_ids |
[] |
white-list id (только если accept_incoming: true) |
bot.report_to |
"saved" |
куда слать отчёт: saved или reply |
ok.base_url |
https://calls.okcdn.ru |
можно подменить для тестов |
ok.application_key |
CHKIPMKGDIHBABABA |
см. OK API key |
ok.session_data |
{"device_id":"antitelega",...} |
параметр анонимного логина |
ok.http_timeout |
12s |
таймаут HTTP-запросов в OK |
scanner.risk_level |
careful |
пресет скорости/стелса (см. выше) |
scanner.worker_count |
2 |
горутины для OK (переопределяется risk_level) |
scanner.rate_limit_per_sec |
3 |
rate-limit на OK API (переопределяется risk_level) |
scanner.participants_page_size |
80 |
размер страницы GetParticipants (переопределяется risk_level) |
scanner.participants_sleep_ms |
4000 |
пауза между страницами (переопределяется risk_level) |
scanner.participants_jitter_pct |
0.40 |
jitter ±% на паузу между страницами |
scanner.ok_jitter_ms |
800 |
случайная задержка 0..N мс на каждый OK вызов |
scanner.max_participants |
10000 |
потолок (Telegram сам перестаёт отдавать после ~10k) |
cache.db_path |
./data/cache.db |
SQLite-кэш результатов |
cache.ttl |
6h |
TTL положительных и отрицательных результатов |
logging.level |
info |
debug, info, warn, error |
logging.format |
text |
text или json |
OK API key
Самая хрупкая часть проекта. Читай если что-то перестало работать.
Что это за ключ
CHKIPMKGDIHBABABA — это application_key приложения зарегистрированного в инфраструктуре OK/VK. У него внутренний appId: 512001570726 (этот id видно прямо в error-сообщениях OK API: ... appId: 512001570726). Ключ принадлежит продукту VK Calls, которым пользуется как сам клиент Telega, так и (потому что мы используем тот же протокол) этот проект.
Технически мы делаем ровно то же самое, что делает свежеустановленный Telega-клиент при первом запуске:
- Идём на
anonymLogin с этим самым application_key.
- Получаем анонимный
session_key.
- Дёргаем дальше всё что нам нужно от лица этой анонимной сессии.
OK не отличает «настоящий клиент Telega» от antitelega — оба используют публично известный ключ через анонимную аутентификацию, оба ходят по тем же endpoint'ам.
Почему он захардкожен и почему его нельзя сменить «правильным способом»
Это не наш ключ. Это ключ ВК. Мы его не зарегистрировали и не имеем к нему официального доступа. Он встроен в APK Telega и в плагин exteraGram аналогично — авторы плагина, по всей видимости, достали его декомпиляцией.
В config.yaml его поле есть (ok.application_key) ровно для одного сценария: если OK когда-нибудь его отзовёт или замаркирует, ты сможешь подсунуть новый, не пересобирая бинарь.
Симптомы протухания ключа
| Что в логе |
Что это значит |
Что делать |
anonymLogin: empty session_key |
Ключ отозван целиком |
Нужен новый ключ |
getOkIdByExternalId: err=2 "SERVICE : ..." |
Rate-limit или soft-бан |
Подождать или сменить ключ |
getOkIdByExternalId: err=4 "REQUEST : common.finder" |
Контракт изменился |
Нужен код-фикс, не только ключ |
Все lookup'ы → false |
Тихая блокировка |
Сменить ключ или IP |
Как обновить ключ
ok:
application_key: "НОВЫЙ_КЛЮЧ_СЮДА"
Или: ANTITELEGA_OK_APPLICATION_KEY=НОВЫЙ_КЛЮЧ ./antitelega
Где взять новый ключ
- @exteraPluginsSup — если авторы обновят плагин, ключ будет в поле
CALLS_API_KEY (см. detyect.json).
- Декомпиляция APK Telega через
jadx — ищи application_key около URL calls.okcdn.ru.
- MITM трафика Telega — mitmproxy + эмулятор Android, лови
POST /api/auth/anonymLogin.
Если OK сменит контракт (имя метода, формат параметров) — нужен код-фикс в internal/okclient/client.go.
FAQ / Troubleshooting
«Бот не реагирует на /scan»
→ bot.accept_incoming: false по умолчанию — бот ловит только твои сообщения. Если тестируешь с другого аккаунта → bot.accept_incoming: true + bot.allowed_user_ids.
«После рестарта /scan молчит, /help работает»
→ Известная ловушка gotgproto: после рестарта в catch-up-сообщениях флаг out бывает false даже для твоих сообщений. Handler учитывает оба сигнала: msg.Out || sender_id == self_id.
«scan failed: CHAT_ADMIN_REQUIRED»
→ Включены «Скрытые участники» — без админ-прав никак.
«scan failed: flood_wait too long»
→ Telegram троттлит. Снизь risk_level до paranoid или careful.
«scan failed: ok batch: ... Application method temporarily unavailable»
→ OK API ключ протух или rate-лимит. См. секцию OK API key.
«scan failed: ok batch: ... common.finder»
→ Контракт OK API изменился, нужен код-фикс.
«panic: sql: Register called twice for driver sqlite»
→ Конфликт SQLite-драйверов. У нас исправлено (github.com/glebarez/go-sqlite). Если вернётся — проверь go.sum.
«Telegram: too many sessions»
→ Удали неиспользуемые сессии: Telegram → Настройки → Устройства.
«Сессия убита извне»
→ Перезапусти ./antitelega, код запросится заново.
«Сбросить кэш»
rm data/cache.db* && ./antitelega
Архитектура
Pipeline одного /scan:
/scan @target
↓
internal/botcmd/scan.go — auth, parse arg, ack, dispatch
↓
internal/scanner/scanner.go — orchestration: enumerate → cache → OK → persist → report
↓
internal/scanner/enumerate.go — ChannelsGetParticipants пагинация, FLOOD_WAIT-aware
↓
internal/db/db.go — Cache.GetMany — снимаем cache hits
↓
internal/scanner/scanner.go — batchCheckOK — worker pool + rate.Limiter + jitter
↓
internal/okclient/client.go — CheckOne — singular endpoint, session reuse
↓
internal/db/db.go — Cache.PutMany — транзакционная запись результатов
↓
internal/scanner/report.go — FormatReport, разбивка на чанки ≤3800 chars
↓
ec.SendMessage(savedMessages, ...)
Файлы:
Тесты:
Ограничения
- Каналы. Telegram скрывает список подписчиков каналов от не-админов. Можно отсканировать только админов канала.
- Супергруппы с «hidden members». Аналогично — без админ-прав не пройти.
- Legacy basic groups. Будет понятная ошибка «не супергруппа».
- Потолок ~10 000 участников. Лимит Telegram: после offset ~10000
ChannelsGetParticipants возвращает пустые страницы.
- OK API key. См. отдельную секцию.
Риски и предостережения
- Userbot = риск бана. Telegram может заморозить аккаунт за массовый
ChannelsGetParticipants. Используй одноразовый номер. Не храни на акке ничего ценного.
- Device fingerprint. Поля
telegram.device_model/lang_pack/etc. маскируют antitelega под Telegram Desktop. Если оставить пустыми — gotgproto отправит "GoTGProto" как имя клиента, что гарантирует бан.
- Детект ≠ «использует прямо сейчас». Найденный юзер когда-то ставил Telega и засветился в OK. Сейчас Telega может быть удалена, но mapping остался.
- ToS. Использование userbot нарушает ToS Telegram, а использование чужого application_key — ToS OK/VK. Для личного использования обычно сходит, но публичный сервис запускать не стоит.
- Не коммить
config.yaml — он содержит api_id/api_hash/phone. В .gitignore уже добавлено.
Лицензия и благодарности
Референс-плагин: @exteraPluginsSup, файл detyect.json в репозитории.
Используемые библиотеки:
MIT.