mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
better presence handling via chat-update
This commit is contained in:
@@ -47,12 +47,14 @@ async function example() {
|
||||
|
||||
/* Note: one can take this auth_info.json file and login again from any computer without having to scan the QR code,
|
||||
and get full access to one's WhatsApp. Despite the convenience, be careful with this file */
|
||||
conn.on ('user-presence-update', json => console.log(json.id + ' presence is ' + json.type))
|
||||
conn.on ('message-status-update', json => {
|
||||
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}`)
|
||||
})
|
||||
conn.on('chat-update', async chat => {
|
||||
if (chat.presences) { // receive presence updates -- composing, available, etc.
|
||||
Object.keys(chat.presences).forEach(jid => console.log( `${jid}'s presence is ${chat.presences[jid].lastKnownPresence} in ${chat.jid}`))
|
||||
}
|
||||
// only do something when a new message is received; i.e. the unread count is updated
|
||||
if (!chat.count) return
|
||||
|
||||
|
||||
@@ -195,8 +195,6 @@ on (event: 'credentials-updated', listener: (auth: AuthenticationCredentials) =>
|
||||
on (event: 'qr', listener: (qr: string) => void): this
|
||||
/** when the connection to the phone changes */
|
||||
on (event: 'connection-phone-change', listener: (state: {connected: boolean}) => void): this
|
||||
/** when a user's presence is updated */
|
||||
on (event: 'user-presence-update', listener: (update: PresenceUpdate) => void): this
|
||||
/** when a user's status is updated */
|
||||
on (event: 'user-status-update', listener: (update: {jid: string, status?: string}) => void): this
|
||||
/** when a new chat is added */
|
||||
@@ -207,7 +205,7 @@ on (event: 'contacts-received', listener: () => void): this
|
||||
on (event: 'chats-received', listener: (update: {hasNewChats: boolean}) => void): this
|
||||
/** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */
|
||||
on (event: 'chats-update', listener: (chats: (Partial<WAChat> & { jid: string })[]) => void): this
|
||||
/** when a chat is updated (new message, updated message, deleted, pinned, etc) */
|
||||
/** when a chat is updated (new message, updated message, deleted, pinned, presence updated etc) */
|
||||
on (event: 'chat-update', listener: (chat: Partial<WAChat> & { jid: string }) => void): this
|
||||
/** when a message's status is updated (deleted, delivered, read, sent etc.) */
|
||||
on (event: 'message-status-update', listener: (message: WAMessageStatusUpdate) => void): this
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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, WAOpenResult, Presence, AuthenticationCredentials, WAParticipantAction, WAGroupMetadata, WAUser, WANode } from './Constants'
|
||||
import { WAMessageStatusUpdate, WAMessage, WAContact, WAChat, WAMessageProto, WA_MESSAGE_STUB_TYPE, WA_MESSAGE_STATUS_TYPE, PresenceUpdate, BaileysEvent, DisconnectReason, WAOpenResult, Presence, AuthenticationCredentials, WAParticipantAction, WAGroupMetadata, WAUser, WANode, WAPresenceData } from './Constants'
|
||||
import { whatsappID, unixTimestampSeconds, isGroupID, GET_MESSAGE_ID, WA_MESSAGE_ID, waMessageKey, newMessagesDB, shallowChanges, toNumber } from './Utils'
|
||||
import KeyedDB from '@adiwajshing/keyed-db'
|
||||
import { Mutex } from './Mutex'
|
||||
@@ -157,19 +157,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 contact = this.contacts[jid]
|
||||
if (contact && jid.endsWith('@s.whatsapp.net')) { // if its a single chat
|
||||
if (update.t) contact.lastSeen = +update.t
|
||||
else if (update.type === Presence.unavailable && contact.lastKnownPresence !== Presence.unavailable) {
|
||||
contact.lastSeen = unixTimestampSeconds()
|
||||
}
|
||||
contact.lastKnownPresence = update.type
|
||||
}
|
||||
|
||||
this.emit('user-presence-update', update)
|
||||
const chatUpdate = this.applyingPresenceUpdate(json[1])
|
||||
chatUpdate && this.emit('chat-update', chatUpdate)
|
||||
})
|
||||
// If a message has been updated (usually called when a video message gets its upload url, or live locations)
|
||||
this.on ('CB:action,add:update,message', json => {
|
||||
@@ -320,6 +309,30 @@ export class WAConnection extends Base {
|
||||
const response = await this.query({ json: ['query', 'ProfilePicThumb', jid || this.user.jid], expect200: true, requiresPhoneConnection: false })
|
||||
return response.eurl as string
|
||||
}
|
||||
protected applyingPresenceUpdate(update: PresenceUpdate) {
|
||||
const chatId = update.id
|
||||
const jid = whatsappID(update.participant || update.id)
|
||||
// emit deprecated
|
||||
this.emit('user-presence-update', update)
|
||||
|
||||
const contact = this.contacts[jid]
|
||||
if (contact && jid.endsWith('@s.whatsapp.net')) { // if its a single chat
|
||||
if (update.t) contact.lastSeen = +update.t
|
||||
else if (update.type === Presence.unavailable && contact.lastKnownPresence !== Presence.unavailable) {
|
||||
contact.lastSeen = unixTimestampSeconds()
|
||||
}
|
||||
contact.lastKnownPresence = update.type
|
||||
const presence: WAPresenceData = { lastKnownPresence: contact.lastKnownPresence, lastSeen: contact.lastSeen }
|
||||
|
||||
const chat = this.chats.get(chatId)
|
||||
if (chat) {
|
||||
chat.presences = chat.presences || {}
|
||||
chat.presences[jid] = presence
|
||||
|
||||
return { jid: chatId, presences: { [jid]: presence } } as Partial<WAChat>
|
||||
}
|
||||
}
|
||||
}
|
||||
protected forwardStatusUpdate (update: WAMessageStatusUpdate) {
|
||||
const chat = this.chats.get( whatsappID(update.to) )
|
||||
if (!chat) return
|
||||
@@ -368,10 +381,11 @@ export class WAConnection extends Base {
|
||||
if (!message.key.fromMe && message.message) {
|
||||
chat.count += 1
|
||||
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 })
|
||||
if (contact.lastKnownPresence === Presence.composing) { // update presence
|
||||
const update = this.applyingPresenceUpdate({ id: chat.jid, participant: message.participant || chat.jid, type: Presence.available })
|
||||
update && Object.assign(chatUpdate, update)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,7 +515,10 @@ export class WAConnection extends Base {
|
||||
on (event: 'qr', listener: (qr: string) => void): this
|
||||
/** when the connection to the phone changes */
|
||||
on (event: 'connection-phone-change', listener: (state: {connected: boolean}) => void): this
|
||||
/** when a user's presence is updated */
|
||||
/**
|
||||
* when a user's presence is updated
|
||||
* @deprecated use `chat-update`
|
||||
* */
|
||||
on (event: 'user-presence-update', listener: (update: PresenceUpdate) => void): this
|
||||
/** when a user's status is updated */
|
||||
on (event: 'user-status-update', listener: (update: {jid: string, status?: string}) => void): this
|
||||
@@ -513,7 +530,7 @@ export class WAConnection extends Base {
|
||||
on (event: 'chats-received', listener: (update: {hasNewChats: boolean}) => void): this
|
||||
/** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */
|
||||
on (event: 'chats-update', listener: (chats: (Partial<WAChat> & { jid: string })[]) => void): this
|
||||
/** when a chat is updated (new message, updated message, deleted, pinned, etc) */
|
||||
/** when a chat is updated (new message, updated message, deleted, pinned, presence updated etc) */
|
||||
on (event: 'chat-update', listener: (chat: Partial<WAChat> & { jid: string }) => void): this
|
||||
/**
|
||||
* when a new message is relayed
|
||||
|
||||
@@ -177,8 +177,11 @@ export interface WAGroupModification {
|
||||
status: number
|
||||
participants?: { [key: string]: any }
|
||||
}
|
||||
|
||||
export interface WAContact {
|
||||
export interface WAPresenceData {
|
||||
lastKnownPresence?: Presence
|
||||
lastSeen?: number
|
||||
}
|
||||
export interface WAContact extends WAPresenceData {
|
||||
verify?: string
|
||||
/** name of the contact, the contact has set on their own on WA */
|
||||
notify?: string
|
||||
@@ -192,8 +195,6 @@ export interface WAContact {
|
||||
short?: string
|
||||
// Baileys Added
|
||||
imgUrl?: string
|
||||
lastKnownPresence?: Presence
|
||||
lastSeen?: number
|
||||
}
|
||||
export interface WAUser extends WAContact {
|
||||
phone: any
|
||||
@@ -215,6 +216,7 @@ export interface WAChat {
|
||||
// Baileys added properties
|
||||
messages: KeyedDB<WAMessage, string>
|
||||
imgUrl?: string
|
||||
presences?: { [k: string]: WAPresenceData }
|
||||
}
|
||||
export enum WAMetric {
|
||||
debugLog = 1,
|
||||
@@ -426,7 +428,6 @@ export type BaileysEvent =
|
||||
'ws-close' |
|
||||
'qr' |
|
||||
'connection-phone-change' |
|
||||
'user-presence-update' |
|
||||
'user-status-update' |
|
||||
'contacts-received' |
|
||||
'chats-received' |
|
||||
|
||||
Reference in New Issue
Block a user