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
A set of message IDs must be explicitly marked read now.
Cannot mark an entire "chat" read as it were with Baileys Web.
A set of message keys must be explicitly marked read now.
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.
``` ts
const id = '1234-123@g.us'
const messageID = 'AHASHH123123AHGA' // id of the message you want to read
const participant = '912121232@s.whatsapp.net' // the ID of the user that sent the message (undefined for individual chats)
await sock.sendReadReceipt(id, participant, [messageID])
``` ts
const key = {
remoteJid: '1234-123@g.us',
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)
}
// 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```.

View File

@@ -2,8 +2,8 @@
import NodeCache from 'node-cache'
import { proto } from '../../WAProto'
import { WA_DEFAULT_EPHEMERAL } from '../Defaults'
import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig } from '../Types'
import { encodeWAMessage, encryptSenderKeyMsgSignalProto, encryptSignalProto, extractDeviceJids, generateMessageID, generateWAMessage, getWAUploadToServer, jidToSignalProtocolAddress, parseAndInjectE2ESessions, unixTimestampSeconds } from '../Utils'
import { AnyMessageContent, MediaConnInfo, MessageReceiptType, MessageRelayOptions, MiscMessageGenerationOptions, SocketConfig, WAMessageKey } from '../Types'
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 { makeGroupsSocket } from './groups'
@@ -131,6 +131,14 @@ export const makeMessagesSocket = (config: SocketConfig) => {
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 deviceResults: JidWithDevice[] = []
@@ -447,6 +455,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
relayMessage,
sendReceipt,
sendReadReceipt,
readMessages,
refreshMediaConn,
waUploadToServer,
fetchPrivacySettings,

View File

@@ -526,6 +526,7 @@ export const getDevice = (id: string) => {
return deviceType
}
/** Upserts a receipt in the message */
export const updateMessageWithReceipt = (msg: WAMessage, receipt: MessageUserReceipt) => {
msg.userReceipt = msg.userReceipt || []
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
*/