fix: revert ?? '' and defensive null checks across Socket files
PRs 124-129 replaced TypeScript non-null assertions (!) with optional chaining (?.) and empty string defaults (?? ''). While defensive programming is usually good, in Signal protocol and WhatsApp binary node handling code these changes caused: - Malformed JIDs with empty user components (e.g. @s.whatsapp.net) - Silent device enumeration failures (messages skip recipients) - Wrong own-device detection (message routing errors) - Broken prekey count handling (prekey uploads silently skipped) - Wrong retry count tracking in Signal protocol These empty-string defaults are dangerous because Signal session lookups fail for malformed JIDs, causing "SessionError: No sessions". Reverted to original Baileys pattern using non-null assertions (!) which match the upstream reference (infinitezap/Teste_InfiniteAPI). Files fixed: messages-send.ts, messages-recv.ts, socket.ts, chats.ts, groups.ts, communities.ts, business.ts https://claude.ai/code/session_01XaA7GwNaB6azTHFYQ8WEpB
This commit is contained in:
@@ -118,7 +118,7 @@ export const makeBusinessSocket = (config: SocketConfig) => {
|
||||
content: [
|
||||
{
|
||||
tag: 'cover_photo',
|
||||
attrs: { id: String(fbid), op: 'update', token: meta_hmac ?? '', ts: String(ts) }
|
||||
attrs: { id: String(fbid), op: 'update', token: meta_hmac!, ts: String(ts) }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+2
-2
@@ -1107,8 +1107,8 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
||||
ev.emit('messages.upsert', { messages: [msg], type })
|
||||
|
||||
if (!!msg.pushName) {
|
||||
let jid = msg.key.fromMe ? (authState.creds.me?.id ?? '') : msg.key.participant || msg.key.remoteJid
|
||||
jid = jidNormalizedUser(jid ?? '')
|
||||
let jid = msg.key.fromMe ? authState.creds.me!.id : msg.key.participant || msg.key.remoteJid
|
||||
jid = jidNormalizedUser(jid!)
|
||||
|
||||
if (!msg.key.fromMe) {
|
||||
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName! }])
|
||||
|
||||
@@ -358,13 +358,13 @@ export const makeCommunitiesSocket = (config: SocketConfig) => {
|
||||
communityAcceptInviteV4: ev.createBufferedFunction(
|
||||
async (key: string | WAMessageKey, inviteMessage: proto.Message.IGroupInviteMessage) => {
|
||||
key = typeof key === 'string' ? { remoteJid: key } : key
|
||||
const results = await communityQuery(inviteMessage.groupJid ?? '', 'set', [
|
||||
const results = await communityQuery(inviteMessage.groupJid!, 'set', [
|
||||
{
|
||||
tag: 'accept',
|
||||
attrs: {
|
||||
code: inviteMessage.inviteCode ?? '',
|
||||
code: inviteMessage.inviteCode!,
|
||||
expiration: (inviteMessage.inviteExpiration ?? 0).toString(),
|
||||
admin: key.remoteJid ?? ''
|
||||
admin: key.remoteJid!
|
||||
}
|
||||
}
|
||||
])
|
||||
@@ -475,7 +475,7 @@ export const extractCommunityMetadata = (result: BinaryNode) => {
|
||||
participants: getBinaryNodeChildren(community, 'participant').map(({ attrs }) => {
|
||||
return {
|
||||
// TODO: IMPLEMENT THE PN/LID FIELDS HERE!!
|
||||
id: attrs.jid ?? '',
|
||||
id: attrs.jid!,
|
||||
admin: (attrs.type || null) as GroupParticipant['admin']
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -225,12 +225,12 @@ export const makeGroupsSocket = (config: SocketConfig) => {
|
||||
groupAcceptInviteV4: ev.createBufferedFunction(
|
||||
async (key: string | WAMessageKey, inviteMessage: proto.Message.IGroupInviteMessage) => {
|
||||
key = typeof key === 'string' ? { remoteJid: key } : key
|
||||
const results = await groupQuery(inviteMessage.groupJid ?? '', 'set', [
|
||||
const results = await groupQuery(inviteMessage.groupJid!, 'set', [
|
||||
{
|
||||
tag: 'accept',
|
||||
attrs: {
|
||||
code: inviteMessage.inviteCode ?? '',
|
||||
expiration: String(inviteMessage.inviteExpiration ?? ''),
|
||||
code: inviteMessage.inviteCode!,
|
||||
expiration: inviteMessage.inviteExpiration!.toString(),
|
||||
admin: key.remoteJid!
|
||||
}
|
||||
}
|
||||
@@ -316,14 +316,14 @@ export const extractGroupMetadata = (result: BinaryNode) => {
|
||||
descId = descChild.attrs.id
|
||||
}
|
||||
|
||||
const groupId = (group.attrs.id ?? '').includes('@') ? (group.attrs.id ?? '') : jidEncode(group.attrs.id ?? '', 'g.us')
|
||||
const groupId = group.attrs.id!.includes('@') ? group.attrs.id! : jidEncode(group.attrs.id!, 'g.us')
|
||||
const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration
|
||||
const memberAddMode = getBinaryNodeChildString(group, 'member_add_mode') === 'all_member_add'
|
||||
const metadata: GroupMetadata = {
|
||||
id: groupId,
|
||||
notify: group.attrs.notify,
|
||||
addressingMode: group.attrs.addressing_mode === 'lid' ? WAMessageAddressingMode.LID : WAMessageAddressingMode.PN,
|
||||
subject: group.attrs.subject ?? '',
|
||||
subject: group.attrs.subject!,
|
||||
subjectOwner: group.attrs.s_o,
|
||||
subjectOwnerPn: group.attrs.s_o_pn,
|
||||
subjectTime: +(group.attrs.s_t ?? '0'),
|
||||
@@ -347,7 +347,7 @@ export const extractGroupMetadata = (result: BinaryNode) => {
|
||||
participants: getBinaryNodeChildren(group, 'participant').map(({ attrs }) => {
|
||||
// TODO: Store LID MAPPINGS
|
||||
return {
|
||||
id: attrs.jid ?? '',
|
||||
id: attrs.jid!,
|
||||
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
||||
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
||||
admin: (attrs.type || null) as GroupParticipant['admin']
|
||||
|
||||
+41
-57
@@ -156,17 +156,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
throw new Boom('Not authenticated')
|
||||
}
|
||||
|
||||
const msgId = messageKey?.id ?? ''
|
||||
if (await placeholderResendCache.get(msgId)) {
|
||||
if (await placeholderResendCache.get(messageKey?.id!)) {
|
||||
logger.debug({ messageKey }, 'already requested resend')
|
||||
return
|
||||
} else {
|
||||
await placeholderResendCache.set(msgId, true)
|
||||
await placeholderResendCache.set(messageKey?.id!, true)
|
||||
}
|
||||
|
||||
await delay(2000)
|
||||
|
||||
if (!(await placeholderResendCache.get(msgId))) {
|
||||
if (!(await placeholderResendCache.get(messageKey?.id!))) {
|
||||
logger.debug({ messageKey }, 'message received while resend requested')
|
||||
return 'RESOLVED'
|
||||
}
|
||||
@@ -181,9 +180,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
}
|
||||
|
||||
setTimeout(async () => {
|
||||
if (await placeholderResendCache.get(msgId)) {
|
||||
if (await placeholderResendCache.get(messageKey?.id!)) {
|
||||
logger.debug({ messageKey }, 'PDO message without response after 8 seconds. Phone possibly offline')
|
||||
await placeholderResendCache.del(msgId)
|
||||
await placeholderResendCache.del(messageKey?.id!)
|
||||
}
|
||||
}, 8_000)
|
||||
|
||||
@@ -234,7 +233,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
if (update.jid && update.user) {
|
||||
ev.emit('newsletter-participants.update', {
|
||||
id: update.jid,
|
||||
author: node.attrs.from ?? '',
|
||||
author: node.attrs.from!,
|
||||
user: update.user,
|
||||
new_role: 'ADMIN',
|
||||
action: 'promote'
|
||||
@@ -252,10 +251,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
|
||||
// Handles newsletter notifications
|
||||
const handleNewsletterNotification = async (node: BinaryNode) => {
|
||||
const from = node.attrs.from ?? ''
|
||||
const child = getAllBinaryNodeChildren(node)[0]
|
||||
if (!child) return
|
||||
const author = node.attrs.participant ?? ''
|
||||
const from = node.attrs.from!
|
||||
const child = getAllBinaryNodeChildren(node)[0]!
|
||||
const author = node.attrs.participant!
|
||||
|
||||
logger.info({ from, child }, 'got newsletter notification')
|
||||
|
||||
@@ -263,7 +261,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
case 'reaction':
|
||||
const reactionUpdate = {
|
||||
id: from,
|
||||
server_id: child.attrs.message_id ?? '',
|
||||
server_id: child.attrs.message_id!,
|
||||
reaction: {
|
||||
code: getBinaryNodeChildString(child, 'reaction'),
|
||||
count: 1
|
||||
@@ -275,7 +273,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
case 'view':
|
||||
const viewUpdate = {
|
||||
id: from,
|
||||
server_id: child.attrs.message_id ?? '',
|
||||
server_id: child.attrs.message_id!,
|
||||
count: parseInt(child.content?.toString() || '0', 10)
|
||||
}
|
||||
ev.emit('newsletter.view', viewUpdate)
|
||||
@@ -285,9 +283,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const participantUpdate = {
|
||||
id: from,
|
||||
author,
|
||||
user: child.attrs.jid ?? '',
|
||||
action: child.attrs.action ?? '',
|
||||
new_role: child.attrs.role ?? ''
|
||||
user: child.attrs.jid!,
|
||||
action: child.attrs.action!,
|
||||
new_role: child.attrs.role!
|
||||
}
|
||||
ev.emit('newsletter-participants.update', participantUpdate)
|
||||
break
|
||||
@@ -347,8 +345,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const stanza: BinaryNode = {
|
||||
tag: 'ack',
|
||||
attrs: {
|
||||
id: attrs.id ?? '',
|
||||
to: attrs.from ?? '',
|
||||
id: attrs.id!,
|
||||
to: attrs.from!,
|
||||
class: tag
|
||||
}
|
||||
}
|
||||
@@ -407,16 +405,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
}
|
||||
|
||||
const sendRetryRequest = async (node: BinaryNode, forceIncludeKeys = false) => {
|
||||
const meId = authState.creds.me?.id
|
||||
if (!meId) throw new Boom('Not authenticated', { statusCode: 401 })
|
||||
const meLid = authState.creds.me?.lid || ''
|
||||
const { fullMessage } = decodeMessageNode(node, meId, meLid)
|
||||
const { fullMessage } = decodeMessageNode(node, authState.creds.me!.id, authState.creds.me!.lid || '')
|
||||
const { key: msgKey } = fullMessage
|
||||
const msgId = msgKey.id
|
||||
if (!msgId) {
|
||||
logger.debug({ node }, 'missing message id in retry request')
|
||||
return
|
||||
}
|
||||
const msgId = msgKey.id!
|
||||
|
||||
if (messageRetryManager) {
|
||||
// Check if we've exceeded max retries using the new system
|
||||
@@ -454,7 +445,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const retryCount = (await msgRetryCache.get<number>(key)) || 1
|
||||
|
||||
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds
|
||||
const fromJid = node.attrs.from ?? ''
|
||||
const fromJid = node.attrs.from!
|
||||
|
||||
// Check if we should recreate the session
|
||||
let shouldRecreateSession = false
|
||||
@@ -519,15 +510,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
attrs: {
|
||||
id: msgId,
|
||||
type: 'retry',
|
||||
to: node.attrs.from ?? ''
|
||||
to: node.attrs.from!
|
||||
},
|
||||
content: [
|
||||
{
|
||||
tag: 'retry',
|
||||
attrs: {
|
||||
count: retryCount.toString(),
|
||||
id: node.attrs.id ?? '',
|
||||
t: node.attrs.t ?? '',
|
||||
id: node.attrs.id!,
|
||||
t: node.attrs.t!,
|
||||
v: '1',
|
||||
// ADD ERROR FIELD
|
||||
error: '0'
|
||||
@@ -553,19 +544,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const { update, preKeys } = await getNextPreKeys(authState, 1)
|
||||
|
||||
const [keyId] = Object.keys(preKeys)
|
||||
if (!keyId) throw new Boom('No pre-keys available')
|
||||
const key = preKeys[+keyId]
|
||||
if (!key) throw new Boom('Pre-key not found')
|
||||
const key = preKeys[+keyId!]
|
||||
|
||||
const content = receipt.content as BinaryNode[]
|
||||
if (!content) throw new Boom('Receipt content missing')
|
||||
const content = receipt.content! as BinaryNode[]
|
||||
content.push({
|
||||
tag: 'keys',
|
||||
attrs: {},
|
||||
content: [
|
||||
{ tag: 'type', attrs: {}, content: Buffer.from(KEY_BUNDLE_TYPE) },
|
||||
{ tag: 'identity', attrs: {}, content: identityKey.public },
|
||||
xmppPreKey(key, +keyId),
|
||||
xmppPreKey(key!, +keyId!),
|
||||
xmppSignedPreKey(signedPreKey),
|
||||
{ tag: 'device-identity', attrs: {}, content: deviceIdentity }
|
||||
]
|
||||
@@ -584,9 +572,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const from = node.attrs.from
|
||||
if (from === S_WHATSAPP_NET) {
|
||||
const countChild = getBinaryNodeChild(node, 'count')
|
||||
const countVal = countChild?.attrs?.value
|
||||
if (!countVal) return
|
||||
const count = +countVal
|
||||
const count = +countChild!.attrs.value!
|
||||
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT
|
||||
|
||||
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count')
|
||||
@@ -651,7 +637,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
}
|
||||
break
|
||||
case 'modify':
|
||||
const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid ?? '').filter(Boolean)
|
||||
const oldNumber = getBinaryNodeChildren(child, 'participant').map(p => p.attrs.jid!)
|
||||
msg.messageStubParameters = oldNumber || []
|
||||
msg.messageStubType = WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER
|
||||
break
|
||||
@@ -666,7 +652,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const participants = getBinaryNodeChildren(child, 'participant').map(({ attrs }) => {
|
||||
// TODO: Store LID MAPPINGS
|
||||
return {
|
||||
id: attrs.jid ?? '',
|
||||
id: attrs.jid!,
|
||||
phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
|
||||
lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
|
||||
admin: (attrs.type || null) as GroupParticipant['admin']
|
||||
@@ -688,7 +674,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
break
|
||||
case 'subject':
|
||||
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_SUBJECT
|
||||
msg.messageStubParameters = [child.attrs.subject ?? '']
|
||||
msg.messageStubParameters = [child.attrs.subject!]
|
||||
break
|
||||
case 'description':
|
||||
const description = getBinaryNodeChild(child, 'body')?.content?.toString()
|
||||
@@ -707,7 +693,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
break
|
||||
case 'invite':
|
||||
msg.messageStubType = WAMessageStubType.GROUP_CHANGE_INVITE_LINK
|
||||
msg.messageStubParameters = [child.attrs.code ?? '']
|
||||
msg.messageStubParameters = [child.attrs.code!]
|
||||
break
|
||||
case 'member_add_mode':
|
||||
const addMode = child.content
|
||||
@@ -721,7 +707,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const approvalMode = getBinaryNodeChild(child, 'group_join')
|
||||
if (approvalMode) {
|
||||
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE
|
||||
msg.messageStubParameters = [approvalMode.attrs.state ?? '']
|
||||
msg.messageStubParameters = [approvalMode.attrs.state!]
|
||||
}
|
||||
|
||||
break
|
||||
@@ -730,7 +716,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
msg.messageStubParameters = [
|
||||
JSON.stringify({ lid: affectedParticipantLid, pn: affectedParticipantPn }),
|
||||
'created',
|
||||
child.attrs.request_method ?? ''
|
||||
child.attrs.request_method!
|
||||
]
|
||||
break
|
||||
case 'revoked_membership_requests':
|
||||
@@ -760,8 +746,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
break
|
||||
case 'w:gp2':
|
||||
// TODO: HANDLE PARTICIPANT_PN
|
||||
if (!child) break
|
||||
handleGroupNotification(node, child, result)
|
||||
handleGroupNotification(node, child!, result)
|
||||
break
|
||||
case 'mediaretry':
|
||||
const event = decodeMediaRetryNode(node)
|
||||
@@ -771,11 +756,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
await handleEncryptNotification(node)
|
||||
break
|
||||
case 'devices':
|
||||
if (!child) break
|
||||
const devices = getBinaryNodeChildren(child, 'device')
|
||||
if (
|
||||
areJidsSameUser(child.attrs.jid, authState.creds.me?.id) ||
|
||||
areJidsSameUser(child.attrs.lid, authState.creds.me?.lid)
|
||||
areJidsSameUser(child!.attrs.jid, authState.creds.me!.id) ||
|
||||
areJidsSameUser(child!.attrs.lid, authState.creds.me!.lid)
|
||||
) {
|
||||
const deviceData = devices.map(d => ({ id: d.attrs.jid, lid: d.attrs.lid }))
|
||||
logger.info({ deviceData }, 'my own devices changed')
|
||||
@@ -840,7 +824,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
const blocklists = getBinaryNodeChildren(child, 'item')
|
||||
|
||||
for (const { attrs } of blocklists) {
|
||||
const blocklist = [attrs.jid ?? '']
|
||||
const blocklist = [attrs.jid!]
|
||||
const type = attrs.action === 'block' ? 'add' : 'remove'
|
||||
ev.emit('blocklist.update', { blocklist, type })
|
||||
}
|
||||
@@ -890,7 +874,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
{
|
||||
tag: 'link_code_companion_reg',
|
||||
attrs: {
|
||||
jid: authState.creds.me?.id ?? '',
|
||||
jid: authState.creds.me!.id,
|
||||
stage: 'companion_finish'
|
||||
},
|
||||
content: [
|
||||
@@ -1092,7 +1076,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
|
||||
const handleReceipt = async (node: BinaryNode) => {
|
||||
const { attrs, content } = node
|
||||
const isLid = (attrs.from ?? '').includes('lid')
|
||||
const isLid = attrs.from!.includes('lid')
|
||||
const isNodeFromMe = areJidsSameUser(
|
||||
attrs.participant || attrs.from,
|
||||
isLid ? authState.creds.me?.lid : authState.creds.me?.id
|
||||
@@ -1198,7 +1182,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
notificationMutex.mutex(async () => {
|
||||
const msg = await processNotification(node)
|
||||
if (msg) {
|
||||
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me?.id ?? '')
|
||||
const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me!.id)
|
||||
const { senderAlt: participantAlt, addressingMode } = extractAddressingContext(node)
|
||||
msg.key = {
|
||||
remoteJid,
|
||||
@@ -1242,7 +1226,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
category,
|
||||
author,
|
||||
decrypt
|
||||
} = decryptMessageNode(node, authState.creds.me?.id ?? '', authState.creds.me?.lid || '', signalRepository, logger)
|
||||
} = decryptMessageNode(node, authState.creds.me!.id, authState.creds.me!.lid || '', signalRepository, logger)
|
||||
|
||||
const alt = msg.key.participantAlt || msg.key.remoteJidAlt
|
||||
// Handle LID/PN mappings with hybrid approach:
|
||||
@@ -1527,7 +1511,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
|
||||
// JID normalization moved BEFORE mutex acquisition (line 1273) to prevent race conditions
|
||||
// cleanMessage still runs inside mutex to ensure atomic message processing
|
||||
cleanMessage(msg, authState.creds.me?.id ?? '', authState.creds.me?.lid ?? '')
|
||||
cleanMessage(msg, authState.creds.me!.id, authState.creds.me!.lid!)
|
||||
|
||||
await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify')
|
||||
|
||||
|
||||
+20
-21
@@ -131,11 +131,11 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
// TODO: explore full length of data that whatsapp provides
|
||||
const node: MediaConnInfo = {
|
||||
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(({ attrs }) => ({
|
||||
hostname: attrs.hostname ?? '',
|
||||
maxContentLengthBytes: +(attrs.maxContentLengthBytes ?? 0)
|
||||
hostname: attrs.hostname!,
|
||||
maxContentLengthBytes: +attrs.maxContentLengthBytes!
|
||||
})),
|
||||
auth: mediaConnNode.attrs.auth ?? '',
|
||||
ttl: +(mediaConnNode.attrs.ttl ?? 0),
|
||||
auth: mediaConnNode.attrs.auth!,
|
||||
ttl: +mediaConnNode.attrs.ttl!,
|
||||
fetchDate: new Date()
|
||||
}
|
||||
logger.debug('fetched media conn')
|
||||
@@ -163,7 +163,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
const node: BinaryNode = {
|
||||
tag: 'receipt',
|
||||
attrs: {
|
||||
id: messageIds[0] ?? ''
|
||||
id: messageIds[0]!
|
||||
}
|
||||
}
|
||||
const isReadReceipt = type === 'read' || type === 'read-self'
|
||||
@@ -268,11 +268,10 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
}
|
||||
|
||||
for (const { jid, user } of jidsWithUser) {
|
||||
if (!user) continue
|
||||
if (useCache) {
|
||||
const devices =
|
||||
mgetDevices?.[user] ||
|
||||
(userDevicesCache.mget ? undefined : ((await userDevicesCache.get(user)) as FullJid[]))
|
||||
mgetDevices?.[user!] ||
|
||||
(userDevicesCache.mget ? undefined : ((await userDevicesCache.get(user!)) as FullJid[]))
|
||||
if (devices) {
|
||||
const devicesWithJid = devices.map(d => ({
|
||||
...d,
|
||||
@@ -567,8 +566,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
let msgToEncrypt = patchedMessage
|
||||
|
||||
if (dsmMessage) {
|
||||
const targetUser = jidDecode(jid)?.user ?? ''
|
||||
const ownPnUser = jidDecode(meId)?.user ?? ''
|
||||
const { user: targetUser } = jidDecode(jid)!
|
||||
const { user: ownPnUser } = jidDecode(meId)!
|
||||
const ownLidUser = meLidUser
|
||||
|
||||
const isOwnUser = targetUser === ownPnUser || (ownLidUser && targetUser === ownLidUser)
|
||||
@@ -1081,7 +1080,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
logger.debug({ to: jid, ownId }, 'Using PN identity for @s.whatsapp.net conversation')
|
||||
}
|
||||
|
||||
const ownUser = jidDecode(ownId)?.user ?? ''
|
||||
const { user: ownUser } = jidDecode(ownId)!
|
||||
if (!participant) {
|
||||
const patchedForReporting = await patchMessageBeforeSending(message, [jid])
|
||||
reportingMessage = Array.isArray(patchedForReporting)
|
||||
@@ -1099,7 +1098,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
|
||||
if (user !== ownUser) {
|
||||
const ownUserServer = isLid ? 'lid' : 's.whatsapp.net'
|
||||
const ownUserForAddressing = isLid && meLid ? (jidDecode(meLid)?.user ?? '') : (jidDecode(meId)?.user ?? '')
|
||||
const ownUserForAddressing = isLid && meLid ? jidDecode(meLid)!.user : jidDecode(meId)!.user
|
||||
|
||||
devices.push({
|
||||
user: ownUserForAddressing,
|
||||
@@ -1115,8 +1114,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
// Use conversation-appropriate sender identity
|
||||
const senderIdentity =
|
||||
isLid && meLid
|
||||
? jidEncode(jidDecode(meLid)?.user ?? '', 'lid', undefined)
|
||||
: jidEncode(jidDecode(meId)?.user ?? '', 's.whatsapp.net', undefined)
|
||||
? jidEncode(jidDecode(meLid)?.user!, 'lid', undefined)
|
||||
: jidEncode(jidDecode(meId)?.user!, 's.whatsapp.net', undefined)
|
||||
|
||||
// Enumerate devices for sender and target with consistent addressing
|
||||
const sessionDevices = await getUSyncDevices([senderIdentity, jid], true, false)
|
||||
@@ -1135,8 +1134,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
const allRecipients: string[] = []
|
||||
const meRecipients: string[] = []
|
||||
const otherRecipients: string[] = []
|
||||
const mePnUser = jidDecode(meId)?.user ?? ''
|
||||
const meLidUser = meLid ? (jidDecode(meLid)?.user ?? null) : null
|
||||
const { user: mePnUser } = jidDecode(meId)!
|
||||
const { user: meLidUser } = meLid ? jidDecode(meLid)! : { user: null }
|
||||
|
||||
// Carousel in DSM wrapper causes error 479 on own devices
|
||||
const isCarouselMsg = isCarouselMessage(message)
|
||||
@@ -1212,7 +1211,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
attrs: {
|
||||
v: '2',
|
||||
type,
|
||||
count: (participant?.count ?? 0).toString()
|
||||
count: participant!.count.toString()
|
||||
},
|
||||
content: encryptedContent
|
||||
})
|
||||
@@ -1636,7 +1635,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
throw new Boom('Missing media key for update', { statusCode: 400 })
|
||||
}
|
||||
|
||||
const meId = authState.creds.me?.id ?? ''
|
||||
const meId = authState.creds.me!.id
|
||||
const node = encryptMediaRetryRequest(message.key, mediaKey, meId)
|
||||
|
||||
let error: Error | undefined = undefined
|
||||
@@ -1713,7 +1712,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
options: MiscMessageGenerationOptions = {}
|
||||
): Promise<AlbumSendResult> => {
|
||||
const startTime = Date.now()
|
||||
const userJid = authState.creds.me?.id ?? ''
|
||||
const userJid = authState.creds.me!.id
|
||||
|
||||
const {
|
||||
medias,
|
||||
@@ -1868,7 +1867,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
|
||||
// Relay the message
|
||||
await relayMessage(jid, mediaMsg.message, {
|
||||
messageId: mediaMsg.key.id ?? '',
|
||||
messageId: mediaMsg.key.id!,
|
||||
useCachedGroupMetadata: options.useCachedGroupMetadata
|
||||
})
|
||||
|
||||
@@ -1997,7 +1996,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
)
|
||||
}
|
||||
|
||||
const userJid = authState.creds.me?.id ?? ''
|
||||
const userJid = authState.creds.me!.id
|
||||
|
||||
// Special path for carousel: call relayMessage directly with plain JS object
|
||||
// This matches Pastorini's working approach:
|
||||
|
||||
+7
-23
@@ -609,12 +609,8 @@ export const makeSocket = (config: SocketConfig) => {
|
||||
},
|
||||
content: [{ tag: 'count', attrs: {} }]
|
||||
})
|
||||
const countChild = getBinaryNodeChild(result, 'count')
|
||||
if (!countChild) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return +(countChild.attrs.value ?? 0)
|
||||
const countChild = getBinaryNodeChild(result, 'count')!
|
||||
return +countChild.attrs.value!
|
||||
}
|
||||
|
||||
// Pre-key upload state management
|
||||
@@ -1364,7 +1360,7 @@ export const makeSocket = (config: SocketConfig) => {
|
||||
attrs: {
|
||||
to: S_WHATSAPP_NET,
|
||||
type: 'result',
|
||||
id: stanza.attrs.id ?? ''
|
||||
id: stanza.attrs.id!
|
||||
}
|
||||
}
|
||||
await sendNode(iq)
|
||||
@@ -1443,9 +1439,7 @@ export const makeSocket = (config: SocketConfig) => {
|
||||
logger.info('opened connection to WA')
|
||||
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
|
||||
|
||||
if (authState.creds.me) {
|
||||
ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } })
|
||||
}
|
||||
ev.emit('creds.update', { me: { ...authState.creds.me!, lid: node.attrs.lid } })
|
||||
|
||||
ev.emit('connection.update', { connection: 'open' })
|
||||
|
||||
@@ -1468,23 +1462,13 @@ export const makeSocket = (config: SocketConfig) => {
|
||||
const myLID = node.attrs.lid
|
||||
process.nextTick(async () => {
|
||||
try {
|
||||
const me = authState.creds.me
|
||||
if (!me) {
|
||||
return
|
||||
}
|
||||
|
||||
const myPN = me.id
|
||||
const myPN = authState.creds.me!.id
|
||||
|
||||
// Store our own LID-PN mapping
|
||||
await signalRepository.lidMapping.storeLIDPNMappings([{ lid: myLID, pn: myPN }])
|
||||
|
||||
// Create device list for our own user (needed for bulk migration)
|
||||
const decoded = jidDecode(myPN)
|
||||
if (!decoded) {
|
||||
return
|
||||
}
|
||||
|
||||
const { user, device } = decoded
|
||||
const { user, device } = jidDecode(myPN)!
|
||||
await authState.keys.set({
|
||||
'device-list': {
|
||||
[user]: [device?.toString() || '0']
|
||||
@@ -1572,7 +1556,7 @@ export const makeSocket = (config: SocketConfig) => {
|
||||
logger.debug({ name }, 'updated pushName')
|
||||
sendNode({
|
||||
tag: 'presence',
|
||||
attrs: { name: name ?? '' }
|
||||
attrs: { name: name! }
|
||||
}).catch(err => {
|
||||
logger.warn({ trace: err.stack }, 'error in sending presence update on name change')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user