Skip to content

Commit b5102ba

Browse files
Drickonsteipete
authored andcommitted
fix(hooks): add isGroup and groupId to message:sent context
Adds group context fields to MessageSentHookContext so hooks can correlate sent events with received events for the same conversation. Previously, message:received included isGroup/groupId but message:sent did not, forcing hooks to use mismatched identifiers (e.g. groupId vs numeric chat ID) when tracking conversations. Fields are derived from MsgContext in dispatch-from-config and threaded through route-reply and deliver via the mirror parameter. Addresses feedback from matskevich (production user, 550+ events) reported on PR #6797.
1 parent 7ad6a04 commit b5102ba

4 files changed

Lines changed: 29 additions & 0 deletions

File tree

src/auto-reply/reply/dispatch-from-config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ export async function dispatchReplyFromConfig(params: {
106106
const sessionKey = ctx.SessionKey;
107107
const startTime = diagnosticsEnabled ? Date.now() : 0;
108108
const canTrackSession = diagnosticsEnabled && Boolean(sessionKey);
109+
const isGroup = Boolean(ctx.GroupSubject || ctx.GroupChannel);
110+
const groupId =
111+
ctx.From?.includes(":group:") || ctx.From?.includes(":channel:") ? ctx.From : undefined;
109112

110113
const recordProcessed = (
111114
outcome: "completed" | "skipped" | "error",
@@ -291,6 +294,8 @@ export async function dispatchReplyFromConfig(params: {
291294
cfg,
292295
abortSignal,
293296
mirror,
297+
isGroup,
298+
groupId,
294299
});
295300
if (!result.ok) {
296301
logVerbose(`dispatch-from-config: route-reply failed: ${result.error ?? "unknown error"}`);
@@ -316,6 +321,8 @@ export async function dispatchReplyFromConfig(params: {
316321
accountId: ctx.AccountId,
317322
threadId: ctx.MessageThreadId,
318323
cfg,
324+
isGroup,
325+
groupId,
319326
});
320327
queuedFinal = result.ok;
321328
if (result.ok) {
@@ -499,6 +506,8 @@ export async function dispatchReplyFromConfig(params: {
499506
accountId: ctx.AccountId,
500507
threadId: ctx.MessageThreadId,
501508
cfg,
509+
isGroup,
510+
groupId,
502511
});
503512
if (!result.ok) {
504513
logVerbose(
@@ -549,6 +558,8 @@ export async function dispatchReplyFromConfig(params: {
549558
accountId: ctx.AccountId,
550559
threadId: ctx.MessageThreadId,
551560
cfg,
561+
isGroup,
562+
groupId,
552563
});
553564
queuedFinal = result.ok || queuedFinal;
554565
if (result.ok) {

src/auto-reply/reply/route-reply.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export type RouteReplyParams = {
3737
abortSignal?: AbortSignal;
3838
/** Mirror reply into session transcript (default: true when sessionKey is set). */
3939
mirror?: boolean;
40+
/** Whether this message is being sent in a group/channel context */
41+
isGroup?: boolean;
42+
/** Group or channel identifier for correlation with received events */
43+
groupId?: string;
4044
};
4145

4246
export type RouteReplyResult = {
@@ -145,6 +149,8 @@ export async function routeReply(params: RouteReplyParams): Promise<RouteReplyRe
145149
agentId: resolvedAgentId,
146150
text,
147151
mediaUrls,
152+
...(params.isGroup != null ? { isGroup: params.isGroup } : {}),
153+
...(params.groupId ? { groupId: params.groupId } : {}),
148154
}
149155
: undefined,
150156
});

src/hooks/internal-hooks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ export type MessageSentHookContext = {
8585
conversationId?: string;
8686
/** Message ID returned by the provider */
8787
messageId?: string;
88+
/** Whether this message was sent in a group/channel context */
89+
isGroup?: boolean;
90+
/** Group or channel identifier, if applicable */
91+
groupId?: string;
8892
};
8993

9094
export type MessageSentHookEvent = InternalHookEvent & {

src/infra/outbound/deliver.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ type DeliverOutboundPayloadsCoreParams = {
220220
agentId?: string;
221221
text?: string;
222222
mediaUrls?: string[];
223+
/** Whether this message is being sent in a group/channel context */
224+
isGroup?: boolean;
225+
/** Group or channel identifier for correlation with received events */
226+
groupId?: string;
223227
};
224228
silent?: boolean;
225229
};
@@ -478,6 +482,8 @@ async function deliverOutboundPayloadsCore(
478482
});
479483
const hookRunner = getGlobalHookRunner();
480484
const sessionKeyForInternalHooks = params.mirror?.sessionKey ?? params.session?.key;
485+
const mirrorIsGroup = params.mirror?.isGroup;
486+
const mirrorGroupId = params.mirror?.groupId;
481487
if (
482488
hookRunner?.hasHooks("message_sent") &&
483489
params.session?.agentId &&
@@ -534,6 +540,8 @@ async function deliverOutboundPayloadsCore(
534540
accountId: accountId ?? undefined,
535541
conversationId: to,
536542
messageId: params.messageId,
543+
...(mirrorIsGroup != null ? { isGroup: mirrorIsGroup } : {}),
544+
...(mirrorGroupId ? { groupId: mirrorGroupId } : {}),
537545
}),
538546
).catch(() => {});
539547
};

0 commit comments

Comments
 (0)