Импорт старой переписки из экспорта Telegram Desktop

- /import: прислать result.json с подписью /import в чат или боту в личку (или ответить на файл)
- Парсер экспорта (zod): текст частями, упоминания по имени-ссылке, медиа, служебные сообщения
- Импорт идемпотентен и не перезаписывает живые сообщения и ники
- Экспорт другого чата в группе отклоняется; в личке чат определяется по экспорту
- CLI import-history для файлов больше 20 МБ
- /context показывает ID чата
- Общие downloadFile и MEDIA_LABELS для живых сообщений, фото и импорта

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yunogasai
2026-09-24 20:18:43 +02:00
parent e812f1b1e2
commit 510221fd3c
17 changed files with 417 additions and 38 deletions

View File

@@ -0,0 +1,32 @@
import { readFileSync } from "node:fs";
import { DB_PATH, HISTORY_LIMIT } from "../config.js";
import { createDb } from "../libs/db.js";
import { parseChatExport } from "../libs/telegram-export.js";
import { createChatMemberRepository } from "../repositories/chat-member-repository.js";
import { createMessageRepository } from "../repositories/message-repository.js";
import { createHistoryImportService } from "../services/history-import-service.js";
/**
* Загрузка экспорта чата с диска — для файлов больше 20 МБ, которые бот не может скачать сам.
* Использование: node dist/scripts/import-history.js /app/data/result.json
*/
const [path] = process.argv.slice(2);
if (!path) throw new Error("Укажи путь к result.json: node dist/scripts/import-history.js <путь>");
const exported = parseChatExport(JSON.parse(readFileSync(path, "utf8")));
const db = createDb(DB_PATH);
const historyImportService = createHistoryImportService({
messageRepository: createMessageRepository(db),
chatMemberRepository: createChatMemberRepository(db),
historyLimit: HISTORY_LIMIT,
});
const result = historyImportService.importChat(exported);
db.close();
console.log(`«${exported.title}» (чат ${exported.chatId}): новых сообщений ${result.inserted} из ${result.total}.`);
console.log(`В истории ${result.stored} (лимит ${result.historyLimit}), новых участников ${result.newMembers}.`);