fix(cron): normalize topic-qualified target.to in messaging tool suppress check (#29480)

* fix(cron): pass job.delivery.accountId through to delivery target resolution

* fix(cron): normalize topic-qualified target.to in messaging tool suppress check

When a cron job targets a Telegram forum topic (e.g. delivery.to =
"-1003597428309:topic:462"), delivery.to is stripped to the chatId
only by resolveOutboundTarget. However, the agent's message tool may
pass the full topic-qualified address as its target, causing
matchesMessagingToolDeliveryTarget to fail the equality check and not
suppress the tool send.

Strip the :topic:NNN suffix from target.to before comparing so the
suppress check works correctly for topic-bound cron deliveries.
Without this, the agent's message tool fires separately using the
announce session's accountId (often "default"), hitting 403 when
default bot is not in the multi-account target group.

* fix(cron): remove duplicate accountId keys after rebase

---------

Co-authored-by: jaxpkm <jaxpkm@jaxpkmdeMac-mini.local>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
bboyyan
2026-03-03 00:32:06 +08:00
committed by GitHub
parent 09f49cd921
commit d94de5c4a1
2 changed files with 11 additions and 1 deletions

View File

@@ -36,7 +36,11 @@ export function matchesMessagingToolDeliveryTarget(
if (target.accountId && delivery.accountId && target.accountId !== delivery.accountId) {
return false;
}
return target.to === delivery.to;
// Strip :topic:NNN suffix from target.to before comparing — the cron delivery.to
// is already stripped to chatId only, but the agent's message tool may pass a
// topic-qualified target (e.g. "-1003597428309:topic:462").
const normalizedTargetTo = target.to.replace(/:topic:\d+$/, "");
return normalizedTargetTo === delivery.to;
}
export function resolveCronDeliveryBestEffort(job: CronJob): boolean {

View File

@@ -42,6 +42,7 @@ export async function resolveDeliveryTarget(
jobPayload: {
channel?: "last" | ChannelId;
to?: string;
/** Explicit accountId from job.delivery — overrides session-derived and binding-derived values. */
accountId?: string;
sessionKey?: string;
},
@@ -118,6 +119,11 @@ export async function resolveDeliveryTarget(
}
}
// job.delivery.accountId takes highest precedence — explicitly set by the job author.
if (jobPayload.accountId) {
accountId = jobPayload.accountId;
}
// Carry threadId when it was explicitly set (from :topic: parsing or config)
// or when delivering to the same recipient as the session's last conversation.
// Session-derived threadIds are dropped when the target differs to prevent