Overview
Baileys provides comprehensive methods for managing group participants, including adding/removing members and changing admin roles. Only group admins can perform these operations.
Group Participants Update
The main method for managing participants is groupParticipantsUpdate, which handles multiple actions.
Function Signature
groupParticipantsUpdate(
jid: string,
participants: string[],
action: ParticipantAction
): Promise<Array<{ status: string; jid: string; content: any }>>
Parameters:
jid - The group JID
participants - Array of participant JIDs to update
action - One of: 'add', 'remove', 'promote', 'demote', or 'modify'
Returns: Array of results showing the status for each participant
Adding Participants
Add new members to an existing group.
Basic Example
Handling Results
const results = await sock.groupParticipantsUpdate(
jid,
['[email protected]', '[email protected]'],
'add'
)
// Check results for each participant
results.forEach(result => {
if (result.status === '200') {
console.log(`Successfully added ${result.jid}`)
} else {
console.log(`Failed to add ${result.jid}: ${result.status}`)
}
})
Success Status: A status of '200' indicates successful operation. Other codes indicate errors.
Removing Participants
Remove members from the group.
Admin Permissions Required: You must be a group admin to remove participants. Attempting to remove participants without admin rights will result in an error.
Safely Removing Participants
const removeParticipants = async (
groupJid: string,
participantsToRemove: string[]
) => {
try {
const results = await sock.groupParticipantsUpdate(
groupJid,
participantsToRemove,
'remove'
)
const successful = results.filter(r => r.status === '200')
const failed = results.filter(r => r.status !== '200')
console.log(`Removed ${successful.length} participants`)
if (failed.length > 0) {
console.log(`Failed to remove ${failed.length} participants`)
}
return { successful, failed }
} catch (error) {
console.error('Error removing participants:', error)
throw error
}
}
Promote regular members to admin status.
const promoteToAdmin = async (
groupJid: string,
participantJid: string
) => {
try {
const results = await sock.groupParticipantsUpdate(
groupJid,
[participantJid],
'promote'
)
if (results[0].status === '200') {
console.log(`${participantJid} is now an admin`)
// Send notification to the group
await sock.sendMessage(groupJid, {
text: `Congratulations! @${participantJid.split('@')[0]} is now an admin.`,
mentions: [participantJid]
})
}
return results[0]
} catch (error) {
console.error('Failed to promote participant:', error)
throw error
}
}
Demoting Participants
Demote admins back to regular member status.
Super Admin: The group creator (super admin) cannot be demoted. Attempting to demote the creator will fail.
Managing Join Requests
For groups with join approval mode enabled, you can approve or reject join requests.
Get Join Request List
const requests = await sock.groupRequestParticipantsList(jid)
console.log(requests) // Array of pending requests with attrs
Approve/Reject Join Requests
Function Signature
groupRequestParticipantsUpdate(
jid: string,
participants: string[],
action: 'approve' | 'reject'
): Promise<Array<{ status: string; jid: string }>>
Approve Requests
Reject Requests
Complete Join Request Handler
const handleJoinRequests = async (groupJid: string) => {
// Get all pending requests
const requests = await sock.groupRequestParticipantsList(groupJid)
if (requests.length === 0) {
console.log('No pending requests')
return
}
console.log(`Found ${requests.length} pending requests`)
// Example: Auto-approve all requests
const jidsToApprove = requests.map(req => req.jid)
const results = await sock.groupRequestParticipantsUpdate(
groupJid,
jidsToApprove,
'approve'
)
// Check results
results.forEach(result => {
if (result.status === '200') {
console.log(`Approved ${result.jid}`)
} else {
console.log(`Failed to approve ${result.jid}: ${result.status}`)
}
})
}
Participant Structure
Participants in group metadata have the following structure:
interface GroupParticipant {
id: string // Participant JID
phoneNumber?: string // Phone number (for LID users)
lid?: string // LID identifier
admin: 'admin' | 'superadmin' | null // Admin status
isAdmin?: boolean // Deprecated: check admin field
isSuperAdmin?: boolean // Deprecated: check if admin === 'superadmin'
}
Best Practices
Check admin status before operations
Verify you have admin permissions before attempting to modify participants.const metadata = await sock.groupMetadata(groupJid)
const myJid = sock.user.id
const me = metadata.participants.find(p => p.id === myJid)
if (!me?.admin) {
throw new Error('You must be an admin to perform this action')
}
Handle errors gracefully
Always check the status codes returned from participant updates.const results = await sock.groupParticipantsUpdate(jid, participants, 'add')
const failures = results.filter(r => r.status !== '200')
if (failures.length > 0) {
// Handle failures appropriately
}
Validate participant JIDs
Ensure JIDs are properly formatted before operations.const formatJid = (phone: string) => {
return phone.includes('@') ? phone : `${phone}@s.whatsapp.net`
}
Common Use Cases
Batch Add with Error Handling
const batchAddParticipants = async (
groupJid: string,
phoneNumbers: string[]
) => {
// Format JIDs
const jids = phoneNumbers.map(num => `${num}@s.whatsapp.net`)
// Add in batches of 10 to avoid rate limits
const batchSize = 10
const results = []
for (let i = 0; i < jids.length; i += batchSize) {
const batch = jids.slice(i, i + batchSize)
const batchResults = await sock.groupParticipantsUpdate(
groupJid,
batch,
'add'
)
results.push(...batchResults)
// Wait between batches
if (i + batchSize < jids.length) {
await new Promise(resolve => setTimeout(resolve, 1000))
}
}
return results
}
Automatic Admin Assignment
const assignAdmins = async (groupJid: string, adminJids: string[]) => {
// Get current group metadata
const metadata = await sock.groupMetadata(groupJid)
// Filter to only non-admin participants
const toPromote = adminJids.filter(jid => {
const participant = metadata.participants.find(p => p.id === jid)
return participant && !participant.admin
})
if (toPromote.length === 0) {
console.log('All specified participants are already admins')
return
}
// Promote them
const results = await sock.groupParticipantsUpdate(
groupJid,
toPromote,
'promote'
)
return results
}