Переписать проект в личный MTProto-юзербот

Смена архитектуры с бизнес-бота на Bot API (команды со слешем) на
личный юзербот на GramJS/MTProto с управлением через компаньон-бота.

Возможности:
- antidelete — кэш входящих в личке, восстановление удалённых «у всех»
- onetime — перехват «просмотр один раз» фото/видео до истечения ссылки
- локальное хранилище node:sqlite + шифрование AES-256-GCM, чистка по сроку
- компаньон-бот (grammY): инлайн-панель, лента с пагинацией, выдача медиа,
  доступ только владельцу по OWNER_ID

Устройство:
- core/ — crypto, db, media, loader, registry, logger
- userbot/ — MTProto-клиент из строки сессии, подписка на события
- modules/ — фичи как модули с хуками setup/onMessage/onEdited/onDeleted
- bot/ — компаньон-бот (единственный UI)
- scripts/login.js — генерация строки сессии

Удалён старый код Bot API (commands/, handlers/, middlewares/, dispatcher,
store). Обновлены README и .env.example. Hcrgram/ (сторонний референс)
добавлен в .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-09 19:16:52 +03:00
parent e92e0df644
commit 15a03a77fd
40 changed files with 1845 additions and 922 deletions
+37
View File
@@ -0,0 +1,37 @@
import { NewMessage } from 'telegram/events/NewMessage.js';
import { DeletedMessage } from 'telegram/events/DeletedMessage.js';
import { EditedMessage } from 'telegram/events/EditedMessage.js';
import { logger } from '../core/logger.js';
import { runHook } from '../core/registry.js';
/**
* Подписывает клиент на апдметы и раздаёт их модулям через хуки.
* Мы слушаем всё, но модули сами решают, что делать (обычно — только личку).
*/
export function wireEvents(client, registry, ctx) {
client.addEventHandler(
(event) => runHook(registry, 'onMessage', event.message, ctx),
new NewMessage({}),
);
client.addEventHandler(
(event) => runHook(registry, 'onEdited', event.message, ctx),
new EditedMessage({}),
);
client.addEventHandler(
(event) => runHook(registry, 'onDeleted', event, ctx),
new DeletedMessage({}),
);
logger.debug('события юзербота подписаны: new / edited / deleted');
}
/** Личный диалог один-на-один (не группа, не канал, не свои Избранные). */
export function isPrivateIncoming(message, me) {
if (!message) return false;
if (message.out) return false; // исходящие от себя не перехватываем
const cls = message.peerId?.className;
return cls === 'PeerUser' && String(message.senderId) !== String(me?.id ?? '');
}