Files
arestools/README.md
T
ros 8bd13b4dd5 Перевести проект на Telegram Business (без хранения сессии)
Смена архитектуры с MTProto-юзербота (GramJS + строка сессии) на
официальное бизнес-подключение Telegram (Bot API). Проект больше НЕ
хранит сессию — работает только через бота с включённым Business Mode,
подключённого в Настройках → Telegram для бизнеса → Чат-боты. Это
соответствует ToS.

Изменения:
- удалено: scripts/login.js, src/userbot/client.js, модуль onetime
- src/userbot/ → src/business/: events.js подписывает business_message /
  edited / deleted / connection и нормализует сообщение; context.js даёт
  ctx.api = bot.api
- core/media.js: скачивание через getFile + fetch вместо GramJS
- core/db.js: составной ключ PRIMARY KEY (chat_id, msg_id) — в Bot API
  message_id уникален только внутри чата
- bot/panel.js: барьер владельца пропускает бизнес-апдейты (у них ctx.from
  это собеседник); убран UI одноразовых
- index.js: сборка только на grammY, явный allowed_updates с бизнес-типами
- config.js: убраны API_ID/API_HASH/SESSION, проверки на старте почищены
- package.json: убраны зависимости telegram и input, скрипт login
- README и .env.example переписаны под бизнес-подключение

Границы: onetime невозможен через Business API (сервер отбрасывает
self-destruct до доставки боту), медиа >~20 МБ не выгружаются (лимит
getFile), перехват — только личные 1-на-1 чаты.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 21:00:22 +03:00

