Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master oficial 25092024 #11

Merged
merged 8 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 6.7.9 (2024-08-22)
## Update WAProto [2, 3000, 1015901307]
## 6.7.12 (2024-09-22)


### Features

* add label feature ([#955](https://github.com/WhiskeySockets/Baileys/issues/955)) ([6ff9455](https://github.com/WhiskeySockets/Baileys/commit/6ff945502d9e78c42a1d05fca79f951e81b946df))
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "baileys",
"version": "6.7.11",
"version": "6.7.12",
"description": "WhatsApp API",
"keywords": [
"whatsapp",
Expand Down Expand Up @@ -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:wkarts/libsignal-node",
Expand Down
24 changes: 22 additions & 2 deletions src/Socket/chats.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Boom } from '@hapi/boom'

Check failure on line 1 in src/Socket/chats.ts

View workflow job for this annotation

GitHub Actions / check-lint

Run autofix to sort these imports!
import NodeCache from 'node-cache'
import { proto } from '../../WAProto'
import { DEFAULT_CACHE_TTLS, PROCESSABLE_HISTORY_TYPES } from '../Defaults'
Expand All @@ -8,7 +8,7 @@
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'

Check failure on line 11 in src/Socket/chats.ts

View workflow job for this annotation

GitHub Actions / check-lint

'Label' is defined but never used

const MAX_SYNC_ATTEMPTS = 2

Expand Down Expand Up @@ -221,11 +221,21 @@

/** 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'
},
Expand All @@ -241,10 +251,20 @@

/** 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'
}
Expand Down
243 changes: 126 additions & 117 deletions src/Socket/messages-recv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@

break
case 'membership_approval_mode':
const approvalMode: any = getBinaryNodeChild(child, 'group_join')

Check warning on line 345 in src/Socket/messages-recv.ts

View workflow job for this annotation

GitHub Actions / check-lint

Unexpected any. Specify a different type
if(approvalMode) {
msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE
msg.messageStubParameters = [ approvalMode.attrs.state ]
Expand Down Expand Up @@ -622,67 +622,70 @@
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) => {
Expand All @@ -693,29 +696,32 @@
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) => {
Expand Down Expand Up @@ -761,62 +767,65 @@
}
}

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(
Expand All @@ -842,7 +851,7 @@
return sendPeerDataOperationMessage(pdoMessage)
}

const requestPlaceholderResend = async(messageKey: WAMessageKey): Promise<'RESOLVED'| string | undefined> => {

Check warning on line 854 in src/Socket/messages-recv.ts

View workflow job for this annotation

GitHub Actions / check-lint

"RESOLVED" is overridden by string in this union type
if(!authState.creds.me?.id) {
throw new Boom('Not authenticated')
}
Expand Down Expand Up @@ -909,7 +918,7 @@
}

// 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)
}

Expand Down
4 changes: 2 additions & 2 deletions src/Store/make-cache-manager-store.ts
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/Types/Call.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading
Loading