Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c52b01ea7 | |||
| a9e926b907 | |||
| 71fe69fd21 | |||
| eecf6df2a2 |
@@ -1,7 +1,7 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package proto;
|
package proto;
|
||||||
|
|
||||||
/// WhatsApp Version: 2.3000.1035370989
|
/// WhatsApp Version: 2.3000.1035484955
|
||||||
|
|
||||||
message ADVDeviceIdentity {
|
message ADVDeviceIdentity {
|
||||||
optional uint32 rawId = 1;
|
optional uint32 rawId = 1;
|
||||||
@@ -417,6 +417,7 @@ message BotCapabilityMetadata {
|
|||||||
JSON_PATCH_STREAMING = 58;
|
JSON_PATCH_STREAMING = 58;
|
||||||
AI_TAB_FORCE_CLIPPY = 59;
|
AI_TAB_FORCE_CLIPPY = 59;
|
||||||
UNIFIED_RESPONSE_EMBEDDED_SCREENS = 60;
|
UNIFIED_RESPONSE_EMBEDDED_SCREENS = 60;
|
||||||
|
AI_SUBSCRIPTION_ENABLED = 61;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-1
@@ -1092,7 +1092,8 @@ export namespace proto {
|
|||||||
RICH_RESPONSE_UR_IMAGINE_VIDEO = 57,
|
RICH_RESPONSE_UR_IMAGINE_VIDEO = 57,
|
||||||
JSON_PATCH_STREAMING = 58,
|
JSON_PATCH_STREAMING = 58,
|
||||||
AI_TAB_FORCE_CLIPPY = 59,
|
AI_TAB_FORCE_CLIPPY = 59,
|
||||||
UNIFIED_RESPONSE_EMBEDDED_SCREENS = 60
|
UNIFIED_RESPONSE_EMBEDDED_SCREENS = 60,
|
||||||
|
AI_SUBSCRIPTION_ENABLED = 61
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6897,6 +6897,10 @@ export const proto = $root.proto = (() => {
|
|||||||
case 60:
|
case 60:
|
||||||
m.capabilities[i] = 60;
|
m.capabilities[i] = 60;
|
||||||
break;
|
break;
|
||||||
|
case "AI_SUBSCRIPTION_ENABLED":
|
||||||
|
case 61:
|
||||||
|
m.capabilities[i] = 61;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6993,6 +6997,7 @@ export const proto = $root.proto = (() => {
|
|||||||
values[valuesById[58] = "JSON_PATCH_STREAMING"] = 58;
|
values[valuesById[58] = "JSON_PATCH_STREAMING"] = 58;
|
||||||
values[valuesById[59] = "AI_TAB_FORCE_CLIPPY"] = 59;
|
values[valuesById[59] = "AI_TAB_FORCE_CLIPPY"] = 59;
|
||||||
values[valuesById[60] = "UNIFIED_RESPONSE_EMBEDDED_SCREENS"] = 60;
|
values[valuesById[60] = "UNIFIED_RESPONSE_EMBEDDED_SCREENS"] = 60;
|
||||||
|
values[valuesById[61] = "AI_SUBSCRIPTION_ENABLED"] = 61;
|
||||||
return values;
|
return values;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":[2,3000,1035406580]}
|
{"version":[2,3000,1035504971]}
|
||||||
|
|||||||
@@ -123,11 +123,11 @@ export const makeNewsletterSocket = (config: SocketConfig) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
newsletterMute: (jid: string) => {
|
newsletterMute: (jid: string) => {
|
||||||
return executeWMexQuery({ newsletter_id: jid }, QueryIds.MUTE, XWAPaths.xwa2_newsletter_mute_v2)
|
return executeWMexQuery({ input: { newsletter_id: jid, type: 'MUTE_ADMIN_ACTIVITY', value: 'OFF' } }, QueryIds.MUTE, XWAPaths.xwa2_newsletter_mute_v2)
|
||||||
},
|
},
|
||||||
|
|
||||||
newsletterUnmute: (jid: string) => {
|
newsletterUnmute: (jid: string) => {
|
||||||
return executeWMexQuery({ newsletter_id: jid }, QueryIds.UNMUTE, XWAPaths.xwa2_newsletter_unmute_v2)
|
return executeWMexQuery({ input: { newsletter_id: jid, type: 'MUTE_ADMIN_ACTIVITY', value: 'ON' } }, QueryIds.UNMUTE, XWAPaths.xwa2_newsletter_unmute_v2)
|
||||||
},
|
},
|
||||||
|
|
||||||
newsletterUpdateName: async (jid: string, name: string) => {
|
newsletterUpdateName: async (jid: string, name: string) => {
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ export type BaileysEventMap = {
|
|||||||
chats: Chat[]
|
chats: Chat[]
|
||||||
contacts: Contact[]
|
contacts: Contact[]
|
||||||
messages: WAMessage[]
|
messages: WAMessage[]
|
||||||
|
/** Past participants for group chats (people who left/were removed). userJid is always a phone number (PN), never a LID. */
|
||||||
|
pastParticipants?: proto.IPastParticipants[] | null
|
||||||
isLatest?: boolean
|
isLatest?: boolean
|
||||||
progress?: number | null
|
progress?: number | null
|
||||||
syncType?: proto.HistorySync.HistorySyncType | null
|
syncType?: proto.HistorySync.HistorySyncType | null
|
||||||
@@ -185,6 +187,8 @@ export type BufferedEventData = {
|
|||||||
chats: { [jid: string]: Chat }
|
chats: { [jid: string]: Chat }
|
||||||
contacts: { [jid: string]: Contact }
|
contacts: { [jid: string]: Contact }
|
||||||
messages: { [uqId: string]: WAMessage }
|
messages: { [uqId: string]: WAMessage }
|
||||||
|
/** Keyed by groupJid for O(1) deduplication across chunks */
|
||||||
|
pastParticipants: { [groupJid: string]: proto.IPastParticipant[] }
|
||||||
empty: boolean
|
empty: boolean
|
||||||
isLatest: boolean
|
isLatest: boolean
|
||||||
progress?: number | null
|
progress?: number | null
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ export enum XWAPaths {
|
|||||||
xwa2_newsletter_view = 'xwa2_newsletter_view',
|
xwa2_newsletter_view = 'xwa2_newsletter_view',
|
||||||
xwa2_newsletter_metadata = 'xwa2_newsletter',
|
xwa2_newsletter_metadata = 'xwa2_newsletter',
|
||||||
xwa2_newsletter_admin_count = 'xwa2_newsletter_admin',
|
xwa2_newsletter_admin_count = 'xwa2_newsletter_admin',
|
||||||
xwa2_newsletter_mute_v2 = 'xwa2_newsletter_mute_v2',
|
xwa2_newsletter_mute_v2 = 'xwa2_newsletter_update_user_setting',
|
||||||
xwa2_newsletter_unmute_v2 = 'xwa2_newsletter_unmute_v2',
|
xwa2_newsletter_unmute_v2 = 'xwa2_newsletter_update_user_setting',
|
||||||
xwa2_newsletter_follow = 'xwa2_newsletter_follow',
|
xwa2_newsletter_follow = 'xwa2_newsletter_join_v2',
|
||||||
xwa2_newsletter_unfollow = 'xwa2_newsletter_unfollow',
|
xwa2_newsletter_unfollow = 'xwa2_newsletter_leave_v2',
|
||||||
xwa2_newsletter_change_owner = 'xwa2_newsletter_change_owner',
|
xwa2_newsletter_change_owner = 'xwa2_newsletter_change_owner',
|
||||||
xwa2_newsletter_demote = 'xwa2_newsletter_demote',
|
xwa2_newsletter_demote = 'xwa2_newsletter_demote',
|
||||||
xwa2_newsletter_delete_v2 = 'xwa2_newsletter_delete_v2'
|
xwa2_newsletter_delete_v2 = 'xwa2_newsletter_delete_v2'
|
||||||
@@ -17,10 +17,10 @@ export enum QueryIds {
|
|||||||
UPDATE_METADATA = '24250201037901610',
|
UPDATE_METADATA = '24250201037901610',
|
||||||
METADATA = '6563316087068696',
|
METADATA = '6563316087068696',
|
||||||
SUBSCRIBERS = '9783111038412085',
|
SUBSCRIBERS = '9783111038412085',
|
||||||
FOLLOW = '7871414976211147',
|
FOLLOW = '24404358912487870',
|
||||||
UNFOLLOW = '7238632346214362',
|
UNFOLLOW = '9767147403369991',
|
||||||
MUTE = '29766401636284406',
|
MUTE = '31938993655691868',
|
||||||
UNMUTE = '9864994326891137',
|
UNMUTE = '31938993655691868',
|
||||||
ADMIN_COUNT = '7130823597031706',
|
ADMIN_COUNT = '7130823597031706',
|
||||||
CHANGE_OWNER = '7341777602580933',
|
CHANGE_OWNER = '7341777602580933',
|
||||||
DEMOTE = '6551828931592903',
|
DEMOTE = '6551828931592903',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import EventEmitter from 'events'
|
import EventEmitter from 'events'
|
||||||
|
import { proto } from '../../WAProto/index.js'
|
||||||
import type {
|
import type {
|
||||||
BaileysEvent,
|
BaileysEvent,
|
||||||
BaileysEventEmitter,
|
BaileysEventEmitter,
|
||||||
@@ -890,6 +891,7 @@ const makeBufferData = (): BufferedEventData => {
|
|||||||
chats: {},
|
chats: {},
|
||||||
messages: {},
|
messages: {},
|
||||||
contacts: {},
|
contacts: {},
|
||||||
|
pastParticipants: {},
|
||||||
isLatest: false,
|
isLatest: false,
|
||||||
empty: true
|
empty: true
|
||||||
},
|
},
|
||||||
@@ -967,6 +969,28 @@ function append<E extends BufferableEvent>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge pastParticipants with deduplication by groupJid and by userJid within each group.
|
||||||
|
// Multiple HistorySync chunks can carry the same group -- we merge rather than concatenate
|
||||||
|
// to avoid duplicate entries in the final event delivered to the consumer.
|
||||||
|
for (const group of (eventData.pastParticipants ?? []) as proto.IPastParticipants[]) {
|
||||||
|
const groupJid = group.groupJid
|
||||||
|
if (!groupJid) continue
|
||||||
|
|
||||||
|
if (!data.historySets.pastParticipants[groupJid]) {
|
||||||
|
data.historySets.pastParticipants[groupJid] = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = data.historySets.pastParticipants[groupJid]
|
||||||
|
const seenJids = new Set(existing.map(p => p.userJid).filter(Boolean))
|
||||||
|
|
||||||
|
for (const participant of (group.pastParticipants ?? []) as proto.IPastParticipant[]) {
|
||||||
|
if (participant.userJid && !seenJids.has(participant.userJid)) {
|
||||||
|
existing.push(participant)
|
||||||
|
seenJids.add(participant.userJid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data.historySets.empty = false
|
data.historySets.empty = false
|
||||||
data.historySets.syncType = eventData.syncType
|
data.historySets.syncType = eventData.syncType
|
||||||
data.historySets.progress = eventData.progress
|
data.historySets.progress = eventData.progress
|
||||||
@@ -1292,6 +1316,10 @@ function consolidateEvents(data: BufferedEventData) {
|
|||||||
chats: Object.values(data.historySets.chats),
|
chats: Object.values(data.historySets.chats),
|
||||||
messages: Object.values(data.historySets.messages),
|
messages: Object.values(data.historySets.messages),
|
||||||
contacts: Object.values(data.historySets.contacts),
|
contacts: Object.values(data.historySets.contacts),
|
||||||
|
// Convert dedup map back to array. Each entry has groupJid + participants (all unique userJids).
|
||||||
|
pastParticipants: Object.entries(data.historySets.pastParticipants).map(
|
||||||
|
([groupJid, participants]) => ({ groupJid, pastParticipants: participants })
|
||||||
|
),
|
||||||
syncType: data.historySets.syncType,
|
syncType: data.historySets.syncType,
|
||||||
progress: data.historySets.progress,
|
progress: data.historySets.progress,
|
||||||
isLatest: data.historySets.isLatest,
|
isLatest: data.historySets.isLatest,
|
||||||
|
|||||||
@@ -374,10 +374,25 @@ export const processHistoryMessage = (item: proto.IHistorySync, logger?: ILogger
|
|||||||
// Convert Map back to array for return
|
// Convert Map back to array for return
|
||||||
const lidPnMappings = Array.from(lidPnMap.values())
|
const lidPnMappings = Array.from(lidPnMap.values())
|
||||||
|
|
||||||
|
// Normalize pastParticipants: resolve LID userJids → PN so the consumer always
|
||||||
|
// receives a phone number, never an opaque LID identifier.
|
||||||
|
// Uses the lidPnMap built above (populated from phoneNumberToLidMappings + conversations).
|
||||||
|
// If a LID cannot be resolved, the original value is kept rather than dropping the participant.
|
||||||
|
const pastParticipants: proto.IPastParticipants[] = (item.pastParticipants ?? []).map(group => ({
|
||||||
|
groupJid: group.groupJid,
|
||||||
|
pastParticipants: (group.pastParticipants ?? []).map(participant => {
|
||||||
|
const userJid = participant.userJid
|
||||||
|
if (!userJid || !isAnyLidUser(userJid)) return participant
|
||||||
|
const mapping = lidPnMap.get(jidNormalizedUser(userJid))
|
||||||
|
return mapping?.pn ? { ...participant, userJid: mapping.pn } : participant
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chats,
|
chats,
|
||||||
contacts,
|
contacts,
|
||||||
messages,
|
messages,
|
||||||
|
pastParticipants,
|
||||||
lidPnMappings,
|
lidPnMappings,
|
||||||
syncType: item.syncType,
|
syncType: item.syncType,
|
||||||
progress: item.progress
|
progress: item.progress
|
||||||
|
|||||||
Reference in New Issue
Block a user