diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 88bc853d..b0a0b0dc 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1306,6 +1306,48 @@ export const makeChatsSocket = (config: SocketConfig) => { 'fallback LID mappings are now available from update event' ) } + + // Automatic chat merge: notify consumers about LID→PN mapping + // This allows ZPRO and other consumers to merge/rename chats accordingly + // Collect all merge notifications to emit in a single batch + const mergeNotifications: ChatUpdate[] = [] + const mergedAt = Date.now() + + for (const mapping of mappings) { + const lidUser = jidNormalizedUser(mapping.lid) + const pnUser = jidNormalizedUser(mapping.pn) + + if (lidUser && pnUser && lidUser !== pnUser) { + logger.debug( + { lid: lidUser, pn: pnUser }, + 'collected chat update for LID→PN merge notification' + ) + + mergeNotifications.push({ + id: pnUser, + merged: true, + previousId: lidUser, + mergedAt + }) + } + } + + // Emit single batch of merge notifications for better performance + if (mergeNotifications.length > 0) { + logger.debug( + { count: mergeNotifications.length }, + 'emitting batch of chat merge notifications' + ) + ev.emit('chats.update', mergeNotifications) + } + + // Log warning if some mappings failed to store + if (result.errors > 0) { + logger.warn( + { errors: result.errors, total: mappings.length, notified: mergeNotifications.length }, + 'some LID-PN mappings failed to store, but merge notifications were sent' + ) + } } catch (error) { logger.warn({ count: mappings.length, error }, 'Failed to store LID-PN mappings') } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index d0a9a86d..03aa40ec 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -75,6 +75,12 @@ export type ChatUpdate = Partial< conditional: (bufferedData: BufferedEventData) => boolean | undefined /** last update time */ timestamp?: number + /** indicates if this chat was merged from LID to PN */ + merged?: boolean + /** previous chat ID before merge (LID format) */ + previousId?: string + /** timestamp when the merge occurred */ + mergedAt?: number } > diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 9277cf2c..7df99a26 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -189,6 +189,7 @@ export type BufferedEventData = { messageReactions: { [key: string]: { key: WAMessageKey; reactions: proto.IReaction[] } } messageReceipts: { [key: string]: { key: WAMessageKey; userReceipt: proto.IUserReceipt[] } } groupUpdates: { [jid: string]: Partial } + lidMappings: { [key: string]: LIDMapping } } export type BaileysEvent = keyof BaileysEventMap diff --git a/src/Utils/event-buffer.ts b/src/Utils/event-buffer.ts index 698c7d43..df92d939 100644 --- a/src/Utils/event-buffer.ts +++ b/src/Utils/event-buffer.ts @@ -83,7 +83,8 @@ const BUFFERABLE_EVENT = [ 'messages.delete', 'messages.reaction', 'message-receipt.update', - 'groups.update' + 'groups.update', + 'lid-mapping.update' ] as const type BufferableEvent = (typeof BUFFERABLE_EVENT)[number] @@ -882,7 +883,8 @@ const makeBufferData = (): BufferedEventData => { messageReactions: {}, messageDeletes: {}, messageReceipts: {}, - groupUpdates: {} + groupUpdates: {}, + lidMappings: {} } } @@ -1197,6 +1199,16 @@ function append( } } + break + case 'lid-mapping.update': + const lidMappings = eventData as BaileysEventMap['lid-mapping.update'] + for (const mapping of lidMappings) { + const key = `${mapping.lid}-${mapping.pn}` + if (!data.lidMappings[key]) { + data.lidMappings[key] = mapping + } + } + break default: throw new Error(`"${event}" cannot be buffered`) @@ -1325,6 +1337,11 @@ function consolidateEvents(data: BufferedEventData) { map['groups.update'] = groupUpdateList } + const lidMappingList = Object.values(data.lidMappings) + if (lidMappingList.length) { + map['lid-mapping.update'] = lidMappingList + } + return map }