diff --git a/.env.example b/.env.example index 5ff0815..60bfe86 100644 --- a/.env.example +++ b/.env.example @@ -18,4 +18,4 @@ OPENROUTER_API_KEY= # Путь к SQLite-базе и сколько сообщений на чат хранить DB_PATH=data/bot.db -HISTORY_LIMIT=2000 +HISTORY_LIMIT=5000 diff --git a/README.md b/README.md index 1fe0258..63856b1 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Telegram не отдаёт ботам сообщения, написанные 2. Пришли боту `result.json` с подписью `/import` — прямо в этот чат или боту в личку (в личке бот сам поймёт, какой это чат). Можно и ответить `/import` на уже отправленный файл. 3. Бот ответит, сколько сообщений и участников добавил. +Загружаются только сообщения с текстом: стикеры, голосовые, опросы и медиа без подписи пропускаются. HTML-экспорт не подходит — в нём нет ID авторов. + - Импорт идемпотентен: повторная загрузка ничего не дублирует, уже сохранённые ботом сообщения и ники не перезаписываются. - Хранится не больше `HISTORY_LIMIT` последних сообщений на чат — для большой истории подними лимит. - Ников в экспорте нет, только имена: участники из экспорта находятся по имени, ник подтянется, когда человек напишет при боте. @@ -61,7 +63,7 @@ pnpm dev \* нужен ключ того провайдера, чья модель выбрана; бот проверяет это при старте. | `DB_PATH` | нет | путь к SQLite, по умолчанию `data/bot.db` (в Docker — `/app/data/bot.db`) | -| `HISTORY_LIMIT` | нет | сколько сообщений на чат хранить, по умолчанию 2000 | +| `HISTORY_LIMIT` | нет | сколько сообщений на чат хранить, по умолчанию 5000 | ## Деплой (Dokploy) diff --git a/src/config.ts b/src/config.ts index 8aac254..2f9197f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -90,7 +90,7 @@ const parseModel = (): ModelChoice => { export const DB_PATH = envValue("DB_PATH") ?? "data/bot.db"; /** Сколько последних сообщений каждого чата хранить в базе; нужен боту и скрипту импорта. */ -export const HISTORY_LIMIT = positiveInt("HISTORY_LIMIT", 2000); +export const HISTORY_LIMIT = positiveInt("HISTORY_LIMIT", 5000); export const loadBotConfig = () => ({ botToken: required("BOT_TOKEN"), diff --git a/src/libs/telegram-export.ts b/src/libs/telegram-export.ts index ee8adde..d4c5716 100644 --- a/src/libs/telegram-export.ts +++ b/src/libs/telegram-export.ts @@ -21,8 +21,6 @@ const exportMessageSchema = z.object({ file: z.string().optional(), file_name: z.string().optional(), media_type: z.string().optional(), - sticker_emoji: z.string().optional(), - poll: z.object({ question: z.string() }).optional(), }); /** Экспорт одного чата из Telegram Desktop: «Экспорт истории чата» → формат JSON. */ @@ -66,19 +64,19 @@ const plainText = (text: ExportMessage["text"]): string => { return text.map((part) => (typeof part === "string" ? part : part.text)).join(""); }; -/** Та же разметка медиа, что у живых сообщений (`MEDIA_LABELS`), чтобы история читалась одинаково. */ +/** + * Импортируем только сообщения с текстом: стикеры, голосовые, опросы и медиа без подписи пропускаем. + * У медиа с подписью оставляем пометку из `MEDIA_LABELS` — как у живых сообщений. + */ const exportMessageText = (msg: ExportMessage): string | undefined => { const text = plainText(msg.text).trim(); + if (!text) return undefined; if (msg.photo) return withLabel(MEDIA_LABELS.photo, text); - if (msg.media_type === "sticker") return withLabel(MEDIA_LABELS.sticker, msg.sticker_emoji ?? ""); - if (msg.media_type === "voice_message") return MEDIA_LABELS.voice; - if (msg.media_type === "video_message") return MEDIA_LABELS.videoNote; if (msg.media_type === "video_file" || msg.media_type === "animation") return withLabel(MEDIA_LABELS.video, text); if (msg.file) return withLabel(MEDIA_LABELS.file(msg.file_name), text); - if (msg.poll) return withLabel(MEDIA_LABELS.poll, msg.poll.question); - return text || undefined; + return text; }; /** Новые экспорты кладут `date_unixtime`; в старых только локальное время без пояса — берём как есть. */