Импорт старой переписки из экспорта 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:
@@ -28,6 +28,10 @@ export const createMessageRepository = (db: Db) => {
|
||||
VALUES (@chatId, @messageId, @userId, @date, @author, @text, @replyToMessageId)
|
||||
ON CONFLICT(chat_id, message_id) DO UPDATE SET text = excluded.text
|
||||
`),
|
||||
insertIfMissing: db.prepare(`
|
||||
INSERT OR IGNORE INTO messages (chat_id, message_id, user_id, date, author, text, reply_to_message_id)
|
||||
VALUES (@chatId, @messageId, @userId, @date, @author, @text, @replyToMessageId)
|
||||
`),
|
||||
pruneChat: db.prepare(`
|
||||
DELETE FROM messages WHERE chat_id = ? AND message_id <= (
|
||||
SELECT message_id FROM messages WHERE chat_id = ?
|
||||
@@ -51,6 +55,18 @@ export const createMessageRepository = (db: Db) => {
|
||||
statements.pruneChat.run(message.chatId, message.chatId, keep);
|
||||
});
|
||||
|
||||
/**
|
||||
* Массовая загрузка (импорт): уже сохранённые сообщения не трогаем — живые данные точнее экспорта.
|
||||
* Возвращает, сколько сообщений добавлено; затем историю чата обрезаем до `keep` последних.
|
||||
*/
|
||||
const insertManyAndPrune = db.transaction((chatId: number, messages: ChatMessage[], keep: number): number => {
|
||||
const inserted = messages.reduce((sum, message) => sum + statements.insertIfMissing.run(message).changes, 0);
|
||||
|
||||
statements.pruneChat.run(chatId, chatId, keep);
|
||||
|
||||
return inserted;
|
||||
});
|
||||
|
||||
/** Последние `limit` сообщений чата в хронологическом порядке. */
|
||||
const latest = (chatId: number, limit: number): ChatMessage[] =>
|
||||
toChronological(statements.latest.all(chatId, limit));
|
||||
@@ -72,7 +88,7 @@ export const createMessageRepository = (db: Db) => {
|
||||
/** Удаляет всю сохранённую историю чата; возвращает, сколько сообщений удалено. */
|
||||
const deleteByChat = (chatId: number): number => statements.deleteByChat.run(chatId).changes;
|
||||
|
||||
return { upsertAndPrune, latest, latestByUser, findById, statsByChat, deleteByChat };
|
||||
return { upsertAndPrune, insertManyAndPrune, latest, latestByUser, findById, statsByChat, deleteByChat };
|
||||
};
|
||||
|
||||
export type MessageRepository = ReturnType<typeof createMessageRepository>;
|
||||
|
||||
Reference in New Issue
Block a user