125 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# telegrambusiness
Личный Telegram-бот на Node.js, работающий через **официальное бизнес-подключение** Telegram (Business API). Бот подключается к вашему аккаунту как чат-бот для бизнеса и сохраняет то, что собеседник удалил:
- **antidelete** — сообщения (и медиа), которые собеседник удалил в личке.
Всё управление и все перехваты приходят в этого же бота — в личку владельца. Наружу бот ничего не пишет, слеш-команд в чатах нет.
> ✅ **Без сессии, по правилам Telegram.** Проект **не хранит строку сессии** и не использует MTProto-юзербот. Работает исключительно через штатную функцию «Telegram для бизнеса» — обычный бот от [@BotFather](https://t.me/BotFather) с включённым Business Mode. Это соответствует ToS.
> ⚠️ **Дисклеймер.** Инструмент для личного использования на **своём** аккаунте и своей переписке. Не применяйте против других людей.
## Как устроено (важно понимать до запуска)
Telegram в бизнес-событии удаления (`deleted_business_messages`) присылает **только id сообщений** — без текста и без медиа. Поэтому «сохранить удалённое» реактивно невозможно: бот **заранее кэширует каждое входящее** в личке, а при удалении достаёт его из своего кэша. То же с медиа — файл качается **в момент прихода**, после удаления ссылка мертва.
Отсюда следствия:
- тексты и метаданные пишутся в локальную БД (`node:sqlite`), **зашифрованы** (AES-256-GCM);
- медиа лежат отдельными **зашифрованными** файлами в `data/media/`;
- всё чистится по `RETENTION_DAYS`.
### Чего этот подход НЕ умеет
- **Одноразовые медиа** («просмотр один раз», самоуничтожающиеся) перехватить **невозможно**: сервер Bot API отбрасывает такие сообщения ещё до доставки боту. Это ограничение платформы, обойти его без юзербота нельзя — а от юзербота мы отказались сознательно.
- **Медиа больше ~20 МБ** не скачиваются: у Bot API (`getFile`) лимит на размер файла. Такое медиа сохранится только как пометка о типе.
## Установка
Нужен Node.js ≥ 22.5 (для встроенного `node:sqlite`).
```bash
npm install
cp .env.example .env
```
Заполните `.env`:
1. **BOT_TOKEN** — новый бот у [@BotFather](https://t.me/BotFather).
2. **OWNER_ID** — ваш id (напишите [@userinfobot](https://t.me/userinfobot)).
3. **ENCRYPTION_KEY** — сгенерируйте: `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`.
Включите боту режим бизнеса и подключите его к аккаунту:
1. [@BotFather](https://t.me/BotFather) → `/mybots` → выберите бота → **Bot Settings****Business Mode****Enable**.
2. В приложении Telegram: **Настройки → Telegram для бизнеса → Чат-боты** → добавьте своего бота. Дайте ему право читать/управлять сообщениями.
Запуск:
```bash
npm run dev
```
Откройте своего бота, нажмите **Start** — появится панель. Когда собеседник удалит сообщение, бот пришлёт уведомление с кнопкой «Открыть».
`npm run dev` — с автоперезапуском, `npm start` — обычный запуск.
## Как добавить модуль
Модуль — файл в `src/modules/`. Загрузчик обходит папку рекурсивно; файлы на `_` игнорируются. Объявляйте только нужные хуки:
```js
// src/modules/keywords.js
export default {
name: 'keywords',
description: 'Уведомлять, если во входящем есть ключевое слово',
async onMessage(msg, ctx) {
if (!msg.isPrivateIncoming) return;
if (/срочно/i.test(msg.text ?? '')) {
await ctx.capture('deleted', { // переиспользуем ленту перехватов
chatId: msg.chatId,
senderId: msg.senderId,
sender: msg.sender,
text: msg.text,
});
}
},
};
```
Хук получает **нормализованное** сообщение: `{ chatId, msgId, senderId, sender, text, media, isPrivateIncoming }`.
| Хук | Когда вызывается |
| --- | --- |
| `setup(_, ctx)` | Один раз при старте |
| `onMessage(msg, ctx)` | Новое бизнес-сообщение (`business_message`) |
| `onEdited(msg, ctx)` | Правка (`edited_business_message`) |
| `onDeleted(event, ctx)` | Удаление; `event.chatId`, `event.msgIds` |
`ctx` даёт: `api` (grammY `bot.api`), `registry` и `capture(kind, data)` — сохранить перехват и уведомить владельца. Ошибка в одном модуле не роняет остальные ([registry.js](src/core/registry.js) — `runHook`).
## Устройство
```
src/
index.js сборка: бот + модули + чистка
config.js .env, проверка на старте
core/
crypto.js AES-256-GCM (шифр текста и медиа)
db.js node:sqlite: кэш входящих + лента перехватов
media.js тип медиа, скачать через getFile + шифровать
loader.js обход src/modules
registry.js реестр модулей, runHook
logger.js
business/
events.js подписка business_message/edited/deleted → модули
context.js ctx.capture — мост модуль↔БД↔бот
modules/
cache.js кэширует входящие (основа antidelete)
antidelete.js удаление → достать из кэша → перехват
bot/
panel.js бот: инлайн-панель, лента, выдача медиа
```
Поток: входящее (`business_message`) → `cache` кэширует текст и качает медиа → при удалении (`deleted_business_messages`) `antidelete` поднимает из кэша → `ctx.capture` пишет в БД и шлёт уведомление → панель показывает и отдаёт расшифрованный файл.
## Что стоит учесть
- Перехватываются только **входящие в личных диалогах**. Свои сообщения — нет (см. `isPrivateIncoming` в [events.js](src/business/events.js)).
- Id сообщения в Bot API уникален **только внутри чата**, поэтому в БД составной ключ `(chat_id, msg_id)`.
- Если вы отключите бизнес-подключение в настройках Telegram, перехват приостановится (бот залогирует это по апдейту `business_connection`).
- `CACHE_MEDIA=1` качает медиа каждого входящего, чтобы восстанавливать удалённые картинки. Это ест диск — при `=0` останется только текст и пометка о типе медиа.
- Ключ шифрования — в `.env`. Потеряете ключ — расшифровать хранилище нельзя.
- Хранилище локальное; `data/` в `.gitignore`.