Files
arestools/src/index.js
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

66 lines
2.3 KiB
JavaScript

import { assertConfig, config } from './config.js';
import { createBot } from './bot/panel.js';
import { openDb, purgeOld } from './core/db.js';
import { loadModules } from './core/loader.js';
import { logger } from './core/logger.js';
import { runHook } from './core/registry.js';
import { createContext } from './business/context.js';
import { wireBusiness } from './business/events.js';
// Бизнес-апдейты Telegram по умолчанию не приходят — их нужно запросить явно.
const ALLOWED_UPDATES = [
'message',
'callback_query',
'business_connection',
'business_message',
'edited_business_message',
'deleted_business_messages',
];
// 1. Конфиг и БД — падаем понятной ошибкой, если что-то не задано.
try {
assertConfig();
} catch (err) {
logger.error(err.message);
process.exit(1);
}
openDb();
// 2. Бот (единственный UI и приёмник бизнес-апдейтов) — запускаем в фоне.
const bot = createBot();
bot
.start({
allowed_updates: ALLOWED_UPDATES,
onStart: ({ username }) => logger.info(`Панель поднята: @${username}`),
})
.catch((err) => {
logger.error('Бот не запустился (проверьте BOT_TOKEN):', err.message);
process.exit(1);
});
// 3. Модули: грузим и раздаём им бизнес-апдейты через хуки.
const registry = await loadModules();
const ctx = createContext({ bot, registry });
await runHook(registry, 'setup', undefined, ctx);
wireBusiness(bot, registry, ctx);
logger.info(`Готово. Активных модулей: ${registry.list().map((m) => m.name).join(', ')}`);
// 4. Периодическая чистка по сроку хранения.
if (config.retentionDays > 0) {
const timer = setInterval(() => {
const { messages, captures } = purgeOld();
if (messages || captures) logger.info(`Чистка: удалено сообщений ${messages}, перехватов ${captures}`);
}, 6 * 3600 * 1000);
timer.unref();
}
// 5. Аккуратная остановка.
for (const signal of ['SIGINT', 'SIGTERM']) {
process.once(signal, async () => {
logger.info('Останавливаюсь…');
await bot.stop().catch(() => {});
process.exit(0);
});
}