From c87d8b81290a2262129b3e224300f2b54d770b05 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Tue, 21 Dec 2021 10:53:39 +0530 Subject: [PATCH] refactor: update chat modifications to be uniform across MD + legacy --- README.md | 6 +++--- src/LegacySocket/chats.ts | 22 ++++++++++++---------- src/Socket/chats.ts | 4 ++-- src/Types/Chat.ts | 11 ++++++++++- src/Utils/chat-utils.ts | 11 +++++------ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 108d086..bd2c71e 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ export type BaileysEventMap = { /** auth credentials updated -- some pre key state, device ID etc. */ 'creds.update': Partial /** set chats (history sync), messages are reverse chronologically sorted */ - 'chats.set': { chats: Chat[], messages: WAMessage[] } + 'chats.set': { chats: Chat[], messages: WAMessage[], contacts: Contact[] } /** upsert chats */ 'chats.upsert': Chat[] /** update the given chats */ @@ -495,7 +495,7 @@ WA uses an encrypted form of communication to send chat/app updates. This has be - Archive a chat ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end - await sock.chatModify({ archive: true }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, '123456@s.whatsapp.net') ``` - Mute/unmute a chat ``` ts @@ -508,7 +508,7 @@ WA uses an encrypted form of communication to send chat/app updates. This has be ``` ts const lastMsgInChat = await getLastMessageInChat('123456@s.whatsapp.net') // implement this on your end // mark it unread - await sock.chatModify({ markRead: false }, '123456@s.whatsapp.net', [lastMsgInChat]) + await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, '123456@s.whatsapp.net') ``` - Delete message for me diff --git a/src/LegacySocket/chats.ts b/src/LegacySocket/chats.ts index f692eb4..8847b2a 100644 --- a/src/LegacySocket/chats.ts +++ b/src/LegacySocket/chats.ts @@ -294,24 +294,30 @@ const makeChatsSocket = (config: LegacySocketConfig) => { * Modify a given chat (archive, pin etc.) * @param jid the ID of the person/group you are modifiying */ - chatModify: async( modification: ChatModification, jid: string, chatInfo: Pick, index?: WAMessageKey) => { + chatModify: async(modification: ChatModification, jid: string, chatInfo: Pick, timestampNow?: number) => { let chatAttrs: BinaryNode['attrs'] = { jid: jid } let data: BinaryNode[] | undefined = undefined - const stamp = unixTimestampSeconds() + + timestampNow = timestampNow || unixTimestampSeconds() if('archive' in modification) { chatAttrs.type = modification.archive ? 'archive' : 'unarchive' + const indexKey = modification.lastMessages[modification.lastMessages.length-1].key + if(indexKey) { + chatAttrs.index = indexKey.id + chatAttrs.owner = indexKey.fromMe ? 'true' : 'false' + } } else if('pin' in modification) { chatAttrs.type = 'pin' if(modification.pin) { - chatAttrs.pin = stamp.toString() + chatAttrs.pin = timestampNow.toString() } else { chatAttrs.previous = chatInfo.pin!.toString() } } else if('mute' in modification) { chatAttrs.type = 'mute' if(modification.mute) { - chatAttrs.mute = (stamp + modification.mute).toString() + chatAttrs.mute = (timestampNow + modification.mute).toString() } else { chatAttrs.previous = chatInfo.mute!.toString() } @@ -335,12 +341,8 @@ const makeChatsSocket = (config: LegacySocketConfig) => { } )) } else if('markRead' in modification) { - return chatRead(index!, modification.markRead ? 0 : -1) - } - - if(index) { - chatAttrs.index = index.id - chatAttrs.owner = index.fromMe ? 'true' : 'false' + const indexKey = modification.lastMessages[modification.lastMessages.length-1].key + return chatRead(indexKey, modification.markRead ? 0 : -1) } const node = { tag: 'chat', attrs: chatAttrs, content: data } diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 5e27a84..8c16e66 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -541,8 +541,8 @@ export const makeChatsSocket = (config: SocketConfig) => { * lastMessages must be sorted in reverse chronologically * requires the last messages till the last message received; required for archive & unread */ - const chatModify = (mod: ChatModification, jid: string, lastMessages: Pick[]) => { - const patch = chatModificationToAppPatch(mod, jid, lastMessages) + const chatModify = (mod: ChatModification, jid: string) => { + const patch = chatModificationToAppPatch(mod, jid) return appPatch(patch) } diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index a959c91..f2d01e4 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -27,9 +27,17 @@ export type Chat = Omit & { pin?: number | null archive?: boolean } +/** + * the last messages in a chat, sorted reverse-chronologically + * for MD modifications, the last message in the array must be the last message recv in the chat + * */ +export type LastMessageList = Pick[] export type ChatModification = - { archive: boolean } | + { + archive: boolean + lastMessages: LastMessageList + } | { pin: boolean } | @@ -48,5 +56,6 @@ export type ChatModification = } | { markRead: boolean + lastMessages: LastMessageList } | { delete: true } \ No newline at end of file diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 1d324ee..0990eea 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -1,6 +1,6 @@ import { Boom } from '@hapi/boom' import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto" -import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, SignalKeyStore } from "../Types" +import { WAPatchCreate, ChatMutation, WAPatchName, LTHashState, ChatModification, LastMessageList } from "../Types" import { proto } from '../../WAProto' import { LT_HASH_ANTI_TAMPERING } from './lt-hash' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary' @@ -418,11 +418,10 @@ export const decodePatches = async( export const chatModificationToAppPatch = ( mod: ChatModification, - jid: string, - lastMessages: Pick[] + jid: string ) => { const OP = proto.SyncdMutation.SyncdMutationSyncdOperation - const getMessageRange = () => { + const getMessageRange = (lastMessages: LastMessageList) => { if(!lastMessages?.length) { throw new Boom('Expected last message to be not from me', { statusCode: 400 }) } @@ -455,7 +454,7 @@ export const chatModificationToAppPatch = ( syncAction: { archiveChatAction: { archived: !!mod.archive, - messageRange: getMessageRange() + messageRange: getMessageRange(mod.lastMessages) } }, index: ['archive', jid], @@ -468,7 +467,7 @@ export const chatModificationToAppPatch = ( syncAction: { markChatAsReadAction: { read: mod.markRead, - messageRange: getMessageRange() + messageRange: getMessageRange(mod.lastMessages) } }, index: ['markChatAsRead', jid],