Skip to content

Commit 9a4ae2b

Browse files
authored
feat(group): add updateMemberAddMode endpoint (#2525)
* feat(group): add updateMemberAddMode endpoint Expose the WhatsApp protocol's group "member add mode" setting (supported by Baileys via groupMemberAddMode) as a new endpoint, so clients can toggle whether non-admin members are allowed to add participants to a group. POST /group/updateMemberAddMode/{instance}?groupJid=<jid> body: { "mode": "admin_add" | "all_member_add" } - admin_add → only admins can add new members - all_member_add → any member can add new members (WhatsApp default) Mirrors the existing pattern of updateSetting: - DTO : GroupUpdateMemberAddModeDto - Schema: updateMemberAddModeSchema (validates mode enum) - Service: WhatsappBaileysService.updateMemberAddMode - Controller: GroupController.updateMemberAddMode - Route: POST /group/updateMemberAddMode No breaking change. No new dependency. * ci: build & publish fork Docker image to GHCR Triggered on every push to feat/group-member-add-mode. Produces: ghcr.io/hassankaid/evolution-api:member-add-mode ghcr.io/hassankaid/evolution-api:sha-<commit> Allows users running self-hosted Evolution to swap their Docker image to this fork while keeping all their state (sessions, DB, Redis) untouched, until the upstream PR #2525 is merged.
1 parent 84a92f1 commit 9a4ae2b

6 files changed

Lines changed: 93 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Publish fork Docker image
2+
3+
on:
4+
push:
5+
branches:
6+
- 'feat/group-member-add-mode'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
packages: write
12+
13+
jobs:
14+
build-and-push:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Set up QEMU
21+
uses: docker/setup-qemu-action@v3
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
26+
- name: Log in to GHCR
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ghcr.io
30+
username: ${{ github.actor }}
31+
password: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Compute lowercase repo
34+
id: vars
35+
run: echo "repo=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
36+
37+
- name: Build and push
38+
uses: docker/build-push-action@v6
39+
with:
40+
context: .
41+
file: ./Dockerfile
42+
push: true
43+
platforms: linux/amd64
44+
tags: |
45+
ghcr.io/${{ steps.vars.outputs.repo }}:member-add-mode
46+
ghcr.io/${{ steps.vars.outputs.repo }}:sha-${{ github.sha }}
47+
cache-from: type=gha
48+
cache-to: type=gha,mode=max

src/api/controllers/group.controller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
GroupSendInvite,
1010
GroupSubjectDto,
1111
GroupToggleEphemeralDto,
12+
GroupUpdateMemberAddModeDto,
1213
GroupUpdateParticipantDto,
1314
GroupUpdateSettingDto,
1415
} from '@api/dto/group.dto';
@@ -74,6 +75,10 @@ export class GroupController {
7475
return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update);
7576
}
7677

78+
public async updateMemberAddMode(instance: InstanceDto, update: GroupUpdateMemberAddModeDto) {
79+
return await this.waMonitor.waInstances[instance.instanceName].updateMemberAddMode(update);
80+
}
81+
7782
public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) {
7883
return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update);
7984
}

src/api/dto/group.dto.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,7 @@ export class GroupUpdateSettingDto extends GroupJid {
5454
export class GroupToggleEphemeralDto extends GroupJid {
5555
expiration: 0 | 86400 | 604800 | 7776000;
5656
}
57+
58+
export class GroupUpdateMemberAddModeDto extends GroupJid {
59+
mode: 'admin_add' | 'all_member_add';
60+
}

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
GroupSendInvite,
2828
GroupSubjectDto,
2929
GroupToggleEphemeralDto,
30+
GroupUpdateMemberAddModeDto,
3031
GroupUpdateParticipantDto,
3132
GroupUpdateSettingDto,
3233
} from '@api/dto/group.dto';
@@ -5080,6 +5081,15 @@ export class BaileysStartupService extends ChannelStartupService {
50805081
}
50815082
}
50825083

5084+
public async updateMemberAddMode(update: GroupUpdateMemberAddModeDto) {
5085+
try {
5086+
await this.client.groupMemberAddMode(update.groupJid, update.mode);
5087+
return { update: 'success', mode: update.mode };
5088+
} catch (error) {
5089+
throw new BadRequestException('Error updating member add mode', error.toString());
5090+
}
5091+
}
5092+
50835093
public async toggleEphemeral(update: GroupToggleEphemeralDto) {
50845094
try {
50855095
await this.client.groupToggleEphemeral(update.groupJid, update.expiration);

src/api/routes/group.router.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
GroupSendInvite,
1111
GroupSubjectDto,
1212
GroupToggleEphemeralDto,
13+
GroupUpdateMemberAddModeDto,
1314
GroupUpdateParticipantDto,
1415
GroupUpdateSettingDto,
1516
} from '@api/dto/group.dto';
@@ -25,6 +26,7 @@ import {
2526
updateGroupDescriptionSchema,
2627
updateGroupPictureSchema,
2728
updateGroupSubjectSchema,
29+
updateMemberAddModeSchema,
2830
updateParticipantsSchema,
2931
updateSettingsSchema,
3032
} from '@validate/validate.schema';
@@ -176,6 +178,16 @@ export class GroupRouter extends RouterBroker {
176178

177179
res.status(HttpStatus.CREATED).json(response);
178180
})
181+
.post(this.routerPath('updateMemberAddMode'), ...guards, async (req, res) => {
182+
const response = await this.groupValidate<GroupUpdateMemberAddModeDto>({
183+
request: req,
184+
schema: updateMemberAddModeSchema,
185+
ClassRef: GroupUpdateMemberAddModeDto,
186+
execute: (instance, data) => groupController.updateMemberAddMode(instance, data),
187+
});
188+
189+
res.status(HttpStatus.CREATED).json(response);
190+
})
179191
.post(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => {
180192
const response = await this.groupValidate<GroupToggleEphemeralDto>({
181193
request: req,

src/validate/group.schema.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,17 @@ export const updateGroupDescriptionSchema: JSONSchema7 = {
191191
required: ['groupJid', 'description'],
192192
...isNotEmpty('groupJid', 'description'),
193193
};
194+
195+
export const updateMemberAddModeSchema: JSONSchema7 = {
196+
$id: v4(),
197+
type: 'object',
198+
properties: {
199+
groupJid: { type: 'string' },
200+
mode: {
201+
type: 'string',
202+
enum: ['admin_add', 'all_member_add'],
203+
},
204+
},
205+
required: ['groupJid', 'mode'],
206+
...isNotEmpty('groupJid', 'mode'),
207+
};

0 commit comments

Comments
 (0)