Overview
Group metadata contains comprehensive information about a WhatsApp group, including its participants, settings, description, and various configuration options.Fetching Group Metadata
Use thegroupMetadata method to retrieve complete information about a group.
Function Signature
groupMetadata(jid: string): Promise<GroupMetadata>
jid- The group JID (e.g.,'123456789@g.us')
GroupMetadata object containing all group information
Basic Example
const metadata = await sock.groupMetadata(jid)
console.log(metadata.id + ', title: ' + metadata.subject + ', description: ' + metadata.desc)
Complete Usage
const getGroupInfo = async (groupJid: string) => {
try {
const metadata = await sock.groupMetadata(groupJid)
console.log('Group Information:')
console.log('ID:', metadata.id)
console.log('Name:', metadata.subject)
console.log('Description:', metadata.desc)
console.log('Owner:', metadata.owner)
console.log('Participants:', metadata.participants.length)
console.log('Created:', new Date(metadata.creation! * 1000))
return metadata
} catch (error) {
console.error('Failed to fetch group metadata:', error)
throw error
}
}
GroupMetadata Interface
The complete structure of group metadata:interface GroupMetadata {
// Basic Information
id: string // Group JID
subject: string // Group name/title
notify?: string // Notification name
size?: number // Number of participants
creation?: number // Creation timestamp (Unix)
// Owner Information
owner: string | undefined // Creator JID
ownerPn?: string // Creator phone number
owner_country_code?: string // Creator country code
// Subject (Name) Metadata
subjectOwner?: string // Who last changed the name
subjectOwnerPn?: string // Subject owner phone number
subjectTime?: number // When name was last changed
// Description Metadata
desc?: string // Group description text
descId?: string // Description ID
descOwner?: string // Who set the description
descOwnerPn?: string // Description owner phone number
descTime?: number // When description was set
// Settings
addressingMode?: WAMessageAddressingMode // 'lid' or 'pn' messaging mode
restrict?: boolean // Locked settings (admin only)
announce?: boolean // Announcement mode (admin only messages)
memberAddMode?: boolean // Members can add participants
joinApprovalMode?: boolean // Approval required to join
ephemeralDuration?: number // Disappearing messages duration
// Community
linkedParent?: string // Parent community JID
isCommunity?: boolean // Is this a community
isCommunityAnnounce?: boolean // Is community announcement group
// Participants
participants: GroupParticipant[] // Array of group members
// Additional
inviteCode?: string // Current invite code
author?: string // Person who added you/changed setting
authorPn?: string // Author phone number
}
GroupParticipant Interface
Each participant in the group has 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
}
Working with Participants
List All Participants
const listParticipants = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
console.log(`Group has ${metadata.participants.length} participants:\n`)
metadata.participants.forEach(participant => {
const role = participant.admin || 'member'
console.log(`${participant.id} - ${role}`)
})
}
Get Admins Only
const getGroupAdmins = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
const admins = metadata.participants.filter(p => p.admin)
console.log('Admins:')
admins.forEach(admin => {
console.log(`${admin.id} - ${admin.admin}`)
})
return admins
}
Check if User is Admin
const isUserAdmin = async (groupJid: string, userJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
const participant = metadata.participants.find(p => p.id === userJid)
return participant?.admin !== null && participant?.admin !== undefined
}
// Usage
const isAdmin = await isUserAdmin(groupJid, '1234@s.whatsapp.net')
console.log('Is admin:', isAdmin)
Check if User is Super Admin (Creator)
const isSuperAdmin = async (groupJid: string, userJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
const participant = metadata.participants.find(p => p.id === userJid)
return participant?.admin === 'superadmin'
}
Checking Group Settings
Display All Settings
const displayGroupSettings = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
console.log('Group Settings:')
console.log('Announcement Mode:', metadata.announce ? 'ON' : 'OFF')
console.log('Locked Settings:', metadata.restrict ? 'ON' : 'OFF')
console.log('Member Can Add:', metadata.memberAddMode ? 'YES' : 'NO')
console.log('Join Approval:', metadata.joinApprovalMode ? 'ON' : 'OFF')
if (metadata.ephemeralDuration) {
const days = metadata.ephemeralDuration / 86400
console.log(`Ephemeral Messages: ${days} day(s)`)
} else {
console.log('Ephemeral Messages: OFF')
}
}
Check Specific Setting
const isAnnouncementGroup = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
return metadata.announce === true
}
const hasEphemeralEnabled = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
return metadata.ephemeralDuration !== undefined && metadata.ephemeralDuration > 0
}
Fetching All Participating Groups
Get metadata for all groups you’re a member of.Function Signature
groupFetchAllParticipating(): Promise<{ [jid: string]: GroupMetadata }>
Fetch All Groups
const response = await sock.groupFetchAllParticipating()
console.log(response)
Complete Example
const getAllGroups = async () => {
const groups = await sock.groupFetchAllParticipating()
const groupList = Object.values(groups)
console.log(`You are in ${groupList.length} groups:\n`)
groupList.forEach(group => {
console.log(`${group.subject} (${group.id})`)
console.log(` Participants: ${group.participants.length}`)
console.log(` Created: ${new Date(group.creation! * 1000).toLocaleDateString()}`)
console.log('')
})
return groups
}
Filter Groups by Criteria
const findGroupsByName = async (searchTerm: string) => {
const groups = await sock.groupFetchAllParticipating()
const matchingGroups = Object.values(groups).filter(group =>
group.subject.toLowerCase().includes(searchTerm.toLowerCase())
)
return matchingGroups
}
const getGroupsWhereAdmin = async () => {
const groups = await sock.groupFetchAllParticipating()
const myJid = sock.user?.id
const adminGroups = Object.values(groups).filter(group => {
const me = group.participants.find(p => p.id === myJid)
return me?.admin !== null && me?.admin !== undefined
})
return adminGroups
}
Description Metadata
Working with group descriptions:const getDescriptionInfo = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
if (!metadata.desc) {
console.log('No description set')
return null
}
console.log('Description:', metadata.desc)
console.log('Set by:', metadata.descOwner)
if (metadata.descTime) {
const date = new Date(metadata.descTime * 1000)
console.log('Set on:', date.toLocaleString())
}
return {
text: metadata.desc,
owner: metadata.descOwner,
time: metadata.descTime,
id: metadata.descId
}
}
Community Groups
Check if a group is part of a community:const getCommunityInfo = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
if (metadata.isCommunity) {
console.log('This is a community')
} else if (metadata.linkedParent) {
console.log('This group is part of community:', metadata.linkedParent)
} else {
console.log('This is a standalone group')
}
if (metadata.isCommunityAnnounce) {
console.log('This is a community announcement group')
}
return {
isCommunity: metadata.isCommunity,
linkedParent: metadata.linkedParent,
isCommunityAnnounce: metadata.isCommunityAnnounce
}
}
Complete Analysis Function
Comprehensive group analysis:Fetch and analyze
const analyzeGroup = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
// Basic Info
console.log('=== GROUP ANALYSIS ===')
console.log('Name:', metadata.subject)
console.log('ID:', metadata.id)
console.log('Created:', new Date(metadata.creation! * 1000).toLocaleString())
console.log('Owner:', metadata.owner)
// Participants Analysis
console.log('\n=== PARTICIPANTS ===')
const admins = metadata.participants.filter(p => p.admin === 'admin')
const superAdmins = metadata.participants.filter(p => p.admin === 'superadmin')
const members = metadata.participants.filter(p => !p.admin)
console.log(`Total: ${metadata.participants.length}`)
console.log(`Super Admins: ${superAdmins.length}`)
console.log(`Admins: ${admins.length}`)
console.log(`Members: ${members.length}`)
// Settings
console.log('\n=== SETTINGS ===')
console.log('Announcement Mode:', metadata.announce ? 'ON' : 'OFF')
console.log('Locked:', metadata.restrict ? 'YES' : 'NO')
console.log('Members Can Add:', metadata.memberAddMode ? 'YES' : 'NO')
console.log('Join Approval:', metadata.joinApprovalMode ? 'REQUIRED' : 'NOT REQUIRED')
if (metadata.ephemeralDuration) {
console.log('Ephemeral:', `${metadata.ephemeralDuration / 86400} days`)
}
// Description
if (metadata.desc) {
console.log('\n=== DESCRIPTION ===')
console.log(metadata.desc)
}
return metadata
}
Export data
const exportGroupData = async (groupJid: string) => {
const metadata = await sock.groupMetadata(groupJid)
const exportData = {
basic: {
id: metadata.id,
name: metadata.subject,
description: metadata.desc,
created: new Date(metadata.creation! * 1000).toISOString(),
owner: metadata.owner
},
settings: {
announcementMode: metadata.announce,
locked: metadata.restrict,
memberCanAdd: metadata.memberAddMode,
joinApproval: metadata.joinApprovalMode,
ephemeralDuration: metadata.ephemeralDuration
},
participants: metadata.participants.map(p => ({
jid: p.id,
role: p.admin || 'member'
})),
community: {
isCommunity: metadata.isCommunity,
linkedParent: metadata.linkedParent,
isCommunityAnnounce: metadata.isCommunityAnnounce
}
}
return exportData
}
Best Practices
Caching: Group metadata doesn’t change frequently. Consider caching it to reduce API calls.
Events: The library emits
'groups.update' events when metadata changes. Listen to these events to keep your cache updated.Privacy: Be careful when storing or displaying participant information. Respect user privacy.
Efficient Metadata Usage
// Cache metadata to avoid repeated fetches
const metadataCache = new Map<string, { data: GroupMetadata, timestamp: number }>()
const CACHE_TTL = 5 * 60 * 1000 // 5 minutes
const getCachedMetadata = async (groupJid: string) => {
const cached = metadataCache.get(groupJid)
const now = Date.now()
if (cached && (now - cached.timestamp) < CACHE_TTL) {
return cached.data
}
const metadata = await sock.groupMetadata(groupJid)
metadataCache.set(groupJid, { data: metadata, timestamp: now })
return metadata
}
// Listen for updates to invalidate cache
sock.ev.on('groups.update', (updates) => {
updates.forEach(update => {
metadataCache.delete(update.id)
})
})
Related Methods
- Group Settings - Modify group configuration
- Managing Participants - Update participant roles
- Invite Codes - Get group invite information