From bd2020bae370ad8d72a8ec6eecba866ccf2477be Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:48:54 -0300 Subject: [PATCH 1/8] Update WaMessageDispatchCoordinator.ts --- .../WaMessageDispatchCoordinator.ts | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/client/coordinators/WaMessageDispatchCoordinator.ts b/src/client/coordinators/WaMessageDispatchCoordinator.ts index 9c957bea..957f5f2b 100644 --- a/src/client/coordinators/WaMessageDispatchCoordinator.ts +++ b/src/client/coordinators/WaMessageDispatchCoordinator.ts @@ -49,6 +49,7 @@ import type { WaMessageClient } from '@message/WaMessageClient' import { proto, type Proto } from '@proto' import { normalizeEphemeralSettingSeconds, + STATUS_MENTION_DELAY, WA_ADDRESSING_MODES, WA_DEFAULTS, WA_NACK_REASONS, @@ -91,6 +92,8 @@ import { buildButtonAddonNode, buildDirectMessageFanoutNode, buildGroupSenderKeyMessageNode, + buildGroupStatusMentionMessage, + buildStatusMentionMetaNode, buildMetaNode } from '@transport/node/builders/message' import type { BinaryNode } from '@transport/types' @@ -760,6 +763,7 @@ export class WaMessageDispatchCoordinator { public async publishStatusMessage(input: { readonly message: Proto.IMessage readonly recipients: readonly string[] + readonly mentionedGroupJids?: readonly string[] readonly statusSetting?: WaStatusDistributionSetting readonly options?: WaSendMessageOptions }): Promise { @@ -783,8 +787,15 @@ export class WaMessageDispatchCoordinator { if (!seen.has(meUserLid)) { recipientsWithSelf.push(meUserLid) } + const mentionedGroups: string[] = [] + const seenGroups = new Set() + for (const jid of input.mentionedGroupJids ?? []) { + if (!isGroupJid(jid) || seenGroups.has(jid)) continue + seenGroups.add(jid) + mentionedGroups.push(jid) + } const statusSetting = input.statusSetting ?? 'contacts' - return this.publishSenderKeyFanout({ + const result = await this.publishSenderKeyFanout({ groupJid: WA_DEFAULTS.STATUS_BROADCAST_JID, senderJid, recipients: recipientsWithSelf, @@ -825,7 +836,11 @@ export class WaMessageDispatchCoordinator { remoteJid: WA_DEFAULTS.STATUS_BROADCAST_JID, context: 'status' }) - const customNodes: BinaryNode[] = [buildMetaNode({ status_setting: statusSetting })] + const customNodes: BinaryNode[] = [ + mentionedGroups.length > 0 + ? buildStatusMentionMetaNode(mentionedGroups, statusSetting) + : buildMetaNode({ status_setting: statusSetting }) + ] if (reportingArtifacts?.node) customNodes.push(reportingArtifacts.node) return { extraParticipants: ackHints, @@ -833,6 +848,38 @@ export class WaMessageDispatchCoordinator { } } }) + if (mentionedGroups.length > 0) { + if (result.id) { + await this.notifyGroupStatusMentions(result.id, mentionedGroups, ) + } else { + this.deps.logger.warn('invalid id, skipping mention notifications', { + groups: mentionedGroups.length + }) + } + } + } + + private async notifyGroupStatusMentions( + statusId: string, + groupJids: readonly string[], + mediaType: string + ): Promise { + const message = buildGroupStatusMentionMessage(statusId) + for (let index = 0; index < groupJids.length; index += 1) { + await delay(STATUS_MENTION_DELAY) + try { + await this.sendMessage(groupJids[index], message, { + additionalAttributes: { type: mediaType }, + disableGroupEphemeralAutoInject: true + }) + } catch (error) { + this.deps.logger.warn('failed to notify group of status mention', { + groupJid: groupJids[index], + statusId, + message: toError(error).message + }) + } + } } public async publishBroadcastListMessage(input: { From 53a6f0e73a1d68529fcebc2428a83175b2dbb9e3 Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:51:46 -0300 Subject: [PATCH 2/8] Update status.ts --- src/protocol/status.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/protocol/status.ts b/src/protocol/status.ts index 3031e058..e68d7799 100644 --- a/src/protocol/status.ts +++ b/src/protocol/status.ts @@ -7,3 +7,5 @@ export const WA_STATUS_DISTRIBUTION_SETTINGS = Object.freeze({ export type WaStatusDistributionSetting = (typeof WA_STATUS_DISTRIBUTION_SETTINGS)[keyof typeof WA_STATUS_DISTRIBUTION_SETTINGS] + +export const STATUS_MENTION_DELAY = 500 From 83b6795c06c5de9f08885d5a5bf85fcceebcc7a2 Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:57:20 -0300 Subject: [PATCH 3/8] Update message.ts --- src/transport/node/builders/message.ts | 43 +++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/transport/node/builders/message.ts b/src/transport/node/builders/message.ts index e250299b..7d586457 100644 --- a/src/transport/node/builders/message.ts +++ b/src/transport/node/builders/message.ts @@ -1,6 +1,7 @@ import type { WaButtonAddonKind } from '@message/encode/content' -import { WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NODE_TAGS } from '@protocol/constants' import type { BinaryNode } from '@transport/types' +import { WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NODE_TAGS } from '@protocol/constants' +import { WA_DEFAULTS } from '@protocol/defaults' interface EncryptedParticipant { readonly jid: string @@ -301,3 +302,43 @@ export function buildMetaNode(attrs: Record): BinaryNode { content: undefined } } + +export function buildStatusMentionMetaNode( + groupJids: readonly string[], + statusSetting: string +): BinaryNode { + return { + tag: 'meta', + attrs: { + status_setting: statusSetting + }, + content: [ + { + tag: 'mentioned_users', + attrs: {}, + content: groupJids.map((jid) => ({ + tag: 'to', + attrs: { jid } + })) + } + ] + } +} + +export function buildGroupStatusMentionMessage(statusId: string): Proto.IMessage { + return { + groupStatusMentionMessage: { + message: { + protocolMessage: { + key: { + remoteJid: WA_DEFAULTS.STATUS_BROADCAST_JID, + fromMe: true, + id: statusId, + participant: 'status_me' + }, + type: proto.Message.ProtocolMessage.Type.STATUS_MENTION_MESSAGE + } + } + } + } +} From 146c8e8aa200fe0bc28c2985b758033e1a1fb11e Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:01:40 -0300 Subject: [PATCH 4/8] Update message.ts --- src/transport/node/builders/message.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transport/node/builders/message.ts b/src/transport/node/builders/message.ts index 7d586457..61509683 100644 --- a/src/transport/node/builders/message.ts +++ b/src/transport/node/builders/message.ts @@ -2,6 +2,7 @@ import type { WaButtonAddonKind } from '@message/encode/content' import type { BinaryNode } from '@transport/types' import { WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NODE_TAGS } from '@protocol/constants' import { WA_DEFAULTS } from '@protocol/defaults' +import { proto, type Proto } from '@proto' interface EncryptedParticipant { readonly jid: string From 007eda1241b0d4455a6780d4ddeefa551617598f Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:04:29 -0300 Subject: [PATCH 5/8] Update WaMessageDispatchCoordinator.ts --- src/client/coordinators/WaMessageDispatchCoordinator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/coordinators/WaMessageDispatchCoordinator.ts b/src/client/coordinators/WaMessageDispatchCoordinator.ts index 957f5f2b..aaf5f2a0 100644 --- a/src/client/coordinators/WaMessageDispatchCoordinator.ts +++ b/src/client/coordinators/WaMessageDispatchCoordinator.ts @@ -850,13 +850,14 @@ export class WaMessageDispatchCoordinator { }) if (mentionedGroups.length > 0) { if (result.id) { - await this.notifyGroupStatusMentions(result.id, mentionedGroups, ) + await this.notifyGroupStatusMentions(result.id, mentionedGroups, input.message.type || 'text') } else { this.deps.logger.warn('invalid id, skipping mention notifications', { groups: mentionedGroups.length }) } } + return result } private async notifyGroupStatusMentions( From bf741e6ed693c364033d514d1a16a1a0040c4116 Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:05:41 -0300 Subject: [PATCH 6/8] Update constants.ts --- src/protocol/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocol/constants.ts b/src/protocol/constants.ts index 5567ad7c..2adaec99 100644 --- a/src/protocol/constants.ts +++ b/src/protocol/constants.ts @@ -112,7 +112,7 @@ export { WA_META_NODE_ATTRS_BOT } from '@protocol/bot' export type { WaBizBotType, WaBotMsgBodyType, WaBotMsgEditType } from '@protocol/bot' -export { WA_STATUS_DISTRIBUTION_SETTINGS } from '@protocol/status' +export { WA_STATUS_DISTRIBUTION_SETTINGS, STATUS_MENTION_DELAY } from '@protocol/status' export type { WaStatusDistributionSetting } from '@protocol/status' export { WA_EMAIL_CONTEXTS, From 1ca5b3e3ce7b71aa80b824ba901f741f097289af Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:10:21 -0300 Subject: [PATCH 7/8] Update WaMessageDispatchCoordinator.ts --- src/client/coordinators/WaMessageDispatchCoordinator.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/client/coordinators/WaMessageDispatchCoordinator.ts b/src/client/coordinators/WaMessageDispatchCoordinator.ts index aaf5f2a0..7853796c 100644 --- a/src/client/coordinators/WaMessageDispatchCoordinator.ts +++ b/src/client/coordinators/WaMessageDispatchCoordinator.ts @@ -850,7 +850,7 @@ export class WaMessageDispatchCoordinator { }) if (mentionedGroups.length > 0) { if (result.id) { - await this.notifyGroupStatusMentions(result.id, mentionedGroups, input.message.type || 'text') + await this.notifyGroupStatusMentions(result.id, mentionedGroups) } else { this.deps.logger.warn('invalid id, skipping mention notifications', { groups: mentionedGroups.length @@ -862,15 +862,14 @@ export class WaMessageDispatchCoordinator { private async notifyGroupStatusMentions( statusId: string, - groupJids: readonly string[], - mediaType: string + groupJids: readonly string[] ): Promise { const message = buildGroupStatusMentionMessage(statusId) for (let index = 0; index < groupJids.length; index += 1) { - await delay(STATUS_MENTION_DELAY) + await new Promise((r) => setTimeout(r, STATUS_MENTION_DELAY)) try { await this.sendMessage(groupJids[index], message, { - additionalAttributes: { type: mediaType }, + additionalAttributes: { type: 'text' }, disableGroupEphemeralAutoInject: true }) } catch (error) { From e294808a4f7b041475193b4799d2aeb2f92ef0eb Mon Sep 17 00:00:00 2001 From: Bob <115008575+bobslavtriev@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:32:59 -0300 Subject: [PATCH 8/8] Update WaStatusCoordinator.ts --- src/client/coordinators/WaStatusCoordinator.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/client/coordinators/WaStatusCoordinator.ts b/src/client/coordinators/WaStatusCoordinator.ts index 1de7c654..c901db40 100644 --- a/src/client/coordinators/WaStatusCoordinator.ts +++ b/src/client/coordinators/WaStatusCoordinator.ts @@ -18,6 +18,7 @@ export interface WaStatusCoordinatorOptions { readonly publishStatusMessage: (input: { readonly message: Proto.IMessage readonly recipients: readonly string[] + readonly mentionedGroupJids?: readonly string[] readonly statusSetting?: WaStatusDistributionSetting readonly options?: WaSendMessageOptions }) => Promise @@ -26,6 +27,7 @@ export interface WaStatusCoordinatorOptions { export interface WaSendStatusInput { readonly content: WaSendMessageContent readonly recipients: readonly string[] + readonly mentionedGroupJids: readonly string[] readonly statusSetting?: WaStatusDistributionSetting readonly options?: WaSendMessageOptions } @@ -71,6 +73,7 @@ export function createStatusCoordinator(options: WaStatusCoordinatorOptions): Wa message, recipients: input.recipients, statusSetting: input.statusSetting, + mentionedGroupJids: input.mentionedGroupJids, options: input.options }) return built.upload ? { ...published, upload: built.upload } : published