feat: add readMessages function

This commit is contained in:
Adhiraj Singh
2022-04-06 09:30:32 +05:30
parent 6d4fc87169
commit 5aa64f2c39
3 changed files with 44 additions and 10 deletions

View File

@@ -521,16 +521,19 @@ await sock.sendMessage('1234@s.whatsapp.net', { forward: msg }) // WA forward th
## Reading Messages ## Reading Messages
A set of message IDs must be explicitly marked read now. A set of message keys must be explicitly marked read now.
Cannot mark an entire "chat" read as it were with Baileys Web. In multi-device, you cannot mark an entire "chat" read as it were with Baileys Web.
This does mean you have to keep track of unread messages. This does mean you have to keep track of unread messages.
``` ts ``` ts
const id = '1234-123@g.us' const key = {
const messageID = 'AHASHH123123AHGA' // id of the message you want to read remoteJid: '1234-123@g.us',
const participant = '912121232@s.whatsapp.net' // the ID of the user that sent the message (undefined for individual chats) id: 'AHASHH123123AHGA', // id of the message you want to read
participant: '912121232@s.whatsapp.net' // the ID of the user that sent the message (undefined for individual chats)
await sock.sendReadReceipt(id, participant, [messageID]) }
// pass to readMessages function
// can pass multiple keys to read multiple messages as well
await sock.readMessages([key])
``` ```
The message ID is the unique identifier of the message that you are marking as read. On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```. The message ID is the unique identifier of the message that you are marking as read. On a `WAMessage`, the `messageID` can be accessed using ```messageID = message.key.id```.

View File

@@ -2,8 +2,8 @@
import NodeCache from 'node-cache' import NodeCache from 'node-cache'
import { proto } from '../../WAProto' import { proto } from '../../WAProto'
import { WA_DEFAULT_EPHEMERAL } from '../Defaults' import { WA_DEFAULT_EPHEMERAL } from '../Defaults'
import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig } from '../Types' import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types'
import { encodeWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, generateMessageID, generateWAMessage, getWAUploadToServer, jidToSignalProtocolAddress, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils' import { aggregateMessageKeysNotFromMe, encodeWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, generateMessageID, generateWAMessage, getWAUploadToServer, jidToSignalProtocolAddress, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils'
import { BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary' import { BinaryNode, BinaryNodeAttributes, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, isJidUser, jidDecode, jidEncode, jidNormalizedUser, JidWithDevice, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary'
import { makeGroupsSocket } from './groups' import { makeGroupsSocket } from './groups'
@@ -131,6 +131,14 @@ export const makeMessagesSocket = (config: SocketConfig) => {
return sendReceipt(jid, participant, messageIds, readType) return sendReceipt(jid, participant, messageIds, readType)
} }
/** Bulk read messages. Keys can be from different chats & participants */
const readMessages = async(keys: WAMessageKey[]) => {
const recps = aggregateMessageKeysNotFromMe(keys)
for(const { jid, participant, messageIds } of recps) {
await sendReadReceipt(jid, participant, messageIds)
}
}
const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => { const getUSyncDevices = async(jids: string[], ignoreZeroDevices: boolean) => {
const deviceResults: JidWithDevice[] = [] const deviceResults: JidWithDevice[] = []
@@ -447,6 +455,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
relayMessage, relayMessage,
sendReceipt, sendReceipt,
sendReadReceipt, sendReadReceipt,
readMessages,
refreshMediaConn, refreshMediaConn,
waUploadToServer, waUploadToServer,
fetchPrivacySettings, fetchPrivacySettings,

View File

@@ -526,6 +526,7 @@ export const getDevice = (id: string) => {
return deviceType return deviceType
} }
/** Upserts a receipt in the message */
export const updateMessageWithReceipt = (msg: WAMessage, receipt: MessageUserReceipt) => { export const updateMessageWithReceipt = (msg: WAMessage, receipt: MessageUserReceipt) => {
msg.userReceipt = msg.userReceipt || [] msg.userReceipt = msg.userReceipt || []
const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid) const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid)
@@ -536,6 +537,27 @@ export const updateMessageWithReceipt = (msg: WAMessage, receipt: MessageUserRec
} }
} }
/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
export const aggregateMessageKeysNotFromMe = (keys: proto.IMessageKey[]) => {
const keyMap: { [id: string]: { jid: string, participant: string | undefined, messageIds: string[] } } = { }
for(const { remoteJid, id, participant, fromMe } of keys) {
if(!fromMe) {
const uqKey = `${remoteJid}:${participant || ''}`
if(!keyMap[uqKey]) {
keyMap[uqKey] = {
jid: remoteJid,
participant,
messageIds: []
}
}
keyMap[uqKey].messageIds.push(id)
}
}
return Object.values(keyMap)
}
/** /**
* Downloads the given message. Throws an error if it's not a media message * Downloads the given message. Throws an error if it's not a media message
*/ */