From 6824a203d03111e548ecfb21e100781ad7b2a459 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Wed, 1 Jun 2022 13:20:21 +0530 Subject: [PATCH] feat: correctly handle presence being offline for receipts When sendPresenceUpdate('unavailable') is called, it should allow notifications to be received on the phone --- README.md | 2 ++ src/Defaults/index.ts | 1 + src/Socket/chats.ts | 10 +++++++--- src/Socket/messages-recv.ts | 11 +++++++++++ src/Types/Message.ts | 2 +- src/Types/State.ts | 6 +++++- src/Types/index.ts | 2 ++ 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5f411dc..aa67e00 100644 --- a/README.md +++ b/README.md @@ -564,6 +564,8 @@ type WAPresence = 'unavailable' | 'available' | 'composing' | 'recording' | 'pau The presence expires after about 10 seconds. +**Note:** In the multi-device version of WhatsApp -- if a desktop client is active, WA doesn't send push notifications to the device. If you would like to receive said notifications -- mark your Baileys client offline using `sock.sendPresenceUpdate('unavailable')` + ## Downloading Media Messages If you want to save the media you received diff --git a/src/Defaults/index.ts b/src/Defaults/index.ts index 639e994..289e261 100644 --- a/src/Defaults/index.ts +++ b/src/Defaults/index.ts @@ -44,6 +44,7 @@ const BASE_CONNECTION_CONFIG: CommonSocketConfig = { export const DEFAULT_CONNECTION_CONFIG: SocketConfig = { ...BASE_CONNECTION_CONFIG, downloadHistory: true, + markOnlineOnConnect: true, linkPreviewImageThumbnailWidth: 192, transactionOpts: { maxCommitRetries: 10, delayBetweenTriesMs: 3000 }, getMessage: async() => undefined diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index e70169d..21319c5 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -9,7 +9,7 @@ import { makeMessagesSocket } from './messages-send' const MAX_SYNC_ATTEMPTS = 5 export const makeChatsSocket = (config: SocketConfig) => { - const { logger } = config + const { logger, markOnlineOnConnect } = config const sock = makeMessagesSocket(config) const { ev, @@ -379,6 +379,8 @@ export const makeChatsSocket = (config: SocketConfig) => { return } + ev.emit('connection.update', { isOnline: type === 'available' }) + await sendNode({ tag: 'presence', attrs: { @@ -467,7 +469,7 @@ export const makeChatsSocket = (config: SocketConfig) => { const events = processSyncActions(actions, authState.creds.me!, logger) emitEventsFromMap(events) // resend available presence to update name on servers - if(events['creds.update']?.me?.name) { + if(events['creds.update']?.me?.name && markOnlineOnConnect) { sendPresenceUpdate('available') } } @@ -610,7 +612,9 @@ export const makeChatsSocket = (config: SocketConfig) => { fetchProps(), fetchBlocklist(), fetchPrivacySettings(), - sendPresenceUpdate('available') + markOnlineOnConnect + ? sendPresenceUpdate('available') + : undefined ]) } diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 42cefd1..b8b1244 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -47,6 +47,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { const historyCache = new Set() + let sendActiveReceipts = false + const sendMessageAck = async({ tag, attrs }: BinaryNode, extraAttrs: BinaryNodeAttributes = { }) => { const stanza: BinaryNode = { tag: 'ack', @@ -511,6 +513,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { if(isJidUser(msg.key.remoteJid)) { participant = author } + } else if(!sendActiveReceipts) { + type = 'inactive' } await sendReceipt(msg.key.remoteJid!, participant, [msg.key.id!], type) @@ -617,6 +621,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } }) + ev.on('connection.update', ({ isOnline }) => { + if(typeof isOnline !== 'undefined') { + sendActiveReceipts = isOnline + logger.trace(`sendActiveReceipts set to "${sendActiveReceipts}"`) + } + }) + return { ...sock, processMessage: processMessageLocal, diff --git a/src/Types/Message.ts b/src/Types/Message.ts index b70efc5..e2e5cdd 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -24,7 +24,7 @@ export type MessageType = keyof proto.Message export type DownloadableMessage = { mediaKey?: Uint8Array, directPath?: string, url?: string } -export type MessageReceiptType = 'read' | 'read-self' | 'hist_sync' | 'peer_msg' | 'sender' | undefined +export type MessageReceiptType = 'read' | 'read-self' | 'hist_sync' | 'peer_msg' | 'sender' | 'inactive' | undefined export type MediaConnInfo = { auth: string diff --git a/src/Types/State.ts b/src/Types/State.ts index 4b6866a..5d9784a 100644 --- a/src/Types/State.ts +++ b/src/Types/State.ts @@ -21,5 +21,9 @@ export type ConnectionState = { phoneConnected: boolean user?: Contact } - + /** + * if the client is shown as an active, online client. + * If this is false, the primary phone and other devices will receive notifs + * */ + isOnline?: boolean } \ No newline at end of file diff --git a/src/Types/index.ts b/src/Types/index.ts index 297b49c..e8aceed 100644 --- a/src/Types/index.ts +++ b/src/Types/index.ts @@ -24,6 +24,8 @@ export type SocketConfig = CommonSocketConfig & { transactionOpts: TransactionCapabilityOptions /** provide a cache to store a user's device list */ userDevicesCache?: NodeCache + /** marks the client as online whenever the socket successfully connects */ + markOnlineOnConnect: boolean /** * map to store the retry counts for failed messages; * used to determine whether to retry a message or not */