separate data structure for presence

This commit is contained in:
Adhiraj Singh
2021-08-24 11:00:37 +05:30
parent 48f477e0c1
commit 8a014df1c5
5 changed files with 32 additions and 36 deletions

View File

@@ -1,5 +1,5 @@
import BinaryNode from "../BinaryNode"; import BinaryNode from "../BinaryNode";
import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate } from "../Types"; import { Chat, Contact, Presence, PresenceData, SocketConfig, WAFlag, WAMetric, WABusinessProfile, ChatModification, WAMessageKey, WAMessage, WAMessageUpdate, BaileysEventMap } from "../Types";
import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics"; import { debouncedTimeout, unixTimestampSeconds, whatsappID } from "../Utils/generics";
import makeAuthSocket from "./auth"; import makeAuthSocket from "./auth";
import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types"; import { Attributes, BinaryNode as BinaryNodeBase } from "../BinaryNode/types";
@@ -91,26 +91,15 @@ const makeChatsSocket = (config: SocketConfig) => {
} }
} }
const applyingPresenceUpdate = (update: Attributes, chat: Partial<Chat>) => { const applyingPresenceUpdate = (update: Attributes): BaileysEventMap['presence.update'] => {
chat.jid = whatsappID(update.id) const jid = whatsappID(update.id)
const jid = whatsappID(update.participant || update.id) const participant = whatsappID(update.participant || update.id)
if (jid.endsWith('@s.whatsapp.net')) { // if its a single chat const presence: PresenceData = {
chat.presences = chat.presences || {} lastSeen: update.t ? +update.t : undefined,
lastKnownPresence: update.type as Presence
const presence = { } as PresenceData }
return { jid, presences: { [participant]: presence } }
if(update.t) {
presence.lastSeen = +update.t
}
presence.lastKnownPresence = update.type as Presence
chat.presences[jid] = presence
chat.presences = {
[jid]: presence
}
}
return chat
} }
ev.on('connection.update', async({ connection }) => { ev.on('connection.update', async({ connection }) => {
@@ -239,8 +228,8 @@ const makeChatsSocket = (config: SocketConfig) => {
// presence updates // presence updates
socketEvents.on('CB:Presence', json => { socketEvents.on('CB:Presence', json => {
const chat = applyingPresenceUpdate(json[1], { }) const update = applyingPresenceUpdate(json[1])
ev.emit('chats.update', [ chat ]) ev.emit('presence.update', update)
}) })
// blocklist updates // blocklist updates

View File

@@ -119,11 +119,14 @@ const makeMessagesSocket = (config: SocketConfig) => {
if(!message.key.fromMe && message.message) { if(!message.key.fromMe && message.message) {
chatUpdate.count = 1 chatUpdate.count = 1
const participant = whatsappID(message.participant || jid) const participant = whatsappID(message.participant || jid)
chatUpdate.presences = {
[participant]: { ev.emit(
lastKnownPresence: Presence.available 'presence.update',
{
jid,
presences: { [participant]: { lastKnownPresence: Presence.available } }
} }
} )
} }
const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage const ephemeralProtocolMsg = message.message?.ephemeralMessage?.message?.protocolMessage

View File

@@ -2,7 +2,7 @@ import type KeyedDB from "@adiwajshing/keyed-db"
import type { Comparable } from "@adiwajshing/keyed-db/lib/Types" import type { Comparable } from "@adiwajshing/keyed-db/lib/Types"
import type { Logger } from "pino" import type { Logger } from "pino"
import type { Connection } from "../Connection" import type { Connection } from "../Connection"
import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, WAMessage, WAMessageCursor, WAMessageKey } from "../Types" import type { BaileysEventEmitter, Chat, ConnectionState, Contact, GroupMetadata, MessageInfo, PresenceData, WAMessage, WAMessageCursor, WAMessageKey } from "../Types"
import { toNumber } from "../Utils" import { toNumber } from "../Utils"
import makeOrderedDictionary from "./ordered-dictionary" import makeOrderedDictionary from "./ordered-dictionary"
@@ -25,10 +25,11 @@ export default(
) => { ) => {
const KeyedDBConstructor = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB<Chat, string> const KeyedDBConstructor = require('@adiwajshing/keyed-db').default as new (...args: any[]) => KeyedDB<Chat, string>
const chats = new KeyedDBConstructor(chatKey, c => c.jid) const chats = new KeyedDBConstructor(chatKey, c => c.jid)
const messages: { [_: string]: ReturnType<typeof makeMessagesDictionary> } = {} const messages: { [_: string]: ReturnType<typeof makeMessagesDictionary> } = { }
const contacts: { [_: string]: Contact } = {} const contacts: { [_: string]: Contact } = { }
const groupMetadata: { [_: string]: GroupMetadata } = {} const groupMetadata: { [_: string]: GroupMetadata } = { }
const messageInfos: { [id: string]: MessageInfo } = { } const messageInfos: { [id: string]: MessageInfo } = { }
const presences: { [id: string]: { [participant: string]: PresenceData } } = { }
const state: ConnectionState = { const state: ConnectionState = {
connection: 'close', connection: 'close',
phoneConnected: false phoneConnected: false
@@ -88,6 +89,10 @@ export default(
} }
} }
}) })
ev.on('presence.update', ({ jid, presences: update }) => {
presences[jid] = presences[jid] || {}
Object.assign(presences[jid], update)
})
ev.on('chats.delete', deletions => { ev.on('chats.delete', deletions => {
for(const item of deletions) { for(const item of deletions) {
chats.deleteById(item) chats.deleteById(item)
@@ -207,6 +212,7 @@ export default(
groupMetadata, groupMetadata,
messageInfos, messageInfos,
state, state,
presences,
listen, listen,
loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => { loadMessages: async(jid: string, count: number, cursor: WAMessageCursor, sock: Connection | undefined) => {
const list = assertMessageList(jid) const list = assertMessageList(jid)

View File

@@ -8,9 +8,8 @@ export enum Presence {
} }
export interface PresenceData { export interface PresenceData {
lastKnownPresence?: Presence lastKnownPresence: Presence
lastSeen?: number lastSeen?: number
name?: string
} }
export interface Chat { export interface Chat {
@@ -31,9 +30,6 @@ export interface Chat {
eph_setting_ts?: string eph_setting_ts?: string
/** how long each message lasts for */ /** how long each message lasts for */
ephemeral?: string ephemeral?: string
// Baileys added properties
presences?: { [k: string]: PresenceData }
} }
export type ChatModification = export type ChatModification =

View File

@@ -11,7 +11,7 @@ import type { Logger } from "pino"
import type { URL } from "url" import type { URL } from "url"
import type BinaryNode from "../BinaryNode" import type BinaryNode from "../BinaryNode"
import { AnyAuthenticationCredentials, AuthenticationCredentials } from './Auth' import { AnyAuthenticationCredentials, AuthenticationCredentials } from './Auth'
import { Chat } from './Chat' import { Chat, PresenceData } from './Chat'
import { Contact } from './Contact' import { Contact } from './Contact'
import { ConnectionState } from './Store' import { ConnectionState } from './Store'
@@ -176,6 +176,8 @@ export type BaileysEventMap = {
'chats.update': Partial<Chat>[] 'chats.update': Partial<Chat>[]
'chats.delete': string[] 'chats.delete': string[]
'presence.update': { jid: string, presences: { [participant: string]: PresenceData } }
'contacts.set': { contacts: Contact[] } 'contacts.set': { contacts: Contact[] }
'contacts.upsert': Contact[] 'contacts.upsert': Contact[]
'contacts.update': Partial<Contact>[] 'contacts.update': Partial<Contact>[]