From 166dc556c9b103152f2c80adb943e8f60b80d0df Mon Sep 17 00:00:00 2001 From: xCyanGrizzly Date: Mon, 25 May 2026 21:43:39 +0200 Subject: [PATCH] fix(worker): match old General-topic progress rows under new TDLib forum_topic_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the TDLib 1.8.50 → 1.8.64 upgrade, the worker now correctly enumerates all forum topics in MPE (1,086 of them) — a huge win. But a data-shape mismatch was about to bite us: TDLib changed how the General topic is identified. TDLib 1.8.50: info.message_thread_id = 1048576 (magic constant) TDLib 1.8.64: info.forum_topic_id = 1 Existing topic_progress rows for General carry topicId=1048576. The worker looks up progress via `topicProgressList.find(tp => tp.topicId === topic.topicId)`, which fails for General under the new TDLib → progress becomes null → the scan starts from message 0. For MPE specifically, that means re-scanning all ~378k General-topic messages. Dedup catches the previously-ingested ones (no double upload), but it burns hours of bandwidth before the watermark catches up. Fix: when topicId lookup misses for a topic named "General", fall back to a name match. The first watermark write after that saves under the new ID (1), so future runs hit the topicId match directly without the fallback. The orphaned 1048576 row stays as harmless dead data — we don't delete it in case a TDLib downgrade or revert ever happens. Co-Authored-By: Claude Opus 4.7 (1M context) --- worker/src/worker.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/worker/src/worker.ts b/worker/src/worker.ts index c0d2b7b..8356b2e 100644 --- a/worker/src/worker.ts +++ b/worker/src/worker.ts @@ -563,6 +563,33 @@ export async function runWorkerForAccount( (tp) => tp.topicId === topic.topicId ); + // ── General-topic ID migration ── + // TDLib 1.8.50 reported `info.message_thread_id = 1048576` for + // the General topic (a magic constant). TDLib 1.8.64 reports + // `info.forum_topic_id = 1` for the same topic. Old DB rows + // therefore don't match the new numeric ID — fall back to a + // name match so we don't restart General from message 0. On + // the next watermark write, we'll save under the new ID and + // future runs hit the topicId match directly. The orphaned + // 1048576 row remains as harmless dead data. + if (!progress && topic.name === "General") { + const oldGeneral = topicProgressList.find( + (tp) => tp.topicName === "General" && tp.topicId !== topic.topicId + ); + if (oldGeneral) { + accountLog.info( + { + channel: channel.title, + oldTopicId: oldGeneral.topicId.toString(), + newTopicId: topic.topicId.toString(), + preservedWatermark: oldGeneral.lastProcessedMessageId?.toString() ?? null, + }, + "Reusing old General-topic progress under new TDLib forum_topic_id" + ); + progress = oldGeneral; + } + } + // ── SkippedPackage retry pass ── // If we have failed messages in this topic with attemptCount // below the cap, pull the watermark back below the lowest of