mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
fix: catch unexpected errors on MD
This commit is contained in:
@@ -19,10 +19,11 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
sendNode,
|
sendNode,
|
||||||
query,
|
query,
|
||||||
fetchPrivacySettings,
|
fetchPrivacySettings,
|
||||||
|
onUnexpectedError,
|
||||||
} = sock
|
} = sock
|
||||||
|
|
||||||
const mutationMutex = makeMutex()
|
const mutationMutex = makeMutex()
|
||||||
|
/// helper function to fetch an app state sync key
|
||||||
const getAppStateSyncKey = async(keyId: string) => {
|
const getAppStateSyncKey = async(keyId: string) => {
|
||||||
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
|
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
|
||||||
return key
|
return key
|
||||||
@@ -176,35 +177,30 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
}]
|
}]
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
const profiles = getBinaryNodeChild(getBinaryNodeChild(results, 'business_profile'), 'profile')
|
|
||||||
if(!profiles) {
|
|
||||||
// if not bussines
|
|
||||||
if(logger.level === 'trace') {
|
|
||||||
logger.trace({ jid }, 'Not bussines')
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
const profileNode = getBinaryNodeChild(results, 'business_profile')
|
||||||
|
const profiles = getBinaryNodeChild(profileNode, 'profile')
|
||||||
|
if(profiles) {
|
||||||
|
const address = getBinaryNodeChild(profiles, 'address')
|
||||||
|
const description = getBinaryNodeChild(profiles, 'description')
|
||||||
|
const website = getBinaryNodeChild(profiles, 'website')
|
||||||
|
const email = getBinaryNodeChild(profiles, 'email')
|
||||||
|
const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category')
|
||||||
|
const business_hours = getBinaryNodeChild(profiles, 'business_hours')
|
||||||
|
const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config')
|
||||||
|
return {
|
||||||
|
wid: profiles.attrs?.jid,
|
||||||
|
address: address?.content.toString(),
|
||||||
|
description: description?.content.toString(),
|
||||||
|
website: [website?.content.toString()],
|
||||||
|
email: email?.content.toString(),
|
||||||
|
category: category?.content.toString(),
|
||||||
|
business_hours: {
|
||||||
|
timezone: business_hours?.attrs?.timezone,
|
||||||
|
business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig)
|
||||||
|
}
|
||||||
|
} as unknown as WABusinessProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
const address = getBinaryNodeChild(profiles, 'address')
|
|
||||||
const description = getBinaryNodeChild(profiles, 'description')
|
|
||||||
const website = getBinaryNodeChild(profiles, 'website')
|
|
||||||
const email = getBinaryNodeChild(profiles, 'email')
|
|
||||||
const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category')
|
|
||||||
const business_hours = getBinaryNodeChild(profiles, 'business_hours')
|
|
||||||
const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config')
|
|
||||||
return {
|
|
||||||
wid: profiles.attrs?.jid,
|
|
||||||
address: address?.content.toString(),
|
|
||||||
description: description?.content.toString(),
|
|
||||||
website: [website?.content.toString()],
|
|
||||||
email: email?.content.toString(),
|
|
||||||
category: category?.content.toString(),
|
|
||||||
business_hours: {
|
|
||||||
timezone: business_hours?.attrs?.timezone,
|
|
||||||
business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig)
|
|
||||||
}
|
|
||||||
} as unknown as WABusinessProfile
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => {
|
const updateAccountSyncTimestamp = async(fromTimestamp: number | string) => {
|
||||||
@@ -431,7 +427,6 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const resyncMainAppState = async() => {
|
const resyncMainAppState = async() => {
|
||||||
|
|
||||||
logger.debug('resyncing main app state')
|
logger.debug('resyncing main app state')
|
||||||
|
|
||||||
await (
|
await (
|
||||||
@@ -445,7 +440,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
])
|
])
|
||||||
)
|
)
|
||||||
.catch(err => (
|
.catch(err => (
|
||||||
logger.warn({ trace: err.stack }, 'failed to sync app state')
|
onUnexpectedError(err, 'main app sync')
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -480,7 +475,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
} else if(action?.pushNameSetting) {
|
} else if(action?.pushNameSetting) {
|
||||||
const me = {
|
const me = {
|
||||||
...authState.creds.me!,
|
...authState.creds.me!,
|
||||||
name: action?.pushNameSetting?.name!
|
name: action?.pushNameSetting?.name!
|
||||||
}
|
}
|
||||||
ev.emit('creds.update', { me })
|
ev.emit('creds.update', { me })
|
||||||
} else if(action?.pinAction) {
|
} else if(action?.pinAction) {
|
||||||
@@ -640,6 +635,20 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
return appPatch(patch)
|
return appPatch(patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queries need to be fired on connection open
|
||||||
|
* help ensure parity with WA Web
|
||||||
|
* */
|
||||||
|
const fireInitQueries = () => (
|
||||||
|
Promise.all([
|
||||||
|
fetchAbt(),
|
||||||
|
fetchProps(),
|
||||||
|
fetchBlocklist(),
|
||||||
|
fetchPrivacySettings(),
|
||||||
|
sendPresenceUpdate('available')
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
ws.on('CB:presence', handlePresenceUpdate)
|
ws.on('CB:presence', handlePresenceUpdate)
|
||||||
ws.on('CB:chatstate', handlePresenceUpdate)
|
ws.on('CB:chatstate', handlePresenceUpdate)
|
||||||
|
|
||||||
@@ -680,12 +689,10 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
|||||||
|
|
||||||
ev.on('connection.update', ({ connection }) => {
|
ev.on('connection.update', ({ connection }) => {
|
||||||
if(connection === 'open') {
|
if(connection === 'open') {
|
||||||
fetchAbt()
|
fireInitQueries()
|
||||||
fetchProps()
|
.catch(
|
||||||
fetchBlocklist()
|
error => onUnexpectedError(error, 'connection open requests')
|
||||||
fetchPrivacySettings()
|
)
|
||||||
|
|
||||||
sendPresenceUpdate('available')
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import { proto } from '../../WAProto'
|
import { proto } from '../../WAProto'
|
||||||
import { KEY_BUNDLE_TYPE } from '../Defaults'
|
import { KEY_BUNDLE_TYPE } from '../Defaults'
|
||||||
import { Chat, GroupMetadata, MessageUserReceipt, ParticipantAction, SocketConfig, WAMessageStubType } from '../Types'
|
import { BaileysEventMap, Chat, GroupMetadata, MessageUserReceipt, ParticipantAction, SocketConfig, WAMessageStubType } from '../Types'
|
||||||
import { decodeMessageStanza, downloadAndProcessHistorySyncNotification, encodeBigEndian, generateSignalPubKey, normalizeMessageContent, toNumber, xmppPreKey, xmppSignedPreKey } from '../Utils'
|
import { decodeMessageStanza, downloadAndProcessHistorySyncNotification, encodeBigEndian, generateSignalPubKey, normalizeMessageContent, toNumber, xmppPreKey, xmppSignedPreKey } from '../Utils'
|
||||||
import { makeKeyedMutex, makeMutex } from '../Utils/make-mutex'
|
import { makeKeyedMutex, makeMutex } from '../Utils/make-mutex'
|
||||||
import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getAllBinaryNodeChildren, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary'
|
import { areJidsSameUser, BinaryNode, BinaryNodeAttributes, getAllBinaryNodeChildren, getBinaryNodeChildren, isJidGroup, jidDecode, jidEncode, jidNormalizedUser } from '../WABinary'
|
||||||
@@ -15,6 +15,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
ev,
|
ev,
|
||||||
authState,
|
authState,
|
||||||
ws,
|
ws,
|
||||||
|
onUnexpectedError,
|
||||||
assertSessions,
|
assertSessions,
|
||||||
assertingPreKeys,
|
assertingPreKeys,
|
||||||
sendNode,
|
sendNode,
|
||||||
@@ -94,6 +95,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node.attrs.recipient) {
|
if(node.attrs.recipient) {
|
||||||
receipt.attrs.recipient = node.attrs.recipient
|
receipt.attrs.recipient = node.attrs.recipient
|
||||||
}
|
}
|
||||||
@@ -103,9 +105,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(retryCount > 1) {
|
if(retryCount > 1) {
|
||||||
const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1);
|
const exec = generateSignalPubKey(Buffer.from(KEY_BUNDLE_TYPE)).slice(0, 1)
|
||||||
|
const content = receipt.content! as BinaryNode[]
|
||||||
(receipt.content! as BinaryNode[]).push({
|
content.push({
|
||||||
tag: 'keys',
|
tag: 'keys',
|
||||||
attrs: { },
|
attrs: { },
|
||||||
content: [
|
content: [
|
||||||
@@ -357,10 +359,13 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
ev.emit('messages.upsert', { messages: [msg], type: stanza.attrs.offline ? 'append' : 'notify' })
|
ev.emit('messages.upsert', { messages: [msg], type: stanza.attrs.offline ? 'append' : 'notify' })
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
.catch(
|
||||||
|
error => onUnexpectedError(error, 'processing message')
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
ws.on('CB:ack,class:message', async(node: BinaryNode) => {
|
ws.on('CB:ack,class:message', async(node: BinaryNode) => {
|
||||||
await sendNode({
|
sendNode({
|
||||||
tag: 'ack',
|
tag: 'ack',
|
||||||
attrs: {
|
attrs: {
|
||||||
class: 'receipt',
|
class: 'receipt',
|
||||||
@@ -368,6 +373,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
from: node.attrs.from
|
from: node.attrs.from
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.catch(err => onUnexpectedError(err, 'ack message receipt'))
|
||||||
logger.debug({ attrs: node.attrs }, 'sending receipt for ack')
|
logger.debug({ attrs: node.attrs }, 'sending receipt for ack')
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -376,7 +382,10 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
|
|
||||||
const [child] = getAllBinaryNodeChildren(node)
|
const [child] = getAllBinaryNodeChildren(node)
|
||||||
if(!!child?.tag) {
|
if(!!child?.tag) {
|
||||||
await sendMessageAck(node, { class: 'call', type: child.tag })
|
sendMessageAck(node, { class: 'call', type: child.tag })
|
||||||
|
.catch(
|
||||||
|
error => onUnexpectedError(error, 'ack call')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -489,11 +498,9 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.on('CB:receipt', handleReceipt)
|
const handleNotification = async(node: BinaryNode) => {
|
||||||
|
|
||||||
ws.on('CB:notification', async(node: BinaryNode) => {
|
|
||||||
const remoteJid = node.attrs.from
|
const remoteJid = node.attrs.from
|
||||||
processingMutex.mutex(
|
await processingMutex.mutex(
|
||||||
remoteJid,
|
remoteJid,
|
||||||
() => {
|
() => {
|
||||||
const msg = processNotification(node)
|
const msg = processNotification(node)
|
||||||
@@ -516,15 +523,19 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
await sendMessageAck(node, { class: 'notification', type: node.attrs.type })
|
await sendMessageAck(node, { class: 'notification', type: node.attrs.type })
|
||||||
})
|
}
|
||||||
|
|
||||||
ev.on('messages.upsert', async({ messages, type }) => {
|
const handleUpsertedMessages = async({ messages, type }: BaileysEventMap<any>['messages.upsert']) => {
|
||||||
if(type === 'notify' || type === 'append') {
|
if(type === 'notify' || type === 'append') {
|
||||||
const chat: Partial<Chat> = { id: messages[0].key.remoteJid }
|
const chatId = jidNormalizedUser(messages[0].key.remoteJid)
|
||||||
|
const chat: Partial<Chat> = { id: chatId }
|
||||||
const contactNameUpdates: { [_: string]: string } = { }
|
const contactNameUpdates: { [_: string]: string } = { }
|
||||||
for(const msg of messages) {
|
for(const msg of messages) {
|
||||||
|
const normalizedChatId = jidNormalizedUser(msg.key.remoteJid)
|
||||||
if(!!msg.pushName) {
|
if(!!msg.pushName) {
|
||||||
const jid = msg.key.fromMe ? jidNormalizedUser(authState.creds.me!.id) : (msg.key.participant || msg.key.remoteJid)
|
let jid = msg.key.fromMe ? authState.creds.me!.id : (msg.key.participant || msg.key.remoteJid)
|
||||||
|
jid = jidNormalizedUser(jid)
|
||||||
|
|
||||||
contactNameUpdates[jid] = msg.pushName
|
contactNameUpdates[jid] = msg.pushName
|
||||||
// update our pushname too
|
// update our pushname too
|
||||||
if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) {
|
if(msg.key.fromMe && authState.creds.me?.name !== msg.pushName) {
|
||||||
@@ -533,7 +544,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await processingMutex.mutex(
|
await processingMutex.mutex(
|
||||||
'p-' + chat.id!,
|
'p-' + normalizedChatId,
|
||||||
() => processMessage(msg, chat)
|
() => processMessage(msg, chat)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -555,6 +566,29 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.on('CB:receipt', node => {
|
||||||
|
handleReceipt(node)
|
||||||
|
.catch(
|
||||||
|
error => onUnexpectedError(error, 'handling receipt')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
ws.on('CB:notification', async(node: BinaryNode) => {
|
||||||
|
handleNotification(node)
|
||||||
|
.catch(
|
||||||
|
error => {
|
||||||
|
onUnexpectedError(error, 'handling notification')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
ev.on('messages.upsert', data => {
|
||||||
|
handleUpsertedMessages(data)
|
||||||
|
.catch(
|
||||||
|
error => onUnexpectedError(error, 'handling upserted messages')
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
return { ...sock, processMessage, sendMessageAck, sendRetryRequest }
|
return { ...sock, processMessage, sendMessageAck, sendRetryRequest }
|
||||||
|
|||||||
@@ -84,6 +84,14 @@ export const makeSocket = ({
|
|||||||
return sendRawMessage(buff)
|
return sendRawMessage(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** log & process any unexpected errors */
|
||||||
|
const onUnexpectedError = (error: Error, msg: string) => {
|
||||||
|
logger.error(
|
||||||
|
{ trace: error.stack, output: (error as any).output },
|
||||||
|
`unexpected error in '${msg}'`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/** await the next incoming message */
|
/** await the next incoming message */
|
||||||
const awaitNextMessage = async(sendMsg?: Uint8Array) => {
|
const awaitNextMessage = async(sendMsg?: Uint8Array) => {
|
||||||
if(ws.readyState !== ws.OPEN) {
|
if(ws.readyState !== ws.OPEN) {
|
||||||
@@ -200,7 +208,11 @@ export const makeSocket = ({
|
|||||||
startKeepAliveRequest()
|
startKeepAliveRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get some pre-keys and do something with them */
|
/**
|
||||||
|
* get some pre-keys and do something with them
|
||||||
|
* @param range how many pre-keys to get
|
||||||
|
* @param execute what to do with them
|
||||||
|
*/
|
||||||
const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise<void>) => {
|
const assertingPreKeys = async(range: number, execute: (keys: { [_: number]: any }) => Promise<void>) => {
|
||||||
const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState.creds, range)
|
const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(authState.creds, range)
|
||||||
|
|
||||||
@@ -558,6 +570,7 @@ export const makeSocket = ({
|
|||||||
sendNode,
|
sendNode,
|
||||||
logout,
|
logout,
|
||||||
end,
|
end,
|
||||||
|
onUnexpectedError,
|
||||||
/** Waits for the connection to WA to reach a state */
|
/** Waits for the connection to WA to reach a state */
|
||||||
waitForConnectionUpdate: bindWaitForConnectionUpdate(ev)
|
waitForConnectionUpdate: bindWaitForConnectionUpdate(ev)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user