From 5a33fd85a4396ada752ef9b6b3d15015500e4638 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sat, 6 Nov 2021 15:41:49 +0530 Subject: [PATCH] fix: read receipts --- src/Socket/chats.ts | 26 ++------------------------ src/Socket/messages-recv.ts | 7 +++++-- src/Socket/messages-send.ts | 32 +++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 66fe476..bd412c7 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -13,7 +13,8 @@ export const makeChatsSocket = (config: SocketConfig) => { authState, generateMessageTag, sendNode, - query + query, + fetchPrivacySettings, } = sock const interactiveQuery = async(userNodes: BinaryNode[], queryNode: BinaryNode) => { @@ -145,28 +146,6 @@ export const makeChatsSocket = (config: SocketConfig) => { }) } - const fetchPrivacySettings = async() => { - const result = await query({ - tag: 'iq', - attrs: { - xmlns: 'privacy', - to: S_WHATSAPP_NET, - type: 'get' - }, - content: [ - { tag: 'privacy', attrs: { } } - ] - }) - const nodes = getBinaryNodeChildren(result, 'category') - const settings = nodes.reduce( - (dict, { attrs }) => { - dict[attrs.name] = attrs.value - return dict - }, { } as { [_: string]: string } - ) - return settings - } - const updateAccountSyncTimestamp = async() => { await sendNode({ tag: 'iq', @@ -486,7 +465,6 @@ export const makeChatsSocket = (config: SocketConfig) => { profilePictureUrl, onWhatsApp, fetchBlocklist, - fetchPrivacySettings, fetchStatus, updateProfilePicture, updateBlockStatus, diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 7cdd863..ab86f0e 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -6,6 +6,8 @@ import { proto } from "../../WAProto" import { KEY_BUNDLE_TYPE } from "../Defaults" import { makeMessagesSocket } from "./messages-send" +const isReadReceipt = (type: string) => type === 'read' || type === 'read-self' + export const makeMessagesRecvSocket = (config: SocketConfig) => { const { logger } = config const sock = makeMessagesSocket(config) @@ -412,13 +414,14 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { }) const handleReceipt = ({ tag, attrs, content }: BinaryNode) => { + const isRead = isReadReceipt(attrs.type) if(tag === 'receipt') { // if not read or no type (no type = delivered, but message sent from other device) - if(attrs.type !== 'read' && !!attrs.type) { + if(!isRead && !!attrs.type) { return } } - const status = attrs.type === 'read' ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK + const status = isRead ? proto.WebMessageInfo.WebMessageInfoStatus.READ : proto.WebMessageInfo.WebMessageInfoStatus.DELIVERY_ACK const ids = [attrs.id] if(Array.isArray(content)) { const items = getBinaryNodeChildren(content[0], 'item') diff --git a/src/Socket/messages-send.ts b/src/Socket/messages-send.ts index 76454a5..0ed975c 100644 --- a/src/Socket/messages-send.ts +++ b/src/Socket/messages-send.ts @@ -21,6 +21,32 @@ export const makeMessagesSocket = (config: SocketConfig) => { groupToggleEphemeral } = sock + let privacySettings: { [_: string]: string } | undefined + + const fetchPrivacySettings = async(force: boolean = false) => { + if(!privacySettings || force) { + const result = await query({ + tag: 'iq', + attrs: { + xmlns: 'privacy', + to: S_WHATSAPP_NET, + type: 'get' + }, + content: [ + { tag: 'privacy', attrs: { } } + ] + }) + const nodes = getBinaryNodeChildren(result, 'category') + privacySettings = nodes.reduce( + (dict, { attrs }) => { + dict[attrs.name] = attrs.value + return dict + }, { } as { [_: string]: string } + ) + } + return privacySettings + } + let mediaConn: Promise const refreshMediaConn = async(forceGet = false) => { let media = await mediaConn @@ -52,13 +78,16 @@ export const makeMessagesSocket = (config: SocketConfig) => { } const sendReadReceipt = async(jid: string, participant: string | undefined, messageIds: string[]) => { + const privacySettings = await fetchPrivacySettings() + // based on privacy settings, we have to change the read type + const readType = privacySettings.readreceipts === 'all' ? 'read' : 'read-self' const node: BinaryNode = { tag: 'receipt', attrs: { id: messageIds[0], t: Date.now().toString(), to: jid, - type: 'read' + type: readType }, } if(participant) { @@ -360,6 +389,7 @@ export const makeMessagesSocket = (config: SocketConfig) => { relayMessage, sendReadReceipt, refreshMediaConn, + fetchPrivacySettings, sendMessage: async( jid: string, content: AnyMessageContent,