diff --git a/src/core/engines/gows/grpc/gows.ts b/src/core/engines/gows/grpc/gows.ts index 9f1c6b39..3ed408d7 100644 --- a/src/core/engines/gows/grpc/gows.ts +++ b/src/core/engines/gows/grpc/gows.ts @@ -11362,6 +11362,15 @@ export namespace messages { responseSerialize: (message: Empty) => Buffer.from(message.serialize()), responseDeserialize: (bytes: Buffer) => Empty.deserialize(new Uint8Array(bytes)) }, + SetGroupMemberAddMode: { + path: "/messages.MessageService/SetGroupMemberAddMode", + requestStream: false, + responseStream: false, + requestSerialize: (message: JidBoolRequest) => Buffer.from(message.serialize()), + requestDeserialize: (bytes: Buffer) => JidBoolRequest.deserialize(new Uint8Array(bytes)), + responseSerialize: (message: Empty) => Buffer.from(message.serialize()), + responseDeserialize: (bytes: Buffer) => Empty.deserialize(new Uint8Array(bytes)) + }, UpdateGroupParticipants: { path: "/messages.MessageService/UpdateGroupParticipants", requestStream: false, @@ -11734,6 +11743,7 @@ export namespace messages { abstract SetGroupPicture(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; abstract SetGroupLocked(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; abstract SetGroupAnnounce(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; + abstract SetGroupMemberAddMode(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; abstract UpdateGroupParticipants(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; abstract GetProfilePicture(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; abstract SendPresence(call: grpc_1.ServerUnaryCall, callback: grpc_1.sendUnaryData): void; @@ -11861,6 +11871,9 @@ export namespace messages { SetGroupAnnounce: GrpcUnaryServiceInterface = (message: JidBoolRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback, options?: grpc_1.CallOptions | grpc_1.requestCallback, callback?: grpc_1.requestCallback): grpc_1.ClientUnaryCall => { return super.SetGroupAnnounce(message, metadata, options, callback); }; + SetGroupMemberAddMode: GrpcUnaryServiceInterface = (message: JidBoolRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback, options?: grpc_1.CallOptions | grpc_1.requestCallback, callback?: grpc_1.requestCallback): grpc_1.ClientUnaryCall => { + return super.SetGroupMemberAddMode(message, metadata, options, callback); + }; UpdateGroupParticipants: GrpcUnaryServiceInterface = (message: UpdateParticipantsRequest, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback, options?: grpc_1.CallOptions | grpc_1.requestCallback, callback?: grpc_1.requestCallback): grpc_1.ClientUnaryCall => { return super.UpdateGroupParticipants(message, metadata, options, callback); }; diff --git a/src/core/engines/gows/grpc/gows_grpc_pb.js b/src/core/engines/gows/grpc/gows_grpc_pb.js index e220f4e0..c6eb08e6 100644 --- a/src/core/engines/gows/grpc/gows_grpc_pb.js +++ b/src/core/engines/gows/grpc/gows_grpc_pb.js @@ -1050,6 +1050,18 @@ setGroupAnnounce: { responseDeserialize: deserialize_messages_Empty, }, // send messages only by admins +setGroupMemberAddMode: { + path: '/messages.MessageService/SetGroupMemberAddMode', + requestStream: false, + responseStream: false, + requestType: gows_pb.JidBoolRequest, + responseType: gows_pb.Empty, + requestSerialize: serialize_messages_JidBoolRequest, + requestDeserialize: deserialize_messages_JidBoolRequest, + responseSerialize: serialize_messages_Empty, + responseDeserialize: deserialize_messages_Empty, + }, + // who can add members - true - all members, false - admins only updateGroupParticipants: { path: '/messages.MessageService/UpdateGroupParticipants', requestStream: false, diff --git a/src/core/engines/gows/session.gows.core.ts b/src/core/engines/gows/session.gows.core.ts index 83e88f20..033381f2 100644 --- a/src/core/engines/gows/session.gows.core.ts +++ b/src/core/engines/gows/session.gows.core.ts @@ -119,6 +119,7 @@ import { GroupSortField, Participant, ParticipantsRequest, + SettingsMemberAddMode, SettingsSecurityChangeInfo, } from '@waha/structures/groups.dto'; import { ReplyToMessage } from '@waha/structures/message.dto'; @@ -1650,6 +1651,24 @@ export class WhatsappSessionGoWSCore extends WhatsappSession { return; } + public async getMemberAddMode(id): Promise { + const group = await this.getGroup(id); + return { + membersCanAddNewMember: group.MemberAddMode === 'all_member_add', + }; + } + + @Activity() + public async setMemberAddMode(id, value) { + const req = new messages.JidBoolRequest({ + session: this.session, + jid: id, + value: value, + }); + await promisify(this.client.SetGroupMemberAddMode)(req); + return; + } + public deleteGroup(id) { throw new NotImplementedByEngineError(); } diff --git a/src/core/engines/webjs/groups.webjs.ts b/src/core/engines/webjs/groups.webjs.ts index 06298561..b1a203bd 100644 --- a/src/core/engines/webjs/groups.webjs.ts +++ b/src/core/engines/webjs/groups.webjs.ts @@ -34,7 +34,7 @@ function ToGroupInfo( subject: group.name, description: group.description, invite: invite, - membersCanAddNewMember: groupMetadata.restrict, + membersCanAddNewMember: groupMetadata.memberAddMode === 'all_member_add', membersCanSendMessages: groupMetadata.announce, newMembersApprovalRequired: groupMetadata.membershipApprovalMode, participants: participants, diff --git a/src/core/engines/webjs/session.webjs.core.ts b/src/core/engines/webjs/session.webjs.core.ts index 58b73e0b..990f9d88 100644 --- a/src/core/engines/webjs/session.webjs.core.ts +++ b/src/core/engines/webjs/session.webjs.core.ts @@ -108,6 +108,7 @@ import { GroupParticipant, GroupSortField, ParticipantsRequest, + SettingsMemberAddMode, SettingsSecurityChangeInfo, } from '@waha/structures/groups.dto'; import { Label, LabelDTO, LabelID } from '@waha/structures/labels.dto'; @@ -1535,6 +1536,22 @@ export class WhatsappSessionWebJSCore extends WhatsappSession { return groupChat.setMessagesAdminsOnly(value); } + public async getMemberAddMode(id): Promise { + const groupChat = (await this.whatsapp.getChatById(id)) as GroupChat; + return { + membersCanAddNewMember: + // @ts-ignore + groupChat.groupMetadata.memberAddMode === 'all_member_add', + }; + } + + @Activity() + public async setMemberAddMode(id, value) { + const groupChat = (await this.whatsapp.getChatById(id)) as GroupChat; + // The library setter is inverted - it takes "adminsOnly" + return groupChat.setAddMembersAdminsOnly(!value); + } + public async getGroups(pagination: PaginationParams) { const chats = await this.whatsapp.getChats(); const groups = lodash.filter(chats, (chat) => chat.isGroup); diff --git a/src/core/engines/wpp/session.wpp.core.ts b/src/core/engines/wpp/session.wpp.core.ts index 53368683..c966fec9 100644 --- a/src/core/engines/wpp/session.wpp.core.ts +++ b/src/core/engines/wpp/session.wpp.core.ts @@ -165,6 +165,7 @@ import { GroupParticipantRole, GroupSortField, ParticipantsRequest, + SettingsMemberAddMode, SettingsSecurityChangeInfo, } from '@waha/structures/groups.dto'; import { ContactQuery, ContactRequest } from '@waha/structures/contacts.dto'; @@ -1412,6 +1413,26 @@ export class WhatsappSessionWPPCore extends WhatsappSession { ); } + public async getMemberAddMode(id): Promise { + const group = await this.wpp!.getChatById(this.ensureSuffix(id)); + // Undocumented property - 'all_member_add' or 'admin_add' + const memberAddMode = group?.groupMetadata?.memberAddMode; + return { + membersCanAddNewMember: memberAddMode === 'all_member_add', + }; + } + + @Activity() + public setMemberAddMode(id: string, value: boolean): Promise { + // Not in the GroupProperty enum, but wa-js passes the property through + // to WhatsApp's setGroupProperty - 1 - all members, 0 - admins only + return this.wpp!.setGroupProperty( + this.ensureSuffix(id), + 'member_add_mode' as GroupProperty, + value, + ); + } + @Activity() public deleteGroup(id: string): Promise { return this.wpp!.deleteChat(this.ensureSuffix(id)); @@ -1874,7 +1895,8 @@ export class WhatsappSessionWPPCore extends WhatsappSession { subject: group?.name || '', description: group?.groupMetadata?.desc || '', invite: null, - membersCanAddNewMember: !group?.groupMetadata?.restrict, + membersCanAddNewMember: + group?.groupMetadata?.memberAddMode === 'all_member_add', membersCanSendMessages: !group?.groupMetadata?.announce, newMembersApprovalRequired: !!group?.groupMetadata?.membershipApprovalMode,