Skip to content

feat: auto-follow basic group → supergroup target migration#9

Merged
awdr74100 merged 1 commit into
mainfrom
feat/auto-follow-supergroup-migration
Jun 30, 2026
Merged

feat: auto-follow basic group → supergroup target migration#9
awdr74100 merged 1 commit into
mainfrom
feat/auto-follow-supergroup-migration

Conversation

@awdr74100

Copy link
Copy Markdown
Owner

Problem

When a forward target is a basic group that later gets upgraded to a
supergroup, its id changes (e.g. -4187363166-100…). Telegram then
rejects every forward to the stale id with CHANNEL_INVALID /
PEER_ID_INVALID. Before this change that surfaced as a recurring
Forward failed error on every source message, and the only fix was to
manually re-run group edit.

What changed

The forwarder now recovers from this automatically. When a forward fails
with an invalid-target error, it probes the target with getChat:

  • Migrated → write the new supergroup id back to the config and retry
    the forward transparently on the new id (logged once, info level).
  • Still healthy / not migrated → re-raise the original error; the
    target was not the cause, so a good target is never wrongly retired.
  • Unreachable → retire it for this session (SkippedForward) and skip
    it silently after a single warning, instead of spamming the log on every
    source message.

FloodWait, deleted-message, and transient network errors are unaffected —
they still flow to the queue's existing retry logic.

Details

  • filter.ts: add replacePeer (swap a stored peer id, preserving order
    and dropping duplicates).
  • queue.ts: add SkippedForward sentinel so a deliberate skip is
    recorded as skipped (warning) rather than failed (error).
  • forwarder.ts: forwardOne / probeTarget migration handling,
    injectable persistConfig (defaults to saving the real config),
    per-session deadTargets set, and isInvalidTargetError.

Tests

  • replacePeer: swap / no-op / dedupe / empty.
  • isInvalidTargetError: matches the invalid-peer codes by errorMessage
    and message string, and does not swallow FloodWait or deleted-message
    errors.

pnpm typecheck, pnpm lint, pnpm test (61 passed), pnpm build, and
pnpm knip all pass.

Note: the forwardOne migration orchestration and the SkippedForward
queue branch are not directly unit-tested (they require driving a real
Dispatcher + RPC, which this repo deliberately does not mock). The pure
logic they rely on is covered.

When a forward target is a basic group that has been upgraded to a
supergroup, its id changes (e.g. -4187363166 → -100…) and Telegram
rejects forwards with CHANNEL_INVALID/PEER_ID_INVALID. Previously this
surfaced as a recurring "Forward failed" error on every source message
and required a manual `group edit`.

The forwarder now probes such a failed target with getChat: if it was
migrated, the new supergroup id is written back to the config and the
forward is retried transparently on the new id; a still-healthy target
re-raises the original error (it was not the cause); an unreachable
target is retired for the session and skipped silently after one warning.

- filter.ts: add replacePeer (swap a stored peer id, dedupe)
- queue.ts: add SkippedForward sentinel so a deliberate skip is recorded
  as 'skipped' (warning) rather than 'failed' (error)
- forwarder.ts: forwardOne/probeTarget migration handling, injectable
  persistConfig, per-session deadTargets set, isInvalidTargetError
- tests for replacePeer and isInvalidTargetError
@awdr74100
awdr74100 merged commit 45edca6 into main Jun 30, 2026
2 checks passed
@awdr74100
awdr74100 deleted the feat/auto-follow-supergroup-migration branch June 30, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant