Deprecated message-new & message-update + fix presence update for groups

The chat-update event is fired now when a message is received/updated
This commit is contained in:
Adhiraj Singh
2020-11-13 16:07:08 +05:30
parent eaf56f6d71
commit eace0c1795
6 changed files with 59 additions and 39 deletions

View File

@@ -47,8 +47,11 @@ async function example() {
const participant = json.participant ? ' (' + json.participant + ')' : '' // participant exists when the message is from a group
console.log(`${json.to}${participant} acknlowledged message(s) ${json.ids} as ${json.type}`)
})
// set to false to NOT relay your own sent messages
conn.on('message-new', async (m) => {
conn.on('chat-update', async chat => {
// only do something when a new message is received; i.e. the unread count is updated
if (!chat.count) return
const m = chat.messages.all()[0] // pull the new message from the update
const messageStubType = WA_MESSAGE_STUB_TYPES[m.messageStubType] || 'MESSAGE'
console.log('got notification of type: ' + messageStubType)

View File

@@ -182,6 +182,8 @@ Also, these events are fired regardless of whether they are initiated by the Bai
on (event: 'open', listener: (result: WAOpenResult) => void): this
/** when the connection is opening */
on (event: 'connecting', listener: () => void): this
/** when the connection has been validated */
on (event: 'connection-validated', listener: (user: WAUser) => void): this
/** when the connection has closed */
on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this
/** when the socket is closed */
@@ -198,12 +200,8 @@ on (event: 'user-presence-update', listener: (update: PresenceUpdate) => void):
on (event: 'user-status-update', listener: (update: {jid: string, status?: string}) => void): this
/** when a new chat is added */
on (event: 'chat-new', listener: (chat: WAChat) => void): this
/** when a chat is updated (archived, deleted, pinned) */
on (event: 'chat-update', listener: (chat: Partial<WAChat> & { jid: string }) => void): this
/** when a new message is relayed */
on (event: 'message-new', listener: (message: WAMessage) => void): this
/** when a message object itself is updated (receives its media info or is deleted) */
on (event: 'message-update', listener: (message: WAMessage) => void): this
/** when a chat is updated (new message, updated message, deleted, pinned, etc) */
on (event: 'chat-update', listener: (chat: WAChatUpdate) => void): this
/** when a message's status is updated (deleted, delivered, read, sent etc.) */
on (event: 'message-status-update', listener: (message: WAMessageStatusUpdate) => void): this
/** when participants are added to a group */

View File

@@ -189,7 +189,7 @@ export class WAConnection extends Base {
chat.jid = Utils.whatsappID (chat.jid)
chat.t = +chat.t
chat.count = +chat.count
chat.messages = new KeyedDB (Utils.waMessageKey, Utils.WA_MESSAGE_ID)
chat.messages = Utils.newMessagesDB()
// chats data (log json to see what it looks like)
!chats.get (chat.jid) && chats.insert (chat)

View File

@@ -1,7 +1,7 @@
import * as QR from 'qrcode-terminal'
import { WAConnection as Base } from './3.Connect'
import { WAMessageStatusUpdate, WAMessage, WAContact, WAChat, WAMessageProto, WA_MESSAGE_STUB_TYPE, WA_MESSAGE_STATUS_TYPE, PresenceUpdate, BaileysEvent, DisconnectReason, WANode, WAOpenResult, Presence, AuthenticationCredentials, WAParticipantAction, WAGroupMetadata } from './Constants'
import { whatsappID, unixTimestampSeconds, isGroupID, GET_MESSAGE_ID, WA_MESSAGE_ID, waMessageKey } from './Utils'
import { WAMessageStatusUpdate, WAMessage, WAContact, WAChat, WAMessageProto, WA_MESSAGE_STUB_TYPE, WA_MESSAGE_STATUS_TYPE, PresenceUpdate, BaileysEvent, DisconnectReason, WAOpenResult, Presence, AuthenticationCredentials, WAParticipantAction, WAGroupMetadata, WAUser } from './Constants'
import { whatsappID, unixTimestampSeconds, isGroupID, GET_MESSAGE_ID, WA_MESSAGE_ID, waMessageKey, newMessagesDB } from './Utils'
import KeyedDB from '@adiwajshing/keyed-db'
import { Mutex } from './Mutex'
@@ -41,8 +41,8 @@ export class WAConnection extends Base {
// presence updates
this.on('CB:Presence', json => {
const update = json[1] as PresenceUpdate
const jid = whatsappID(update.participant || update.id)
const jid = whatsappID(update.id)
const contact = this.contacts[jid]
if (contact && jid.endsWith('@s.whatsapp.net')) { // if its a single chat
if (update.t) contact.lastSeen = +update.t
@@ -66,6 +66,10 @@ export class WAConnection extends Base {
message['epoch'] = oldMessage['epoch']
chat.messages.delete (oldMessage)
chat.messages.insert (message)
const chatUpdate: Partial<WAChat> = { jid, messages: newMessagesDB([ message ]) }
this.emit ('chat-update', chatUpdate)
// emit deprecated
this.emit ('message-update', message)
} else {
this.logger.debug ({ unhandled: true }, 'received message update for non-present message from ' + jid)
@@ -236,15 +240,21 @@ export class WAConnection extends Base {
this.chatAddMessage (message, chat)
}
protected chatAddMessage (message: WAMessage, chat: WAChat) {
// store updates in this
const chatUpdate: Partial<WAChat> & { jid: string } = { jid: chat.jid }
// add to count if the message isn't from me & there exists a message
if (!message.key.fromMe && message.message) {
chat.count += 1
const contact = this.contacts[chat.jid]
chatUpdate.count = chat.count
const contact = this.contacts[message.participant || chat.jid]
if (contact && contact.lastKnownPresence === Presence.composing) { // update presence
contact.lastKnownPresence = Presence.available // emit change
this.emit ('user-presence-update', { id: chat.jid, presence: Presence.available, participant: message.participant })
}
}
const messages = chat.messages
const protocolMessage = message.message?.protocolMessage
// if it's a message to delete another message
if (protocolMessage) {
@@ -256,17 +266,16 @@ export class WAConnection extends Base {
found.messageStubType = WA_MESSAGE_STUB_TYPE.REVOKE
delete found.message
this.emit ('message-update', found)
chatUpdate.messages = newMessagesDB([ found ])
// emit deprecated
this.emit('message-update', found)
}
break
default:
break
}
} else {
const messages = chat.messages
// if the message is already there
if (messages.get(WA_MESSAGE_ID(message))) return
} else if (!messages.get(WA_MESSAGE_ID(message))) { // if the message is not already there
const last = messages.all().slice(-1)
const lastEpoch = ((last && last[0]) && last[0]['epoch']) || 0
message['epoch'] = lastEpoch+1
@@ -277,9 +286,13 @@ export class WAConnection extends Base {
messages.delete (messages.all()[0]) // delete oldest messages
}
// only update if it's an actual message
if (message.message) this.chatUpdateTime (chat)
this.emit ('message-new', message)
if (message.message) {
this.chatUpdateTime (chat)
chatUpdate.t = chat.t
}
chatUpdate.messages = newMessagesDB([ message ])
// emit deprecated
this.emit('message-new', message)
// check if the message is an action
if (message.messageStubType) {
@@ -297,7 +310,7 @@ export class WAConnection extends Base {
// mark the chat read only if you left the group
if (participants.includes(this.user.jid)) {
chat.read_only = 'true'
this.emit ('chat-update', { jid, read_only: chat.read_only })
chatUpdate.read_only = 'true'
}
break
case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_ADD:
@@ -306,7 +319,7 @@ export class WAConnection extends Base {
participants = message.messageStubParameters.map (whatsappID)
if (participants.includes(this.user.jid) && chat.read_only === 'true') {
delete chat.read_only
this.emit ('chat-update', { jid, read_only: 'false' })
chatUpdate.read_only = 'false'
}
emitParticipantsUpdate('add')
break
@@ -325,20 +338,13 @@ export class WAConnection extends Base {
case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_SUBJECT:
case WA_MESSAGE_STUB_TYPE.GROUP_CREATE:
chat.name = message.messageStubParameters[0]
this.emit ('chat-update', { jid, name: chat.name })
break
case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_PROMOTE:
case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_DEMOTE:
participants = message.messageStubParameters.map (whatsappID)
emitParticipantsUpdate(
WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_PROMOTE ?
'promote' :
'demote'
)
chatUpdate.name = chat.name
break
}
}
}
this.emit('chat-update', chatUpdate)
}
protected chatUpdatedMessage (messageIDs: string[], status: WA_MESSAGE_STATUS_TYPE, chat: WAChat) {
for (let id of messageIDs) {
@@ -362,6 +368,8 @@ export class WAConnection extends Base {
on (event: 'open', listener: (result: WAOpenResult) => void): this
/** when the connection is opening */
on (event: 'connecting', listener: () => void): this
/** when the connection has been validated */
on (event: 'connection-validated', listener: (user: WAUser) => void): this
/** when the connection has closed */
on (event: 'close', listener: (err: {reason?: DisconnectReason | string, isReconnecting: boolean}) => void): this
/** when the socket is closed */
@@ -378,11 +386,17 @@ export class WAConnection extends Base {
on (event: 'user-status-update', listener: (update: {jid: string, status?: string}) => void): this
/** when a new chat is added */
on (event: 'chat-new', listener: (chat: WAChat) => void): this
/** when a chat is updated (archived, deleted, pinned) */
/** when a chat is updated (new message, updated message, deleted, pinned, etc) */
on (event: 'chat-update', listener: (chat: Partial<WAChat> & { jid: string }) => void): this
/** when a new message is relayed */
/**
* when a new message is relayed
* @deprecated use `chat-update`
* */
on (event: 'message-new', listener: (message: WAMessage) => void): this
/** when a message object itself is updated (receives its media info or is deleted) */
/**
* when a message object itself is updated (receives its media info or is deleted)
* @deprecated use `chat-update`
* */
on (event: 'message-update', listener: (message: WAMessage) => void): this
/** when a message's status is updated (deleted, delivered, read, sent etc.) */
on (event: 'message-status-update', listener: (message: WAMessageStatusUpdate) => void): this

View File

@@ -425,8 +425,6 @@ export type BaileysEvent =
'user-status-update' |
'chat-new' |
'chat-update' |
'message-new' |
'message-update' |
'message-status-update' |
'group-participants-update' |
'group-update' |

View File

@@ -9,6 +9,7 @@ import { URL } from 'url'
import { Agent } from 'https'
import Decoder from '../Binary/Decoder'
import { MessageType, HKDFInfoKeys, MessageOptions, WAChat, WAMessageContent, BaileysError, WAMessageProto, TimedOutError, CancelledError, WAGenericMediaMessage, WAMessage, WAMessageKey } from './Constants'
import KeyedDB from '@adiwajshing/keyed-db'
const platformMap = {
'aix': 'AIX',
@@ -38,6 +39,12 @@ export const GET_MESSAGE_ID = (key: WAMessageKey) => `${key.id}|${key.fromMe ? 1
export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net')
export const isGroupID = (jid: string) => jid?.endsWith ('@g.us')
export const newMessagesDB = (messages: WAMessage[] = []) => {
const db = new KeyedDB(waMessageKey, WA_MESSAGE_ID)
messages.forEach(m => db.insert(m))
return db
}
export function shallowChanges <T> (old: T, current: T): Partial<T> {
let changes: Partial<T> = {}
for (let key in current) {