mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
238 lines
7.1 KiB
TypeScript
238 lines
7.1 KiB
TypeScript
import { BinaryNode, jidNormalizedUser } from "../WABinary";
|
|
import { LegacySocketConfig, GroupModificationResponse, ParticipantAction, GroupMetadata, WAFlag, WAMetric, WAGroupCreateResponse, GroupParticipant } from "../Types";
|
|
import { generateMessageID, unixTimestampSeconds } from "../Utils/generics";
|
|
import makeMessagesSocket from "./messages";
|
|
|
|
const makeGroupsSocket = (config: LegacySocketConfig) => {
|
|
const { logger } = config
|
|
const sock = makeMessagesSocket(config)
|
|
const {
|
|
ev,
|
|
ws: socketEvents,
|
|
query,
|
|
generateMessageTag,
|
|
currentEpoch,
|
|
setQuery,
|
|
state
|
|
} = sock
|
|
|
|
/** Generic function for group queries */
|
|
const groupQuery = async(type: string, jid?: string, subject?: string, participants?: string[], additionalNodes?: BinaryNode[]) => {
|
|
const tag = generateMessageTag()
|
|
const result = await setQuery ([
|
|
{
|
|
tag: 'group',
|
|
attrs: {
|
|
author: state.legacy?.user?.id,
|
|
id: tag,
|
|
type: type,
|
|
jid: jid,
|
|
subject: subject,
|
|
},
|
|
content: participants ?
|
|
participants.map(jid => (
|
|
{ tag: 'participant', attrs: { jid } }
|
|
)) :
|
|
additionalNodes
|
|
}
|
|
], [WAMetric.group, 136], tag)
|
|
return result
|
|
}
|
|
|
|
/** Get the metadata of the group from WA */
|
|
const groupMetadataFull = async (jid: string) => {
|
|
const metadata = await query({
|
|
json: ['query', 'GroupMetadata', jid],
|
|
expect200: true
|
|
})
|
|
metadata.participants = metadata.participants.map(p => (
|
|
{ ...p, id: undefined, jid: jidNormalizedUser(p.id) }
|
|
))
|
|
metadata.owner = jidNormalizedUser(metadata.owner)
|
|
return metadata as GroupMetadata
|
|
}
|
|
/** Get the metadata (works after you've left the group also) */
|
|
const groupMetadataMinimal = async (jid: string) => {
|
|
const { attrs, content }:BinaryNode = await query({
|
|
json: {
|
|
tag: 'query',
|
|
attrs: {type: 'group', jid: jid, epoch: currentEpoch().toString()}
|
|
},
|
|
binaryTag: [WAMetric.group, WAFlag.ignore],
|
|
expect200: true
|
|
})
|
|
const participants: GroupParticipant[] = []
|
|
let desc: string | undefined
|
|
if(Array.isArray(content) && Array.isArray(content[0].content)) {
|
|
const nodes = content[0].content
|
|
for(const item of nodes) {
|
|
if(item.tag === 'participant') {
|
|
participants.push({
|
|
id: item.attrs.jid,
|
|
isAdmin: item.attrs.type === 'admin',
|
|
isSuperAdmin: false
|
|
})
|
|
} else if(item.tag === 'description') {
|
|
desc = (item.content as Buffer).toString('utf-8')
|
|
}
|
|
}
|
|
}
|
|
const meta: GroupMetadata = {
|
|
id: jid,
|
|
owner: attrs?.creator,
|
|
creation: +attrs?.create,
|
|
subject: null,
|
|
desc,
|
|
participants
|
|
}
|
|
return meta
|
|
}
|
|
|
|
socketEvents.on('CB:Chat,cmd:action', (json: BinaryNode) => {
|
|
/*const data = json[1].data
|
|
if (data) {
|
|
const emitGroupParticipantsUpdate = (action: WAParticipantAction) => this.emitParticipantsUpdate
|
|
(json[1].id, data[2].participants.map(whatsappID), action)
|
|
const emitGroupUpdate = (data: Partial<WAGroupMetadata>) => this.emitGroupUpdate(json[1].id, data)
|
|
|
|
switch (data[0]) {
|
|
case "promote":
|
|
emitGroupParticipantsUpdate('promote')
|
|
break
|
|
case "demote":
|
|
emitGroupParticipantsUpdate('demote')
|
|
break
|
|
case "desc_add":
|
|
emitGroupUpdate({ ...data[2], descOwner: data[1] })
|
|
break
|
|
default:
|
|
this.logger.debug({ unhandled: true }, json)
|
|
break
|
|
}
|
|
}*/
|
|
})
|
|
|
|
return {
|
|
...sock,
|
|
groupMetadata: async(jid: string, minimal: boolean) => {
|
|
let result: GroupMetadata
|
|
|
|
if(minimal) result = await groupMetadataMinimal(jid)
|
|
else result = await groupMetadataFull(jid)
|
|
|
|
return result
|
|
},
|
|
/**
|
|
* Create a group
|
|
* @param title like, the title of the group
|
|
* @param participants people to include in the group
|
|
*/
|
|
groupCreate: async (title: string, participants: string[]) => {
|
|
const response = await groupQuery('create', null, title, participants) as WAGroupCreateResponse
|
|
const gid = response.gid
|
|
let metadata: GroupMetadata
|
|
try {
|
|
metadata = await groupMetadataFull(gid)
|
|
} catch (error) {
|
|
logger.warn (`error in group creation: ${error}, switching gid & checking`)
|
|
// if metadata is not available
|
|
const comps = gid.replace ('@g.us', '').split ('-')
|
|
response.gid = `${comps[0]}-${+comps[1] + 1}@g.us`
|
|
|
|
metadata = await groupMetadataFull(gid)
|
|
logger.warn (`group ID switched from ${gid} to ${response.gid}`)
|
|
}
|
|
ev.emit('chats.upsert', [
|
|
{
|
|
id: response.gid!,
|
|
name: title,
|
|
conversationTimestamp: unixTimestampSeconds(),
|
|
unreadCount: 0
|
|
}
|
|
])
|
|
return metadata
|
|
},
|
|
/**
|
|
* Leave a group
|
|
* @param jid the ID of the group
|
|
*/
|
|
groupLeave: async (id: string) => {
|
|
await groupQuery('leave', id)
|
|
ev.emit('chats.update', [ { id, readOnly: true } ])
|
|
},
|
|
/**
|
|
* Update the subject of the group
|
|
* @param {string} jid the ID of the group
|
|
* @param {string} title the new title of the group
|
|
*/
|
|
groupUpdateSubject: async (id: string, title: string) => {
|
|
await groupQuery('subject', id, title)
|
|
ev.emit('chats.update', [ { id, name: title } ])
|
|
ev.emit('contacts.update', [ { id, name: title } ])
|
|
ev.emit('groups.update', [ { id: id, subject: title } ])
|
|
},
|
|
/**
|
|
* Update the group description
|
|
* @param {string} jid the ID of the group
|
|
* @param {string} title the new title of the group
|
|
*/
|
|
groupUpdateDescription: async (jid: string, description: string) => {
|
|
const metadata = await groupMetadataFull(jid)
|
|
const node: BinaryNode = {
|
|
tag: 'description',
|
|
attrs: {id: generateMessageID(), prev: metadata?.descId},
|
|
content: Buffer.from(description, 'utf-8')
|
|
}
|
|
|
|
const response = await groupQuery ('description', jid, null, null, [node])
|
|
ev.emit('groups.update', [ { id: jid, desc: description } ])
|
|
return response
|
|
},
|
|
/**
|
|
* Update participants in the group
|
|
* @param jid the ID of the group
|
|
* @param participants the people to add
|
|
*/
|
|
groupParticipantsUpdate: async(id: string, participants: string[], action: ParticipantAction) => {
|
|
const result: GroupModificationResponse = await groupQuery(action, id, null, participants)
|
|
const jids = Object.keys(result.participants || {})
|
|
ev.emit('group-participants.update', { id, participants: jids, action })
|
|
return jids
|
|
},
|
|
/** Query broadcast list info */
|
|
getBroadcastListInfo: async(jid: string) => {
|
|
interface WABroadcastListInfo {
|
|
status: number
|
|
name: string
|
|
recipients?: {id: string}[]
|
|
}
|
|
|
|
const result = await query({
|
|
json: ['query', 'contact', jid],
|
|
expect200: true,
|
|
requiresPhoneConnection: true
|
|
}) as WABroadcastListInfo
|
|
|
|
const metadata: GroupMetadata = {
|
|
subject: result.name,
|
|
id: jid,
|
|
creation: undefined,
|
|
owner: state.legacy?.user?.id,
|
|
participants: result.recipients!.map(({ id }) => (
|
|
{ id: jidNormalizedUser(id), isAdmin: false, isSuperAdmin: false }
|
|
))
|
|
}
|
|
return metadata
|
|
},
|
|
groupInviteCode: async(jid: string) => {
|
|
const response = await sock.query({
|
|
json: ['query', 'inviteCode', jid],
|
|
expect200: true,
|
|
requiresPhoneConnection: false
|
|
})
|
|
return response.code as string
|
|
}
|
|
}
|
|
|
|
}
|
|
export default makeGroupsSocket |