diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 6b86337..fe7a55c 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -64,14 +64,16 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const sendRetryRequest = async(node: BinaryNode) => { const msgId = node.attrs.id - const retryCount = msgRetryMap[msgId] || 1 + + let retryCount = msgRetryMap[msgId] || 0 if(retryCount >= 5) { logger.debug({ retryCount, msgId }, 'reached retry limit, clearing') delete msgRetryMap[msgId] return } - msgRetryMap[msgId] = retryCount + 1 + retryCount += 1 + msgRetryMap[msgId] = retryCount const isGroup = !!node.attrs.participant const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds @@ -79,11 +81,6 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account!).finish() await authState.keys.transaction( async() => { - const { update, preKeys } = await getNextPreKeys(authState, 1) - - const [keyId] = Object.keys(preKeys) - const key = preKeys[+keyId] - const decFrom = node.attrs.from ? jidDecode(node.attrs.from) : undefined const receipt: BinaryNode = { tag: 'receipt', @@ -119,6 +116,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } if(retryCount > 1) { + const { update, preKeys } = await getNextPreKeys(authState, 1) + + const [keyId] = Object.keys(preKeys) + const key = preKeys[+keyId] + const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1) const content = receipt.content! as BinaryNode[] content.push({ @@ -132,13 +134,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { { tag: 'device-identity', attrs: { }, content: deviceIdentity } ] }) + + ev.emit('creds.update', update) } await sendNode(receipt) logger.info({ msgAttrs: node.attrs, retryCount }, 'sent retry receipt') - - ev.emit('creds.update', update) } ) } @@ -268,7 +270,11 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { msgRetryMap[key] = (msgRetryMap[key] || 0) + 1 } - const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => { + const sendMessagesAgain = async( + key: proto.IMessageKey, + ids: string[], + retryNode: BinaryNode + ) => { const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id }))) const remoteJid = key.remoteJid! const participant = key.participant || remoteJid @@ -293,7 +299,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(sendToAll) { msgRelayOpts.useUserDevicesCache = false } else { - msgRelayOpts.participant = participant + msgRelayOpts.participant = { + jid: participant, + count: +retryNode.attrs.count + } } await relayMessage(key.remoteJid!, msg, msgRelayOpts) @@ -363,11 +372,12 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(attrs.type === 'retry') { // correctly set who is asking for the retry key.participant = key.participant || attrs.from + const retryNode = getBinaryNodeChild(node, 'retry') if(willSendMessageAgain(ids[0], key.participant)) { if(key.fromMe) { try { logger.debug({ attrs, key }, 'recv retry request') - await sendMessagesAgain(key, ids) + await sendMessagesAgain(key, ids, retryNode!) } catch(error) { logger.error({ key, ids, trace: error.stack }, 'error in sending message again') } diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 73dbc6f..030c189 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -299,7 +299,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { additionalAttributes = { ...additionalAttributes, device_fanout: 'false' } } - const { user, device } = jidDecode(participant)! + const { user, device } = jidDecode(participant.jid)! devices.push({ user, device }) } @@ -423,6 +423,12 @@ export const makeMessagesSocket = (config: SocketConfig) => { shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2 } + if(participant?.count) { + for(const node of participants) { + node.attrs.count = participant.count.toString() + } + } + if(participants.length) { binaryNodeContent.push({ tag: 'participants', @@ -446,12 +452,12 @@ export const makeMessagesSocket = (config: SocketConfig) => { if(participant) { if(isJidGroup(destinationJid)) { stanza.attrs.to = destinationJid - stanza.attrs.participant = participant - } else if(areJidsSameUser(participant, meId)) { - stanza.attrs.to = participant + stanza.attrs.participant = participant.jid + } else if(areJidsSameUser(participant.jid, meId)) { + stanza.attrs.to = participant.jid stanza.attrs.recipient = destinationJid } else { - stanza.attrs.to = participant + stanza.attrs.to = participant.jid } } else { stanza.attrs.to = destinationJid diff --git a/src/Types/Message.ts b/src/Types/Message.ts index 14a4eb6..2cdda10 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -150,7 +150,7 @@ type MinimalRelayOptions = { export type MessageRelayOptions = MinimalRelayOptions & { /** only send to a specific participant; used when a message decryption fails for a single user */ - participant?: string + participant?: { jid: string, count: number } /** additional attributes to add to the WA binary node */ additionalAttributes?: { [_: string]: string } /** should we use the devices cache, or fetch afresh from the server; default assumed to be "true" */