From 0af6c2f298de14aa96db490cefa6048588d6f2a5 Mon Sep 17 00:00:00 2001 From: Rajeh Taher Date: Thu, 2 Oct 2025 19:38:47 +0300 Subject: [PATCH] general: preliminary support for @hosted + Usync LID stuff --- src/Socket/messages-send.ts | 10 ++++++---- src/Utils/decode-wa-message.ts | 2 +- src/Utils/signal.ts | 8 +++++--- src/WABinary/jid-utils.ts | 10 ++++++---- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 7f3d81f6..8ab751a0 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -39,6 +39,7 @@ import { areJidsSameUser, type BinaryNode, type BinaryNodeAttributes, + type FullJid, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, @@ -281,7 +282,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { } } - const query = new USyncQuery().withContext('message').withDeviceProtocol() + const query = new USyncQuery().withContext('message').withDeviceProtocol().withLIDProtocol() for (const jid of toFetch) { query.withUser(new USyncUser().withId(jid)) // todo: investigate - the idea here is that should have an inline lid field with the lid being the pn equivalent @@ -290,8 +291,9 @@ export const makeMessagesSocket = (config: SocketConfig) => { const result = await sock.executeUSyncQuery(query) if (result) { + // TODO: LID MAP this stuff (lid protocol will now return lid with devices) const extracted = extractDeviceJids(result?.list, authState.creds.me!.id, ignoreZeroDevices) - const deviceMap: { [_: string]: JidWithDevice[] } = {} + const deviceMap: { [_: string]: FullJid[] } = {} for (const item of extracted) { deviceMap[item.user] = deviceMap[item.user] || [] @@ -305,8 +307,8 @@ export const makeMessagesSocket = (config: SocketConfig) => { // Process all devices for this user for (const item of userDevices) { const finalJid = isLidUser - ? jidEncode(user, 'lid', item.device) - : jidEncode(item.user, 's.whatsapp.net', item.device) + ? jidEncode(user, item.server == 'hosted' ? 'hosted.lid' : 'lid', item.device) + : jidEncode(item.user, item.server == 'hosted' ? 'hosted' :'s.whatsapp.net', item.device) deviceResults.push({ ...item, diff --git a/src/Utils/decode-wa-message.ts b/src/Utils/decode-wa-message.ts index aa6ebf12..0f1c5fd3 100644 --- a/src/Utils/decode-wa-message.ts +++ b/src/Utils/decode-wa-message.ts @@ -121,7 +121,7 @@ export function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: strin let msgType: MessageType let chatId: string let author: string - let fromMe: boolean = false + let fromMe = false const msgId = stanza.attrs.id const from = stanza.attrs.from diff --git a/src/Utils/signal.ts b/src/Utils/signal.ts index aadb1e4f..ed758bd5 100644 --- a/src/Utils/signal.ts +++ b/src/Utils/signal.ts @@ -11,6 +11,7 @@ import type { import { assertNodeErrorFree, type BinaryNode, + type FullJid, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildren, @@ -134,20 +135,21 @@ export const parseAndInjectE2ESessions = async (node: BinaryNode, repository: Si export const extractDeviceJids = (result: USyncQueryResultList[], myJid: string, excludeZeroDevices: boolean) => { const { user: myUser, device: myDevice } = jidDecode(myJid)! - const extracted: JidWithDevice[] = [] + const extracted: FullJid[] = [] for (const userResult of result) { + // TODO: ADD SUPPORT FOR HOSTED JIDS const { devices, id } = userResult as { devices: ParsedDeviceInfo; id: string } const { user } = jidDecode(id)! const deviceList = devices?.deviceList as DeviceListData[] if (Array.isArray(deviceList)) { - for (const { id: device, keyIndex } of deviceList) { + for (const { id: device, keyIndex, isHosted } of deviceList) { if ( (!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero (myUser !== user || myDevice !== device) && // either different user or if me user, not this device (device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise ) { - extracted.push({ user, device }) + extracted.push({ user, device, server: isHosted ? 'hosted' : 's.whatsapp.net' }) } } } diff --git a/src/WABinary/jid-utils.ts b/src/WABinary/jid-utils.ts index 74e61cb2..bd10f828 100644 --- a/src/WABinary/jid-utils.ts +++ b/src/WABinary/jid-utils.ts @@ -5,7 +5,7 @@ export const PSA_WID = '0@c.us' export const STORIES_JID = 'status@broadcast' export const META_AI_JID = '13135550002@c.us' -export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' | 'lid' | 'newsletter' | 'bot' +export type JidServer = 'c.us' | 'g.us' | 'broadcast' | 's.whatsapp.net' | 'call' | 'lid' | 'newsletter' | 'bot' | 'hosted' | 'hosted.lid' export type JidWithDevice = { user: string @@ -14,11 +14,10 @@ export type JidWithDevice = { export type FullJid = JidWithDevice & { server: JidServer - domainType?: number } export const jidEncode = (user: string | number | null, server: JidServer, device?: number, agent?: number) => { - return `${user || ''}${!!agent ? `_${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` + return `${user || ''}${!!agent ? `.${agent}` : ''}${!!device ? `:${device}` : ''}@${server}` } export const jidDecode = (jid: string | undefined): FullJid | undefined => { @@ -36,7 +35,6 @@ export const jidDecode = (jid: string | undefined): FullJid | undefined => { return { server: server as JidServer, user, - domainType: server === 'lid' ? 1 : 0, device: device ? +device : undefined } } @@ -58,6 +56,10 @@ export const isJidGroup = (jid: string | undefined) => jid?.endsWith('@g.us') export const isJidStatusBroadcast = (jid: string) => jid === 'status@broadcast' /** is the jid a newsletter */ export const isJidNewsletter = (jid: string | undefined) => jid?.endsWith('@newsletter') +/** is the jid a hosted PN */ +export const isJidHostedPnUser = (jid: string | undefined) => jid?.endsWith('@hosted') +/** is the jid a hosted LID */ +export const isJidHostedLidUser = (jid: string | undefined) => jid?.endsWith('@hosted.lid') const botRegexp = /^1313555\d{4}$|^131655500\d{2}$/