From 70f03213810fb821c05ea5f024f6f270babe4df5 Mon Sep 17 00:00:00 2001 From: Rajeh Taher Date: Sun, 22 Sep 2024 14:32:05 +0300 Subject: [PATCH 1/7] fix(master): New profile update/removal endpoint (inspired by #1048) --- src/Socket/chats.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 7385d09742c..495b86f0481 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -220,11 +220,21 @@ export const makeChatsSocket = (config: SocketConfig) => { /** update the profile picture for yourself or a group */ const updateProfilePicture = async(jid: string, content: WAMediaUpload) => { + let targetJid = '' + if(!jid) { + throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update') + } + + if(jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me!.id)) { + targetJid = jid // in case it is someone other than us + } + const { img } = await generateProfilePicture(content) await query({ tag: 'iq', attrs: { - to: jidNormalizedUser(jid), + target: targetJid, + to: S_WHATSAPP_NET, type: 'set', xmlns: 'w:profile:picture' }, @@ -240,10 +250,20 @@ export const makeChatsSocket = (config: SocketConfig) => { /** remove the profile picture for yourself or a group */ const removeProfilePicture = async(jid: string) => { + let targetJid = '' + if(!jid) { + throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update') + } + + if(jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me!.id)) { + targetJid = jid // in case it is someone other than us + } + await query({ tag: 'iq', attrs: { - to: jidNormalizedUser(jid), + target: targetJid, + to: S_WHATSAPP_NET, type: 'set', xmlns: 'w:profile:picture' } From ed00a57c843695e5af05344edb3bebc893537fd5 Mon Sep 17 00:00:00 2001 From: vini <91087061+vinikjkkj@users.noreply.github.com> Date: Sun, 22 Sep 2024 08:34:29 -0300 Subject: [PATCH 2/7] remove duplicated call reject event / add terminate tag (#1031) * initial commit * add terminate tag * lint * lint 2 * Update src/Socket/messages-recv.ts * chore: linting --------- Co-authored-by: Rajeh Taher --- src/Socket/messages-recv.ts | 2 +- src/Types/Call.ts | 2 +- src/Utils/generics.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index 79c2cdf29f1..a7b142ea177 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -909,7 +909,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } // delete data once call has ended - if(status === 'reject' || status === 'accept' || status === 'timeout') { + if(status === 'reject' || status === 'accept' || status === 'timeout' || status === 'terminate') { callOfferCache.del(call.id) } diff --git a/src/Types/Call.ts b/src/Types/Call.ts index 06f3b1f2819..a5dbe1a92ea 100644 --- a/src/Types/Call.ts +++ b/src/Types/Call.ts @@ -1,5 +1,5 @@ -export type WACallUpdateType = 'offer' | 'ringing' | 'timeout' | 'reject' | 'accept' +export type WACallUpdateType = 'offer' | 'ringing' | 'timeout' | 'reject' | 'accept' | 'terminate' export type WACallEvent = { chatId: string diff --git a/src/Utils/generics.ts b/src/Utils/generics.ts index c99dbb43ee9..06ea2bb4b27 100644 --- a/src/Utils/generics.ts +++ b/src/Utils/generics.ts @@ -364,7 +364,8 @@ export const getCallStatusFromNode = ({ tag, attrs }: BinaryNode) => { if(attrs.reason === 'timeout') { status = 'timeout' } else { - status = 'reject' + //fired when accepted/rejected/timeout/caller hangs up + status = 'terminate' } break From fda268916927c81e407b4f5d2830b63ed8c23b30 Mon Sep 17 00:00:00 2001 From: vini <91087061+vinikjkkj@users.noreply.github.com> Date: Sun, 22 Sep 2024 08:34:43 -0300 Subject: [PATCH 3/7] fix: messaging-history.set event not emitting syncType and progress / add PDO request id (#1042) * initial commit * add PDO request id --- src/Types/Events.ts | 4 ++++ src/Utils/event-buffer.ts | 8 +++++++- src/Utils/history.ts | 2 +- src/Utils/process-message.ts | 3 ++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 35bed25ca75..bb13e39629f 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -23,6 +23,7 @@ export type BaileysEventMap = { isLatest?: boolean progress?: number | null syncType?: proto.HistorySync.HistorySyncType + peerDataRequestSessionId?: string | null } /** upsert chats */ 'chats.upsert': Chat[] @@ -73,6 +74,9 @@ export type BufferedEventData = { messages: { [uqId: string]: WAMessage } empty: boolean isLatest: boolean + progress?: number | null + syncType?: proto.HistorySync.HistorySyncType + peerDataRequestSessionId?: string } chatUpserts: { [jid: string]: Chat } chatUpdates: { [jid: string]: ChatUpdate } diff --git a/src/Utils/event-buffer.ts b/src/Utils/event-buffer.ts index 74083980875..fc07cf45258 100644 --- a/src/Utils/event-buffer.ts +++ b/src/Utils/event-buffer.ts @@ -230,6 +230,9 @@ function append( } data.historySets.empty = false + data.historySets.syncType = eventData.syncType + data.historySets.progress = eventData.progress + data.historySets.peerDataRequestSessionId = eventData.peerDataRequestSessionId data.historySets.isLatest = eventData.isLatest || data.historySets.isLatest break @@ -521,7 +524,10 @@ function consolidateEvents(data: BufferedEventData) { chats: Object.values(data.historySets.chats), messages: Object.values(data.historySets.messages), contacts: Object.values(data.historySets.contacts), - isLatest: data.historySets.isLatest + syncType: data.historySets.syncType, + progress: data.historySets.progress, + isLatest: data.historySets.isLatest, + peerDataRequestSessionId: data.historySets.peerDataRequestSessionId } } diff --git a/src/Utils/history.ts b/src/Utils/history.ts index ad3c693b55a..4969abbad58 100644 --- a/src/Utils/history.ts +++ b/src/Utils/history.ts @@ -95,7 +95,7 @@ export const processHistoryMessage = (item: proto.IHistorySync) => { contacts, messages, syncType: item.syncType, - progress: item.progress, + progress: item.progress } } diff --git a/src/Utils/process-message.ts b/src/Utils/process-message.ts index ee3f02161a2..0d142a0f522 100644 --- a/src/Utils/process-message.ts +++ b/src/Utils/process-message.ts @@ -223,7 +223,8 @@ const processMessage = async( isLatest: histNotification.syncType !== proto.HistorySync.HistorySyncType.ON_DEMAND ? isLatest - : undefined + : undefined, + peerDataRequestSessionId: histNotification.peerDataRequestSessionId }) } From 71082bf1b3375fd19a5a8abcff9861af093d71f3 Mon Sep 17 00:00:00 2001 From: vini <91087061+vinikjkkj@users.noreply.github.com> Date: Sun, 22 Sep 2024 08:35:50 -0300 Subject: [PATCH 4/7] hotfix: always send acks even in case of errors (#1043) --- src/Socket/messages-recv.ts | 241 +++++++++++++++++++----------------- 1 file changed, 125 insertions(+), 116 deletions(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index a7b142ea177..6066680af7d 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -622,67 +622,70 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { ids.push(...items.map(i => i.attrs.id)) } - await Promise.all([ - processingMutex.mutex( - async() => { - const status = getStatusFromReceiptType(attrs.type) - if( - typeof status !== 'undefined' && - ( - // basically, we only want to know when a message from us has been delivered to/read by the other person - // or another device of ours has read some messages - status > proto.WebMessageInfo.Status.DELIVERY_ACK || - !isNodeFromMe - ) - ) { - if(isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) { - if(attrs.participant) { - const updateKey: keyof MessageUserReceipt = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp' + try { + await Promise.all([ + processingMutex.mutex( + async() => { + const status = getStatusFromReceiptType(attrs.type) + if( + typeof status !== 'undefined' && + ( + // basically, we only want to know when a message from us has been delivered to/read by the other person + // or another device of ours has read some messages + status > proto.WebMessageInfo.Status.DELIVERY_ACK || + !isNodeFromMe + ) + ) { + if(isJidGroup(remoteJid) || isJidStatusBroadcast(remoteJid)) { + if(attrs.participant) { + const updateKey: keyof MessageUserReceipt = status === proto.WebMessageInfo.Status.DELIVERY_ACK ? 'receiptTimestamp' : 'readTimestamp' + ev.emit( + 'message-receipt.update', + ids.map(id => ({ + key: { ...key, id }, + receipt: { + userJid: jidNormalizedUser(attrs.participant), + [updateKey]: +attrs.t + } + })) + ) + } + } else { ev.emit( - 'message-receipt.update', + 'messages.update', ids.map(id => ({ key: { ...key, id }, - receipt: { - userJid: jidNormalizedUser(attrs.participant), - [updateKey]: +attrs.t - } + update: { status } })) ) } - } else { - ev.emit( - 'messages.update', - ids.map(id => ({ - key: { ...key, id }, - update: { status } - })) - ) } - } - if(attrs.type === 'retry') { - // correctly set who is asking for the retry - key.participant = key.participant || attrs.from - const retryNode = getBinaryNodeChild(node, 'retry') - if(willSendMessageAgain(ids[0], key.participant)) { - if(key.fromMe) { - try { - logger.debug({ attrs, key }, 'recv retry request') - await sendMessagesAgain(key, ids, retryNode!) - } catch(error) { - logger.error({ key, ids, trace: error.stack }, 'error in sending message again') + if(attrs.type === 'retry') { + // correctly set who is asking for the retry + key.participant = key.participant || attrs.from + const retryNode = getBinaryNodeChild(node, 'retry') + if(willSendMessageAgain(ids[0], key.participant)) { + if(key.fromMe) { + try { + logger.debug({ attrs, key }, 'recv retry request') + await sendMessagesAgain(key, ids, retryNode!) + } catch(error) { + logger.error({ key, ids, trace: error.stack }, 'error in sending message again') + } + } else { + logger.info({ attrs, key }, 'recv retry for not fromMe message') } } else { - logger.info({ attrs, key }, 'recv retry for not fromMe message') + logger.info({ attrs, key }, 'will not send message again, as sent too many times') } - } else { - logger.info({ attrs, key }, 'will not send message again, as sent too many times') } } - } - ), - sendMessageAck(node) - ]) + ) + ]) + } finally { + await sendMessageAck(node) + } } const handleNotification = async(node: BinaryNode) => { @@ -693,29 +696,32 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { return } - await Promise.all([ - processingMutex.mutex( - async() => { - const msg = await processNotification(node) - if(msg) { - const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me!.id) - msg.key = { - remoteJid, - fromMe, - participant: node.attrs.participant, - id: node.attrs.id, - ...(msg.key || {}) - } - msg.participant ??= node.attrs.participant - msg.messageTimestamp = +node.attrs.t + try { + await Promise.all([ + processingMutex.mutex( + async() => { + const msg = await processNotification(node) + if(msg) { + const fromMe = areJidsSameUser(node.attrs.participant || remoteJid, authState.creds.me!.id) + msg.key = { + remoteJid, + fromMe, + participant: node.attrs.participant, + id: node.attrs.id, + ...(msg.key || {}) + } + msg.participant ??= node.attrs.participant + msg.messageTimestamp = +node.attrs.t - const fullMsg = proto.WebMessageInfo.fromObject(msg) - await upsertMessage(fullMsg, 'append') + const fullMsg = proto.WebMessageInfo.fromObject(msg) + await upsertMessage(fullMsg, 'append') + } } - } - ), - sendMessageAck(node) - ]) + ) + ]) + } finally { + await sendMessageAck(node) + } } const handleMessage = async(node: BinaryNode) => { @@ -761,62 +767,65 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } } - await Promise.all([ - processingMutex.mutex( - async() => { - await decrypt() - // message failed to decrypt - if(msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) { - retryMutex.mutex( - async() => { - if(ws.isOpen) { - if(getBinaryNodeChild(node, 'unavailable')) { - return - } + try { + await Promise.all([ + processingMutex.mutex( + async() => { + await decrypt() + // message failed to decrypt + if(msg.messageStubType === proto.WebMessageInfo.StubType.CIPHERTEXT) { + retryMutex.mutex( + async() => { + if(ws.isOpen) { + if(getBinaryNodeChild(node, 'unavailable')) { + return + } - const encNode = getBinaryNodeChild(node, 'enc') - await sendRetryRequest(node, !encNode) - if(retryRequestDelayMs) { - await delay(retryRequestDelayMs) + const encNode = getBinaryNodeChild(node, 'enc') + await sendRetryRequest(node, !encNode) + if(retryRequestDelayMs) { + await delay(retryRequestDelayMs) + } + } else { + logger.debug({ node }, 'connection closed, ignoring retry req') } - } else { - logger.debug({ node }, 'connection closed, ignoring retry req') } + ) + } else { + // no type in the receipt => message delivered + let type: MessageReceiptType = undefined + let participant = msg.key.participant + if(category === 'peer') { // special peer message + type = 'peer_msg' + } else if(msg.key.fromMe) { // message was sent by us from a different device + type = 'sender' + // need to specially handle this case + if(isJidUser(msg.key.remoteJid!)) { + participant = author + } + } else if(!sendActiveReceipts) { + type = 'inactive' } - ) - } else { - // no type in the receipt => message delivered - let type: MessageReceiptType = undefined - let participant = msg.key.participant - if(category === 'peer') { // special peer message - type = 'peer_msg' - } else if(msg.key.fromMe) { // message was sent by us from a different device - type = 'sender' - // need to specially handle this case - if(isJidUser(msg.key.remoteJid!)) { - participant = author - } - } else if(!sendActiveReceipts) { - type = 'inactive' - } - await sendReceipt(msg.key.remoteJid!, participant!, [msg.key.id!], type) + await sendReceipt(msg.key.remoteJid!, participant!, [msg.key.id!], type) - // send ack for history message - const isAnyHistoryMsg = getHistoryMsg(msg.message!) - if(isAnyHistoryMsg) { - const jid = jidNormalizedUser(msg.key.remoteJid!) - await sendReceipt(jid, undefined, [msg.key.id!], 'hist_sync') + // send ack for history message + const isAnyHistoryMsg = getHistoryMsg(msg.message!) + if(isAnyHistoryMsg) { + const jid = jidNormalizedUser(msg.key.remoteJid!) + await sendReceipt(jid, undefined, [msg.key.id!], 'hist_sync') + } } - } - cleanMessage(msg, authState.creds.me!.id) + cleanMessage(msg, authState.creds.me!.id) - await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify') - } - ), - sendMessageAck(node) - ]) + await upsertMessage(msg, node.attrs.offline ? 'append' : 'notify') + } + ) + ]) + } finally { + await sendMessageAck(node) + } } const fetchMessageHistory = async( From 9e4e2117517260a48a1c3221ac537ef3b135d19e Mon Sep 17 00:00:00 2001 From: wduandy <64294538+wduandy@users.noreply.github.com> Date: Sun, 22 Sep 2024 08:43:17 -0300 Subject: [PATCH 5/7] chore: update-cache-manager-dependency (#996) * chore: update-cache-manager-dependency * fix: Linting --------- Co-authored-by: Eduardo --- package.json | 2 +- src/Store/make-cache-manager-store.ts | 4 +-- yarn.lock | 35 ++++++++++++++++++--------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 3cdcb7ca099..1e288b9b37f 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "async-lock": "^1.4.1", "audio-decode": "^2.1.3", "axios": "^1.6.0", - "cache-manager": "4.0.1", + "cache-manager": "^5.7.6", "futoin-hkdf": "^1.5.1", "libphonenumber-js": "^1.10.20", "libsignal": "github:WhiskeySockets/libsignal-node", diff --git a/src/Store/make-cache-manager-store.ts b/src/Store/make-cache-manager-store.ts index c93ccc02fb7..d5e53b7e46a 100644 --- a/src/Store/make-cache-manager-store.ts +++ b/src/Store/make-cache-manager-store.ts @@ -1,10 +1,10 @@ -import { caching, Storage } from 'cache-manager' +import { caching, Store } from 'cache-manager' import { proto } from '../../WAProto' import { AuthenticationCreds } from '../Types' import { BufferJSON, initAuthCreds } from '../Utils' import logger from '../Utils/logger' -const makeCacheManagerAuthState = async(store: Storage, sessionKey: string) => { +const makeCacheManagerAuthState = async(store: Store, sessionKey: string) => { const defaultKey = (file: string): string => `${sessionKey}:${file}` const databaseConn = await caching(store) diff --git a/yarn.lock b/yarn.lock index ae5bf6225e4..c05f5db7211 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1778,11 +1778,6 @@ async-retry@1.3.3: dependencies: retry "0.13.1" -async@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" - integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -2090,14 +2085,15 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" -cache-manager@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-4.0.1.tgz#185b1d1aa1385fbb4fb0ec88fda7676f566a15b8" - integrity sha512-JWdtjdX8e0e6eMehAZsdJvBMvHn/pVQGYUjgzc1ILFH0vtcffb9R7XIEAqfYgEeaVJVCOSP4+dxCius+ciW0RA== +cache-manager@^5.7.6: + version "5.7.6" + resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-5.7.6.tgz#bdd8a154c73e5233824aa09ceb359ed225d37b7e" + integrity sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w== dependencies: - async "3.2.3" + eventemitter3 "^5.0.1" lodash.clonedeep "^4.5.0" - lru-cache "^7.10.1" + lru-cache "^10.2.2" + promise-coalesce "^1.1.2" cacheable-lookup@^7.0.0: version "7.0.0" @@ -3301,6 +3297,11 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + execa@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" @@ -5307,6 +5308,11 @@ lowercase-keys@^3.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== +lru-cache@^10.2.2: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5321,7 +5327,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.10.1, lru-cache@^7.14.1: +lru-cache@^7.14.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== @@ -6238,6 +6244,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +promise-coalesce@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/promise-coalesce/-/promise-coalesce-1.1.2.tgz#5d3bc4d0b2cf2e41e9df7cbeb6519b2a09459e3d" + integrity sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg== + promise.allsettled@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.6.tgz#8dc8ba8edf429feb60f8e81335b920e109c94b6e" From 6ff945502d9e78c42a1d05fca79f951e81b946df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=BA=E8=BE=89?= Date: Sun, 22 Sep 2024 19:48:17 +0800 Subject: [PATCH 6/7] feat: add label feature (#955) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 刘建辉 --- src/Socket/chats.ts | 13 +++++++++++++ src/Types/Chat.ts | 3 +++ src/Types/Label.ts | 12 ++++++++++++ src/Utils/chat-utils.ts | 15 +++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 495b86f0481..38ee669e9cf 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -8,6 +8,7 @@ import { makeMutex } from '../Utils/make-mutex' import processMessage from '../Utils/process-message' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary' import { makeSocket } from './socket' +import { Label, LabelActionBody } from '../Types/Label' const MAX_SYNC_ATTEMPTS = 2 @@ -804,6 +805,17 @@ export const makeChatsSocket = (config: SocketConfig) => { }, jid) } + /** + * Adds label + */ + const addLabel = (jid: string, labels: LabelActionBody) => { + return chatModify({ + addLabel: { + ...labels + } + }, jid) + } + /** * Adds label for the chats */ @@ -1024,6 +1036,7 @@ export const makeChatsSocket = (config: SocketConfig) => { resyncAppState, chatModify, cleanDirtyBits, + addLabel, addChatLabel, removeChatLabel, addMessageLabel, diff --git a/src/Types/Chat.ts b/src/Types/Chat.ts index 09b2cc3125a..a7ff6bbd6cd 100644 --- a/src/Types/Chat.ts +++ b/src/Types/Chat.ts @@ -1,6 +1,7 @@ import type { proto } from '../../WAProto' import type { AccountSettings } from './Auth' import type { BufferedEventData } from './Events' +import type { LabelActionBody } from './Label' import type { ChatLabelAssociationActionBody } from './LabelAssociation' import type { MessageLabelAssociationActionBody } from './LabelAssociation' import type { MinimalMessage } from './Message' @@ -90,6 +91,8 @@ export type ChatModification = lastMessages: LastMessageList } | { delete: true, lastMessages: LastMessageList } + // Label + | { addLabel: LabelActionBody } // Label assosiation | { addChatLabel: ChatLabelAssociationActionBody } | { removeChatLabel: ChatLabelAssociationActionBody } diff --git a/src/Types/Label.ts b/src/Types/Label.ts index 6319b007e2b..d9349e60df4 100644 --- a/src/Types/Label.ts +++ b/src/Types/Label.ts @@ -11,6 +11,18 @@ export interface Label { predefinedId?: string } +export interface LabelActionBody { + id: string + /** Label name */ + name?: string + /** Label color ID */ + color?: number + /** Is label has been deleted */ + deleted?: boolean + /** WhatsApp has 5 predefined labels (New customer, New order & etc) */ + predefinedId?: number +} + /** WhatsApp has 20 predefined colors */ export enum LabelColor { Color1 = 0, diff --git a/src/Utils/chat-utils.ts b/src/Utils/chat-utils.ts index 22e4243428a..75e15a2ad3b 100644 --- a/src/Utils/chat-utils.ts +++ b/src/Utils/chat-utils.ts @@ -620,6 +620,21 @@ export const chatModificationToAppPatch = ( apiVersion: 1, operation: OP.SET, } + } else if('addLabel' in mod) { + patch = { + syncAction: { + labelEditAction: { + name: mod.addLabel.name, + color: mod.addLabel.color, + predefinedId : mod.addLabel.predefinedId, + deleted: mod.addLabel.deleted + } + }, + index: ['label_edit', mod.addLabel.id], + type: 'regular', + apiVersion: 3, + operation: OP.SET, + } } else if('addChatLabel' in mod) { patch = { syncAction: { From a1abb635d5c61231659d0f52ab36d82b3aced388 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2024 12:04:45 +0000 Subject: [PATCH 7/7] chore(release): v6.7.8 --- CHANGELOG.md | 7 ++++++- package.json | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 986ffc920ec..8cdb07a4f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -## 6.7.7 (2024-08-22) +## 6.7.8 (2024-09-22) + + +### Features + +* add label feature ([#955](https://github.com/WhiskeySockets/Baileys/issues/955)) ([6ff9455](https://github.com/WhiskeySockets/Baileys/commit/6ff945502d9e78c42a1d05fca79f951e81b946df)) diff --git a/package.json b/package.json index 1e288b9b37f..ef13dcf3139 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "baileys", - "version": "6.7.7", + "version": "6.7.8", "description": "WhatsApp API", "keywords": [ "whatsapp",