Telegram: preserve topic IDs in restart notifications (#1807)
Co-authored-by: hsrvc <hsrvc@users.noreply.github.com>
This commit is contained in:
@@ -20,6 +20,7 @@ Status: unreleased.
|
||||
- Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla.
|
||||
- Routing: precompile session key regexes. (#1697) Thanks @Ray0907.
|
||||
- TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein.
|
||||
- Telegram: keep topic IDs in restart sentinel notifications. (#1807) Thanks @hsrvc.
|
||||
|
||||
## 2026.1.24-3
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ export type AnnounceTarget = {
|
||||
channel: string;
|
||||
to: string;
|
||||
accountId?: string;
|
||||
threadId?: string; // Forum topic/thread ID
|
||||
};
|
||||
|
||||
export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget | null {
|
||||
@@ -22,7 +23,22 @@ export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget
|
||||
if (parts.length < 3) return null;
|
||||
const [channelRaw, kind, ...rest] = parts;
|
||||
if (kind !== "group" && kind !== "channel") return null;
|
||||
const id = rest.join(":").trim();
|
||||
|
||||
// Extract topic/thread ID from rest (supports both :topic: and :thread:)
|
||||
// Telegram uses :topic:, other platforms use :thread:
|
||||
let threadId: string | undefined;
|
||||
const restJoined = rest.join(":");
|
||||
const topicMatch = restJoined.match(/:topic:(\d+)$/);
|
||||
const threadMatch = restJoined.match(/:thread:(\d+)$/);
|
||||
const match = topicMatch || threadMatch;
|
||||
|
||||
if (match) {
|
||||
threadId = match[1]; // Keep as string to match AgentCommandOpts.threadId
|
||||
}
|
||||
|
||||
// Remove :topic:N or :thread:N suffix from ID for target
|
||||
const id = match ? restJoined.replace(/:(topic|thread):\d+$/, "") : restJoined.trim();
|
||||
|
||||
if (!id) return null;
|
||||
if (!channelRaw) return null;
|
||||
const normalizedChannel = normalizeAnyChannelId(channelRaw) ?? normalizeChatChannelId(channelRaw);
|
||||
@@ -37,7 +53,11 @@ export function resolveAnnounceTargetFromKey(sessionKey: string): AnnounceTarget
|
||||
const normalized = normalizedChannel
|
||||
? getChannelPlugin(normalizedChannel)?.messaging?.normalizeTarget?.(kindTarget)
|
||||
: undefined;
|
||||
return { channel, to: normalized ?? kindTarget };
|
||||
return {
|
||||
channel,
|
||||
to: normalized ?? kindTarget,
|
||||
threadId,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildAgentToAgentMessageContext(params: {
|
||||
|
||||
@@ -28,11 +28,16 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) {
|
||||
return;
|
||||
}
|
||||
|
||||
const threadMarker = ":thread:";
|
||||
const threadIndex = sessionKey.lastIndexOf(threadMarker);
|
||||
const baseSessionKey = threadIndex === -1 ? sessionKey : sessionKey.slice(0, threadIndex);
|
||||
// Extract topic/thread ID from sessionKey (supports both :topic: and :thread:)
|
||||
// Telegram uses :topic:, other platforms use :thread:
|
||||
const topicIndex = sessionKey.lastIndexOf(":topic:");
|
||||
const threadIndex = sessionKey.lastIndexOf(":thread:");
|
||||
const markerIndex = Math.max(topicIndex, threadIndex);
|
||||
const marker = topicIndex > threadIndex ? ":topic:" : ":thread:";
|
||||
|
||||
const baseSessionKey = markerIndex === -1 ? sessionKey : sessionKey.slice(0, markerIndex);
|
||||
const threadIdRaw =
|
||||
threadIndex === -1 ? undefined : sessionKey.slice(threadIndex + threadMarker.length);
|
||||
markerIndex === -1 ? undefined : sessionKey.slice(markerIndex + marker.length);
|
||||
const sessionThreadId = threadIdRaw?.trim() || undefined;
|
||||
|
||||
const { cfg, entry } = loadSessionEntry(sessionKey);
|
||||
@@ -42,7 +47,7 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) {
|
||||
// Handles race condition where store wasn't flushed before restart
|
||||
const sentinelContext = payload.deliveryContext;
|
||||
let sessionDeliveryContext = deliveryContextFromSession(entry);
|
||||
if (!sessionDeliveryContext && threadIndex !== -1 && baseSessionKey) {
|
||||
if (!sessionDeliveryContext && markerIndex !== -1 && baseSessionKey) {
|
||||
const { entry: baseEntry } = loadSessionEntry(baseSessionKey);
|
||||
sessionDeliveryContext = deliveryContextFromSession(baseEntry);
|
||||
}
|
||||
@@ -74,6 +79,7 @@ export async function scheduleRestartSentinelWake(params: { deps: CliDeps }) {
|
||||
|
||||
const threadId =
|
||||
payload.threadId ??
|
||||
parsedTarget?.threadId ?? // From resolveAnnounceTargetFromKey (extracts :topic:N)
|
||||
sessionThreadId ??
|
||||
(origin?.threadId != null ? String(origin.threadId) : undefined);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user