mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Manage group metdata state in Baileys + Remove presence from Contact
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@adiwajshing/baileys",
|
"name": "@adiwajshing/baileys",
|
||||||
"version": "3.3.1",
|
"version": "3.3.2",
|
||||||
"description": "WhatsApp Web API",
|
"description": "WhatsApp Web API",
|
||||||
"homepage": "https://github.com/adiwajshing/Baileys",
|
"homepage": "https://github.com/adiwajshing/Baileys",
|
||||||
"main": "lib/WAConnection/WAConnection.js",
|
"main": "lib/WAConnection/WAConnection.js",
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ export const makeConnection = () => {
|
|||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sendAndRetreiveMessage(conn: WAConnection, content, type: MessageType, options: MessageOptions = {}) {
|
export async function sendAndRetreiveMessage(conn: WAConnection, content, type: MessageType, options: MessageOptions = {}, recipientJid = testJid) {
|
||||||
const response = await conn.sendMessage(testJid, content, type, options)
|
const response = await conn.sendMessage(recipientJid, content, type, options)
|
||||||
const {messages} = await conn.loadMessages(testJid, 10)
|
const {messages} = await conn.loadMessages(recipientJid, 10)
|
||||||
const message = messages.find (m => m.key.id === response.key.id)
|
const message = messages.find (m => m.key.id === response.key.id)
|
||||||
assert.ok(message)
|
assert.ok(message)
|
||||||
|
|
||||||
const chat = conn.chats.get(testJid)
|
const chat = conn.chats.get(recipientJid)
|
||||||
|
|
||||||
assert.ok (chat.messages.get(GET_MESSAGE_ID(message.key)))
|
assert.ok (chat.messages.get(GET_MESSAGE_ID(message.key)))
|
||||||
assert.ok (chat.t >= (unixTimestampSeconds()-5) )
|
assert.ok (chat.t >= (unixTimestampSeconds()-5) )
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { MessageType, GroupSettingChange, delay, ChatModification, whatsappID } from '../WAConnection/WAConnection'
|
import { MessageType, GroupSettingChange, delay, ChatModification, whatsappID } from '../WAConnection/WAConnection'
|
||||||
import * as assert from 'assert'
|
import * as assert from 'assert'
|
||||||
import { WAConnectionTest, testJid } from './Common'
|
import { WAConnectionTest, testJid, sendAndRetreiveMessage } from './Common'
|
||||||
|
|
||||||
WAConnectionTest('Groups', (conn) => {
|
WAConnectionTest('Groups', (conn) => {
|
||||||
let gid: string
|
let gid: string
|
||||||
it('should create a group', async () => {
|
it('should create a group', async () => {
|
||||||
const response = await conn.groupCreate('Cool Test Group', [testJid])
|
const response = await conn.groupCreate('Cool Test Group', [testJid])
|
||||||
assert.ok (conn.chats.get(response.gid))
|
assert.ok (conn.chats.get(response.gid))
|
||||||
|
|
||||||
const {chats} = await conn.loadChats(10, null)
|
const {chats} = await conn.loadChats(10, null)
|
||||||
assert.strictEqual (chats[0].jid, response.gid) // first chat should be new group
|
assert.strictEqual (chats[0].jid, response.gid) // first chat should be new group
|
||||||
|
|
||||||
@@ -24,18 +24,24 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
const metadata = await conn.groupMetadata(gid)
|
const metadata = await conn.groupMetadata(gid)
|
||||||
assert.strictEqual(metadata.id, gid)
|
assert.strictEqual(metadata.id, gid)
|
||||||
assert.strictEqual(metadata.participants.filter((obj) => obj.id.split('@')[0] === testJid.split('@')[0]).length, 1)
|
assert.strictEqual(metadata.participants.filter((obj) => obj.id.split('@')[0] === testJid.split('@')[0]).length, 1)
|
||||||
|
assert.ok(conn.chats.get(gid))
|
||||||
|
assert.ok(conn.chats.get(gid).metadata)
|
||||||
})
|
})
|
||||||
it('should update the group description', async () => {
|
it('should update the group description', async () => {
|
||||||
const newDesc = 'Wow this was set from Baileys'
|
const newDesc = 'Wow this was set from Baileys'
|
||||||
|
|
||||||
const waitForEvent = new Promise (resolve => {
|
const waitForEvent = new Promise (resolve => (
|
||||||
conn.once ('group-update', ({jid, actor}) => {
|
conn.once ('group-update', ({jid, desc}) => {
|
||||||
if (jid === gid) {
|
if (jid === gid && desc) {
|
||||||
assert.ok (actor, conn.user.jid)
|
assert.strictEqual(desc, newDesc)
|
||||||
|
assert.strictEqual(
|
||||||
|
conn.chats.get(jid).metadata.desc,
|
||||||
|
newDesc
|
||||||
|
)
|
||||||
resolve ()
|
resolve ()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
))
|
||||||
await conn.groupUpdateDescription (gid, newDesc)
|
await conn.groupUpdateDescription (gid, newDesc)
|
||||||
await waitForEvent
|
await waitForEvent
|
||||||
|
|
||||||
@@ -43,7 +49,7 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
assert.strictEqual(metadata.desc, newDesc)
|
assert.strictEqual(metadata.desc, newDesc)
|
||||||
})
|
})
|
||||||
it('should send a message on the group', async () => {
|
it('should send a message on the group', async () => {
|
||||||
await conn.sendMessage(gid, 'hello', MessageType.text)
|
await sendAndRetreiveMessage(conn, 'Hello!', MessageType.text, {}, gid)
|
||||||
})
|
})
|
||||||
it('should quote a message on the group', async () => {
|
it('should quote a message on the group', async () => {
|
||||||
const {messages} = await conn.loadMessages (gid, 100)
|
const {messages} = await conn.loadMessages (gid, 100)
|
||||||
@@ -61,7 +67,8 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
const waitForEvent = new Promise (resolve => {
|
const waitForEvent = new Promise (resolve => {
|
||||||
conn.once ('chat-update', ({jid, name}) => {
|
conn.once ('chat-update', ({jid, name}) => {
|
||||||
if (jid === gid) {
|
if (jid === gid) {
|
||||||
assert.strictEqual (name, subject)
|
assert.strictEqual(name, subject)
|
||||||
|
assert.strictEqual(conn.chats.get(jid).name, subject)
|
||||||
resolve ()
|
resolve ()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -78,6 +85,7 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
conn.once ('group-update', ({jid, announce}) => {
|
conn.once ('group-update', ({jid, announce}) => {
|
||||||
if (jid === gid) {
|
if (jid === gid) {
|
||||||
assert.strictEqual (announce, 'true')
|
assert.strictEqual (announce, 'true')
|
||||||
|
assert.strictEqual(conn.chats.get(gid).metadata.announce, announce)
|
||||||
resolve ()
|
resolve ()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -85,7 +93,7 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
await conn.groupSettingChange (gid, GroupSettingChange.messageSend, true)
|
await conn.groupSettingChange (gid, GroupSettingChange.messageSend, true)
|
||||||
|
|
||||||
await waitForEvent
|
await waitForEvent
|
||||||
conn.removeAllListeners ('group-settings-update')
|
conn.removeAllListeners ('group-update')
|
||||||
|
|
||||||
await delay (2000)
|
await delay (2000)
|
||||||
await conn.groupSettingChange (gid, GroupSettingChange.settingsChange, true)
|
await conn.groupSettingChange (gid, GroupSettingChange.settingsChange, true)
|
||||||
@@ -93,10 +101,17 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
|
|
||||||
it('should promote someone', async () => {
|
it('should promote someone', async () => {
|
||||||
const waitForEvent = new Promise (resolve => {
|
const waitForEvent = new Promise (resolve => {
|
||||||
conn.once ('group-participants-update', ({ jid, action }) => {
|
conn.once ('group-participants-update', ({ jid, action, participants }) => {
|
||||||
if (jid === gid) {
|
if (jid === gid) {
|
||||||
assert.strictEqual (action, 'promote')
|
assert.strictEqual (action, 'promote')
|
||||||
resolve ()
|
console.log(participants)
|
||||||
|
console.log(conn.chats.get(jid).metadata)
|
||||||
|
assert.ok(
|
||||||
|
conn.chats.get(jid).metadata.participants.find(({ id, isAdmin }) => (
|
||||||
|
whatsappID(id) === whatsappID(participants[0]) && isAdmin
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -113,6 +128,10 @@ WAConnectionTest('Groups', (conn) => {
|
|||||||
if (jid === gid) {
|
if (jid === gid) {
|
||||||
assert.strictEqual (participants[0], testJid)
|
assert.strictEqual (participants[0], testJid)
|
||||||
assert.strictEqual (action, 'remove')
|
assert.strictEqual (action, 'remove')
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
conn.chats.get(jid).metadata.participants.find(p => whatsappID(p.id) === whatsappID(participants[0])),
|
||||||
|
undefined
|
||||||
|
)
|
||||||
resolve ()
|
resolve ()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export class WAConnection extends Base {
|
|||||||
|
|
||||||
this.conn.on('message', data => this.onMessageRecieved(data as any))
|
this.conn.on('message', data => this.onMessageRecieved(data as any))
|
||||||
|
|
||||||
this.conn.on ('open', async () => {
|
this.conn.once('open', async () => {
|
||||||
this.startKeepAliveRequest()
|
this.startKeepAliveRequest()
|
||||||
this.logger.info(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`)
|
this.logger.info(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`)
|
||||||
|
|
||||||
@@ -109,8 +109,8 @@ export class WAConnection extends Base {
|
|||||||
)
|
)
|
||||||
|
|
||||||
this.conn
|
this.conn
|
||||||
.removeAllListeners ('error')
|
.removeAllListeners('error')
|
||||||
.removeAllListeners ('close')
|
.removeAllListeners('close')
|
||||||
this.stopDebouncedTimeout ()
|
this.stopDebouncedTimeout ()
|
||||||
resolve ({ ...authResult, ...chatsResult })
|
resolve ({ ...authResult, ...chatsResult })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ export class WAConnection extends Base {
|
|||||||
chat.messages = oldChat.messages
|
chat.messages = oldChat.messages
|
||||||
if (oldChat.t !== chat.t || oldChat.modify_tag !== chat.modify_tag) {
|
if (oldChat.t !== chat.t || oldChat.modify_tag !== chat.modify_tag) {
|
||||||
const changes = shallowChanges (oldChat, chat)
|
const changes = shallowChanges (oldChat, chat)
|
||||||
|
delete chat.metadata // remove group metadata as that may have changed; TODO, write better mechanism for this
|
||||||
delete changes.messages
|
delete changes.messages
|
||||||
|
|
||||||
updatedChats.push({ ...changes, jid: chat.jid })
|
updatedChats.push({ ...changes, jid: chat.jid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,22 +140,15 @@ export class WAConnection extends Base {
|
|||||||
// new messages
|
// new messages
|
||||||
this.on('CB:action,add:relay,message', json => {
|
this.on('CB:action,add:relay,message', json => {
|
||||||
const message = json[2][0][2] as WAMessage
|
const message = json[2][0][2] as WAMessage
|
||||||
const jid = whatsappID( message.key.remoteJid )
|
|
||||||
if (jid.endsWith('@s.whatsapp.net')) {
|
|
||||||
const contact = this.contacts[jid]
|
|
||||||
if (contact && contact?.lastKnownPresence === Presence.composing) {
|
|
||||||
contact.lastKnownPresence = Presence.available
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.chatAddMessageAppropriate (message)
|
this.chatAddMessageAppropriate (message)
|
||||||
})
|
})
|
||||||
this.on('CB:Chat,cmd:action', json => {
|
this.on('CB:Chat,cmd:action', json => {
|
||||||
const data = json[1].data
|
const data = json[1].data
|
||||||
if (data) {
|
if (data) {
|
||||||
const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emit(
|
const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate
|
||||||
'group-participants-update',
|
(json[1].id, data[2].participants.map(whatsappID), action)
|
||||||
{ participants: data[2].participants.map(whatsappID), actor: data[1], jid: json[1].id, action }
|
const emitGroupUpdate = (data: Partial<WAGroupMetadata>) => this.emitGroupUpdate(json[1].id, data)
|
||||||
)
|
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case "promote":
|
case "promote":
|
||||||
emitGroupParticipantsUpdate('promote')
|
emitGroupParticipantsUpdate('promote')
|
||||||
@@ -161,6 +156,12 @@ export class WAConnection extends Base {
|
|||||||
case "demote":
|
case "demote":
|
||||||
emitGroupParticipantsUpdate('demote')
|
emitGroupParticipantsUpdate('demote')
|
||||||
break
|
break
|
||||||
|
case "desc_add":
|
||||||
|
emitGroupUpdate({ ...data[2], descOwner: data[1] })
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this.logger.debug({ unhandled: true }, json)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -324,26 +325,24 @@ export class WAConnection extends Base {
|
|||||||
// emit deprecated
|
// emit deprecated
|
||||||
this.emit('user-presence-update', update)
|
this.emit('user-presence-update', update)
|
||||||
|
|
||||||
const contact = this.contacts[jid]
|
const chat = this.chats.get(chatId)
|
||||||
if (contact && jid.endsWith('@s.whatsapp.net')) { // if its a single chat
|
if (chat && jid.endsWith('@s.whatsapp.net')) { // if its a single chat
|
||||||
if (update.t) contact.lastSeen = +update.t
|
chat.presences = chat.presences || {}
|
||||||
else if (update.type === Presence.unavailable && contact.lastKnownPresence !== Presence.unavailable) {
|
|
||||||
contact.lastSeen = unixTimestampSeconds()
|
const presence = { ...(chat.presences[jid] || {}) } as WAPresenceData
|
||||||
}
|
if (update.t) presence.lastSeen = +update.t
|
||||||
contact.lastKnownPresence = update.type
|
else if (update.type === Presence.unavailable && presence.lastKnownPresence !== Presence.unavailable) {
|
||||||
const presence: WAPresenceData = {
|
presence.lastSeen = unixTimestampSeconds()
|
||||||
lastKnownPresence: contact.lastKnownPresence,
|
|
||||||
lastSeen: contact.lastSeen,
|
|
||||||
name: contact.name || contact.vname || contact.notify
|
|
||||||
}
|
}
|
||||||
|
presence.lastKnownPresence = update.type
|
||||||
|
|
||||||
const chat = this.chats.get(chatId)
|
const contact = this.contacts[jid]
|
||||||
if (chat) {
|
if (contact) {
|
||||||
chat.presences = chat.presences || {}
|
presence.name = contact.name || contact.notify || contact.vname
|
||||||
chat.presences[jid] = presence
|
|
||||||
|
|
||||||
return { jid: chatId, presences: { [jid]: presence } } as Partial<WAChat>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chat.presences[jid] = presence
|
||||||
|
return { jid: chatId, presences: { [jid]: presence } } as Partial<WAChat>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected forwardStatusUpdate (update: WAMessageStatusUpdate) {
|
protected forwardStatusUpdate (update: WAMessageStatusUpdate) {
|
||||||
@@ -366,12 +365,13 @@ export class WAConnection extends Base {
|
|||||||
spam: 'false',
|
spam: 'false',
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chats.insert (chat)
|
this.chats.insert (chat)
|
||||||
if (this.loadProfilePicturesForChatsAutomatically) {
|
if (this.loadProfilePicturesForChatsAutomatically) {
|
||||||
await this.setProfilePicture (chat)
|
await this.setProfilePicture (chat)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit ('chat-new', chat)
|
this.emit ('chat-new', chat)
|
||||||
|
|
||||||
return chat
|
return chat
|
||||||
}
|
}
|
||||||
/** find a chat or return an error */
|
/** find a chat or return an error */
|
||||||
@@ -395,9 +395,10 @@ export class WAConnection extends Base {
|
|||||||
chat.count += 1
|
chat.count += 1
|
||||||
chatUpdate.count = chat.count
|
chatUpdate.count = chat.count
|
||||||
|
|
||||||
const contact = this.contacts[message.participant || chat.jid]
|
const participant = whatsappID(message.participant || chat.jid)
|
||||||
|
const contact = chat.presences && chat.presences[participant]
|
||||||
if (contact?.lastKnownPresence === Presence.composing) { // update presence
|
if (contact?.lastKnownPresence === Presence.composing) { // update presence
|
||||||
const update = this.applyingPresenceUpdate({ id: chat.jid, participant: message.participant || chat.jid, type: Presence.available })
|
const update = this.applyingPresenceUpdate({ id: chat.jid, participant, type: Presence.available })
|
||||||
update && Object.assign(chatUpdate, update)
|
update && Object.assign(chatUpdate, update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,10 +447,12 @@ export class WAConnection extends Base {
|
|||||||
// check if the message is an action
|
// check if the message is an action
|
||||||
if (message.messageStubType) {
|
if (message.messageStubType) {
|
||||||
const jid = chat.jid
|
const jid = chat.jid
|
||||||
let actor = whatsappID (message.participant)
|
//let actor = whatsappID (message.participant)
|
||||||
let participants: string[]
|
let participants: string[]
|
||||||
const emitParticipantsUpdate = (action: WAParticipantAction) => this.emit ('group-participants-update', { jid, actor, participants, action })
|
const emitParticipantsUpdate = (action: WAParticipantAction) => (
|
||||||
const emitGroupUpdate = (update: Partial<WAGroupMetadata>) => this.emit ('group-update', { jid, actor, ...update })
|
this.emitParticipantsUpdate(jid, participants, action)
|
||||||
|
)
|
||||||
|
const emitGroupUpdate = (update: Partial<WAGroupMetadata>) => this.emitGroupUpdate(jid, update)
|
||||||
|
|
||||||
switch (message.messageStubType) {
|
switch (message.messageStubType) {
|
||||||
case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_LEAVE:
|
case WA_MESSAGE_STUB_TYPE.GROUP_PARTICIPANT_LEAVE:
|
||||||
@@ -480,14 +483,11 @@ export class WAConnection extends Base {
|
|||||||
const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false'
|
const restrict = message.messageStubParameters[0] === 'on' ? 'true' : 'false'
|
||||||
emitGroupUpdate({ restrict })
|
emitGroupUpdate({ restrict })
|
||||||
break
|
break
|
||||||
case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_DESCRIPTION:
|
|
||||||
const desc = message.messageStubParameters[0]
|
|
||||||
emitGroupUpdate({ desc })
|
|
||||||
break
|
|
||||||
case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_SUBJECT:
|
case WA_MESSAGE_STUB_TYPE.GROUP_CHANGE_SUBJECT:
|
||||||
case WA_MESSAGE_STUB_TYPE.GROUP_CREATE:
|
case WA_MESSAGE_STUB_TYPE.GROUP_CREATE:
|
||||||
chat.name = message.messageStubParameters[0]
|
chat.name = message.messageStubParameters[0]
|
||||||
chatUpdate.name = chat.name
|
chatUpdate.name = chat.name
|
||||||
|
if (chat.metadata) chat.metadata.subject = chat.name
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,6 +495,35 @@ export class WAConnection extends Base {
|
|||||||
|
|
||||||
this.emit('chat-update', chatUpdate)
|
this.emit('chat-update', chatUpdate)
|
||||||
}
|
}
|
||||||
|
protected emitParticipantsUpdate = (jid: string, participants: string[], action: WAParticipantAction) => {
|
||||||
|
const chat = this.chats.get(jid)
|
||||||
|
const meta = chat?.metadata
|
||||||
|
if (meta) {
|
||||||
|
switch (action) {
|
||||||
|
case 'add':
|
||||||
|
participants.forEach(id => (
|
||||||
|
meta.participants.push({ id, isAdmin: false, isSuperAdmin: false })
|
||||||
|
))
|
||||||
|
break
|
||||||
|
case 'remove':
|
||||||
|
meta.participants = meta.participants.filter(p => !participants.includes(whatsappID(p.id)))
|
||||||
|
break
|
||||||
|
case 'promote':
|
||||||
|
case 'demote':
|
||||||
|
const isAdmin = action==='promote'
|
||||||
|
meta.participants.forEach(p => {
|
||||||
|
if (participants.includes(whatsappID(p.id))) p.isAdmin = isAdmin
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.emit ('group-participants-update', { jid, participants, action })
|
||||||
|
}
|
||||||
|
protected emitGroupUpdate = (jid: string, update: Partial<WAGroupMetadata>) => {
|
||||||
|
const chat = this.chats.get(jid)
|
||||||
|
if (chat.metadata) Object.assign(chat.metadata, update)
|
||||||
|
this.emit ('group-update', { jid, ...update })
|
||||||
|
}
|
||||||
protected chatUpdatedMessage (messageIDs: string[], status: WA_MESSAGE_STATUS_TYPE, chat: WAChat) {
|
protected chatUpdatedMessage (messageIDs: string[], status: WA_MESSAGE_STATUS_TYPE, chat: WAChat) {
|
||||||
for (let id of messageIDs) {
|
for (let id of messageIDs) {
|
||||||
let msg = chat.messages.get (GET_MESSAGE_ID({ id, fromMe: true })) || chat.messages.get (GET_MESSAGE_ID({ id, fromMe: false }))
|
let msg = chat.messages.get (GET_MESSAGE_ID({ id, fromMe: true })) || chat.messages.get (GET_MESSAGE_ID({ id, fromMe: false }))
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {WAConnection as Base} from './7.MessagesExtra'
|
import {WAConnection as Base} from './7.MessagesExtra'
|
||||||
import { WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification } from '../WAConnection/Constants'
|
import { WAMetric, WAFlag, WANode, WAGroupMetadata, WAGroupCreateResponse, WAGroupModification, BaileysError } from '../WAConnection/Constants'
|
||||||
import { GroupSettingChange } from './Constants'
|
import { GroupSettingChange } from './Constants'
|
||||||
import { generateMessageID } from '../WAConnection/Utils'
|
import { generateMessageID } from '../WAConnection/Utils'
|
||||||
|
import { Mutex } from './Mutex'
|
||||||
|
|
||||||
export class WAConnection extends Base {
|
export class WAConnection extends Base {
|
||||||
/** Generic function for group queries */
|
/** Generic function for group queries */
|
||||||
@@ -21,8 +22,26 @@ export class WAConnection extends Base {
|
|||||||
const result = await this.setQuery ([json], [WAMetric.group, 136], tag)
|
const result = await this.setQuery ([json], [WAMetric.group, 136], tag)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
/** Get the metadata of the group */
|
/**
|
||||||
groupMetadata = (jid: string) => this.query({json: ['query', 'GroupMetadata', jid], expect200: true}) as Promise<WAGroupMetadata>
|
* Get the metadata of the group
|
||||||
|
* Baileys automatically caches & maintains this state
|
||||||
|
*/
|
||||||
|
@Mutex(jid => jid)
|
||||||
|
async groupMetadata (jid: string) {
|
||||||
|
const chat = this.chats.get(jid)
|
||||||
|
let metadata = chat?.metadata
|
||||||
|
if (!metadata) {
|
||||||
|
if (chat?.read_only) {
|
||||||
|
metadata = await this.groupMetadataMinimal(jid)
|
||||||
|
} else {
|
||||||
|
metadata = await this.fetchGroupMetadataFromWA(jid)
|
||||||
|
}
|
||||||
|
if (chat) chat.metadata = metadata
|
||||||
|
}
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
|
/** Get the metadata of the group from WA */
|
||||||
|
fetchGroupMetadataFromWA = (jid: string) => this.query({json: ['query', 'GroupMetadata', jid], expect200: true}) as Promise<WAGroupMetadata>
|
||||||
/** Get the metadata (works after you've left the group also) */
|
/** Get the metadata (works after you've left the group also) */
|
||||||
groupMetadataMinimal = async (jid: string) => {
|
groupMetadataMinimal = async (jid: string) => {
|
||||||
const query = ['query', {type: 'group', jid: jid, epoch: this.msgCount.toString()}, null]
|
const query = ['query', {type: 'group', jid: jid, epoch: this.msgCount.toString()}, null]
|
||||||
@@ -49,18 +68,20 @@ export class WAConnection extends Base {
|
|||||||
groupCreate = async (title: string, participants: string[]) => {
|
groupCreate = async (title: string, participants: string[]) => {
|
||||||
const response = await this.groupQuery('create', null, title, participants) as WAGroupCreateResponse
|
const response = await this.groupQuery('create', null, title, participants) as WAGroupCreateResponse
|
||||||
const gid = response.gid
|
const gid = response.gid
|
||||||
|
let metadata: WAGroupMetadata
|
||||||
try {
|
try {
|
||||||
await this.groupMetadata (gid)
|
metadata = await this.groupMetadata (gid)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.warn (`error in group creation: ${error}, switching gid & checking`)
|
this.logger.warn (`error in group creation: ${error}, switching gid & checking`)
|
||||||
// if metadata is not available
|
// if metadata is not available
|
||||||
const comps = gid.replace ('@g.us', '').split ('-')
|
const comps = gid.replace ('@g.us', '').split ('-')
|
||||||
response.gid = `${comps[0]}-${+comps[1] + 1}@g.us`
|
response.gid = `${comps[0]}-${+comps[1] + 1}@g.us`
|
||||||
|
|
||||||
await this.groupMetadata (gid)
|
metadata = await this.groupMetadata (gid)
|
||||||
this.logger.warn (`group ID switched from ${gid} to ${response.gid}`)
|
this.logger.warn (`group ID switched from ${gid} to ${response.gid}`)
|
||||||
}
|
}
|
||||||
await this.chatAdd (response.gid, title)
|
await this.chatAdd (response.gid, title)
|
||||||
|
this.chats.get(response.gid).metadata = metadata
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +103,7 @@ export class WAConnection extends Base {
|
|||||||
*/
|
*/
|
||||||
groupUpdateSubject = async (jid: string, title: string) => {
|
groupUpdateSubject = async (jid: string, title: string) => {
|
||||||
const chat = this.chats.get (jid)
|
const chat = this.chats.get (jid)
|
||||||
if (chat?.name === title) throw new Error ('redundant change')
|
if (chat?.name === title) throw new BaileysError ('redundant change', { status: 400 })
|
||||||
|
|
||||||
const response = await this.groupQuery('subject', jid, title)
|
const response = await this.groupQuery('subject', jid, title)
|
||||||
if (chat) chat.name = title
|
if (chat) chat.name = title
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ export interface WAGroupMetadata {
|
|||||||
restrict?: 'true' | 'false'
|
restrict?: 'true' | 'false'
|
||||||
/** is set when the group only allows admins to write messages */
|
/** is set when the group only allows admins to write messages */
|
||||||
announce?: 'true' | 'false'
|
announce?: 'true' | 'false'
|
||||||
participants: [{ id: string; isAdmin: boolean; isSuperAdmin: boolean }]
|
participants: { id: string; isAdmin: boolean; isSuperAdmin: boolean }[]
|
||||||
}
|
}
|
||||||
export interface WAGroupModification {
|
export interface WAGroupModification {
|
||||||
status: number
|
status: number
|
||||||
@@ -191,7 +191,7 @@ export interface WAPresenceData {
|
|||||||
lastSeen?: number
|
lastSeen?: number
|
||||||
name?: string
|
name?: string
|
||||||
}
|
}
|
||||||
export interface WAContact extends WAPresenceData {
|
export interface WAContact {
|
||||||
verify?: string
|
verify?: string
|
||||||
/** name of the contact, the contact has set on their own on WA */
|
/** name of the contact, the contact has set on their own on WA */
|
||||||
notify?: string
|
notify?: string
|
||||||
@@ -227,6 +227,7 @@ export interface WAChat {
|
|||||||
messages: KeyedDB<WAMessage, string>
|
messages: KeyedDB<WAMessage, string>
|
||||||
imgUrl?: string
|
imgUrl?: string
|
||||||
presences?: { [k: string]: WAPresenceData }
|
presences?: { [k: string]: WAPresenceData }
|
||||||
|
metadata?: WAGroupMetadata
|
||||||
}
|
}
|
||||||
export type WAChatUpdate = Partial<WAChat> & { jid: string, hasNewMessage?: boolean }
|
export type WAChatUpdate = Partial<WAChat> & { jid: string, hasNewMessage?: boolean }
|
||||||
export enum WAMetric {
|
export enum WAMetric {
|
||||||
|
|||||||
Reference in New Issue
Block a user