diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index e7aad6d..49985f4 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -240,6 +240,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { child: BinaryNode, msg: Partial ) => { + const participantJid = getBinaryNodeChild(child, 'participant')?.attrs?.jid || participant switch (child?.tag) { case 'create': const metadata = extractGroupMetadata(child) @@ -321,6 +322,15 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { msg.messageStubParameters = [ approvalMode.attrs.state ] } + break + case 'created_membership_requests': + msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD + msg.messageStubParameters = [ participantJid, 'created', child.attrs.request_method ] + break + case 'revoked_membership_requests': + const isDenied = areJidsSameUser(participantJid, participant) + msg.messageStubType = WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD + msg.messageStubParameters = [ participantJid, isDenied ? 'revoked' : 'rejected' ] break } } diff --git a/src/Types/Events.ts b/src/Types/Events.ts index 6a5dfb2..e10aad7 100644 --- a/src/Types/Events.ts +++ b/src/Types/Events.ts @@ -4,7 +4,7 @@ import { AuthenticationCreds } from './Auth' import { WACallEvent } from './Call' import { Chat, ChatUpdate, PresenceData } from './Chat' import { Contact } from './Contact' -import { GroupMetadata, ParticipantAction } from './GroupMetadata' +import { GroupMetadata, ParticipantAction, RequestJoinAction, RequestJoinMethod } from './GroupMetadata' import { Label } from './Label' import { LabelAssociation } from './LabelAssociation' import { MessageUpsertType, MessageUserReceiptUpdate, WAMessage, WAMessageKey, WAMessageUpdate } from './Message' @@ -52,6 +52,7 @@ export type BaileysEventMap = { 'groups.update': Partial[] /** apply an action to participants in a group */ 'group-participants.update': { id: string, author: string, participants: string[], action: ParticipantAction } + 'group.join-request': { id: string, author: string, participant: string, action: RequestJoinAction, method: RequestJoinMethod } 'blocklist.set': { blocklist: string[] } 'blocklist.update': { blocklist: string[], type: 'add' | 'remove' } diff --git a/src/Types/GroupMetadata.ts b/src/Types/GroupMetadata.ts index a7d0dcb..bc37ada 100644 --- a/src/Types/GroupMetadata.ts +++ b/src/Types/GroupMetadata.ts @@ -4,6 +4,10 @@ export type GroupParticipant = (Contact & { isAdmin?: boolean, isSuperAdmin?: bo export type ParticipantAction = 'add' | 'remove' | 'promote' | 'demote' +export type RequestJoinAction = 'created' | 'revoked' | 'rejected' + +export type RequestJoinMethod = 'invite_link' | 'linked_group_join' | 'non_admin_add' | undefined + export interface GroupMetadata { id: string owner: string | undefined diff --git a/src/Utils/process-message.ts b/src/Utils/process-message.ts index 114ccf0..db9b215 100644 --- a/src/Utils/process-message.ts +++ b/src/Utils/process-message.ts @@ -1,7 +1,7 @@ import { AxiosRequestConfig } from 'axios' import type { Logger } from 'pino' import { proto } from '../../WAProto' -import { AuthenticationCreds, BaileysEventEmitter, Chat, GroupMetadata, ParticipantAction, SignalKeyStoreWithTransaction, SocketConfig, WAMessageStubType } from '../Types' +import { AuthenticationCreds, BaileysEventEmitter, Chat, GroupMetadata, ParticipantAction, RequestJoinAction, RequestJoinMethod, SignalKeyStoreWithTransaction, SocketConfig, WAMessageStubType } from '../Types' import { getContentType, normalizeMessageContent } from '../Utils/messages' import { areJidsSameUser, isJidBroadcast, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary' import { aesDecryptGCM, hmacSign } from './crypto' @@ -301,6 +301,10 @@ const processMessage = async( ev.emit('groups.update', [{ id: jid, ...update, author: message.participant ?? undefined }]) } + const emitGroupRequestJoin = (participant: string, action: RequestJoinAction, method: RequestJoinMethod) => { + ev.emit('group.join-request', { id: jid, author: message.participant!, participant, action, method: method! }) + } + const participantsIncludesMe = () => participants.find(jid => areJidsSameUser(meId, jid)) switch (message.messageStubType) { @@ -357,7 +361,14 @@ const processMessage = async( const approvalMode = message.messageStubParameters?.[0] emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' }) break + case WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD: + const participant = message.messageStubParameters?.[0] as string + const action = message.messageStubParameters?.[1] as RequestJoinAction + const method = message.messageStubParameters?.[2] as RequestJoinMethod + emitGroupRequestJoin(participant, action, method) + break } + } else if(content?.pollUpdateMessage) { const creationMsgKey = content.pollUpdateMessage.pollCreationMessageKey! // we need to fetch the poll creation message to get the poll enc key