fix: cannot send message on new Whatsapp Business limited accounts (#2080)
* fix: cannot send message on new Whatsapp Business limited accounts * chore: add woraround to resend the message on 475 errors * fix: lint * fix: add handler * fix: lint * Update src/Socket/messages-send.ts --------- Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
This commit is contained in:
@@ -41,7 +41,7 @@ export const PROCESSABLE_HISTORY_TYPES = [
|
||||
proto.HistorySync.HistorySyncType.FULL,
|
||||
proto.HistorySync.HistorySyncType.ON_DEMAND,
|
||||
proto.HistorySync.HistorySyncType.NON_BLOCKING_DATA,
|
||||
proto.HistorySync.HistorySyncType.INITIAL_STATUS_V3,
|
||||
proto.HistorySync.HistorySyncType.INITIAL_STATUS_V3
|
||||
]
|
||||
|
||||
export const DEFAULT_CONNECTION_CONFIG: SocketConfig = {
|
||||
|
||||
+2
-1
@@ -1037,7 +1037,8 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
||||
|
||||
const historyMsg = getHistoryMsg(msg.message!)
|
||||
const shouldProcessHistoryMsg = historyMsg
|
||||
? shouldSyncHistoryMessage(historyMsg) && PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType! as proto.HistorySync.HistorySyncType)
|
||||
? shouldSyncHistoryMessage(historyMsg) &&
|
||||
PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType! as proto.HistorySync.HistorySyncType)
|
||||
: false
|
||||
|
||||
// State machine: decide on sync and flush
|
||||
|
||||
@@ -872,6 +872,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
})
|
||||
authState.creds.registered = true
|
||||
ev.emit('creds.update', authState.creds)
|
||||
break
|
||||
case 'privacy_token':
|
||||
await handlePrivacyTokenNotification(node)
|
||||
break
|
||||
}
|
||||
|
||||
if (Object.keys(result).length) {
|
||||
@@ -879,6 +883,36 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handlePrivacyTokenNotification = async (node: BinaryNode) => {
|
||||
const tokensNode = getBinaryNodeChild(node, 'tokens')
|
||||
const from = jidNormalizedUser(node.attrs.from)
|
||||
|
||||
if (!tokensNode) return
|
||||
|
||||
const tokenNodes = getBinaryNodeChildren(tokensNode, 'token')
|
||||
|
||||
for (const tokenNode of tokenNodes) {
|
||||
const { attrs, content } = tokenNode
|
||||
const type = attrs.type
|
||||
const timestamp = attrs.t
|
||||
|
||||
if (type === 'trusted_contact' && content instanceof Buffer) {
|
||||
logger.debug(
|
||||
{
|
||||
from,
|
||||
timestamp,
|
||||
tcToken: content
|
||||
},
|
||||
'received trusted contact token'
|
||||
)
|
||||
|
||||
await authState.keys.set({
|
||||
'contacts-tc-token': { [from]: { token: content, timestamp } }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function decipherLinkPublicKey(data: Uint8Array | Buffer) {
|
||||
const buffer = toRequiredBuffer(data)
|
||||
const salt = buffer.slice(0, 32)
|
||||
@@ -1369,6 +1403,20 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
// resend the message with device_fanout=false, use at your own risk
|
||||
// if (attrs.error === '475') {
|
||||
// const msg = await getMessage(key)
|
||||
// if (msg) {
|
||||
// await relayMessage(key.remoteJid!, msg, {
|
||||
// messageId: key.id!,
|
||||
// useUserDevicesCache: false,
|
||||
// additionalAttributes: {
|
||||
// device_fanout: 'false'
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -929,6 +929,19 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
logger.debug({ jid }, 'adding device identity')
|
||||
}
|
||||
|
||||
const contactTcTokenData =
|
||||
!isGroup && !isRetryResend && !isStatus ? await authState.keys.get('contacts-tc-token', [destinationJid]) : {}
|
||||
|
||||
const tcTokenBuffer = contactTcTokenData[destinationJid]?.token
|
||||
|
||||
if (tcTokenBuffer) {
|
||||
(stanza.content as BinaryNode[]).push({
|
||||
tag: 'tctoken',
|
||||
attrs: {},
|
||||
content: tcTokenBuffer
|
||||
})
|
||||
}
|
||||
|
||||
if (additionalNodes && additionalNodes.length > 0) {
|
||||
;(stanza.content as BinaryNode[]).push(...additionalNodes)
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ export type SignalDataTypeMap = {
|
||||
'app-state-sync-version': LTHashState
|
||||
'lid-mapping': string
|
||||
'device-list': string[]
|
||||
'contacts-tc-token': { token: Buffer; timestamp?: string }
|
||||
}
|
||||
|
||||
export type SignalDataSet = { [T in keyof SignalDataTypeMap]?: { [id: string]: SignalDataTypeMap[T] | null } }
|
||||
|
||||
@@ -75,7 +75,7 @@ export function makeCacheableSignalKeyStore(
|
||||
const item = fetched[id]
|
||||
if (item) {
|
||||
data[id] = item
|
||||
cache.set(getUniqueId(type, id), item)
|
||||
cache.set(getUniqueId(type, id), item as SignalDataTypeMap[keyof SignalDataTypeMap])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ export const downloadAndProcessHistorySyncNotification = async (
|
||||
} else {
|
||||
historyMsg = await downloadHistory(msg, options)
|
||||
}
|
||||
|
||||
return processHistoryMessage(historyMsg)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user