Skip to main content

Event Emitter

The WASocket instance includes an event emitter accessible via sock.ev. Use it to listen for WhatsApp events.
interface BaileysEventEmitter {
    on<T extends BaileysEvent>(event: T, listener: (arg: BaileysEventMap[T]) => void): void
    off<T extends BaileysEvent>(event: T, listener: (arg: BaileysEventMap[T]) => void): void
    removeAllListeners<T extends BaileysEvent>(event: T): void
    emit<T extends BaileysEvent>(event: T, arg: BaileysEventMap[T]): boolean
}

Example Usage

import makeWASocket from '@whiskeysockets/baileys'

const sock = makeWASocket({ auth: state })

// Listen to connection updates
sock.ev.on('connection.update', (update) => {
    const { connection, lastDisconnect, qr } = update
    
    if(qr) {
        console.log('QR Code:', qr)
    }
    
    if(connection === 'close') {
        console.log('Connection closed')
    }
})

// Listen to new messages
sock.ev.on('messages.upsert', ({ messages, type }) => {
    console.log('Received', messages.length, 'messages')
    
    for(const msg of messages) {
        console.log('Message from:', msg.key.remoteJid)
    }
})

BaileysEventMap

All available events and their payload types.

Connection Events

connection.update
Partial<ConnectionState>
Emitted when connection state changes (WebSocket opened, closed, connecting, etc.).
sock.ev.on('connection.update', (update) => {
    const { connection, lastDisconnect, qr, isNewLogin, isOnline } = update
    
    if(connection === 'close') {
        // Handle disconnect
        const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut
        if(shouldReconnect) {
            // Reconnect
        }
    } else if(connection === 'open') {
        console.log('Connected successfully')
    }
})
connection
'open' | 'close' | 'connecting'
Current connection state
lastDisconnect
{ error?: Error; date?: Date }
Information about the last disconnection
qr
string
QR code string for authentication (only during initial pairing)
isNewLogin
boolean
Whether this is a new login session
isOnline
boolean
Whether the phone is online

Authentication Events

creds.update
Partial<AuthenticationCreds>
Emitted when authentication credentials are updated. Always save these updates to maintain the session.
const { state, saveCreds } = await useMultiFileAuthState('auth_info')

const sock = makeWASocket({ auth: state })

sock.ev.on('creds.update', saveCreds)

Message Events

messages.upsert
object
Emitted when new messages are received or updated.
sock.ev.on('messages.upsert', ({ messages, type }) => {
    for(const msg of messages) {
        if(!msg.key.fromMe && type === 'notify') {
            console.log('New message from', msg.key.remoteJid)
            console.log('Message:', msg.message)
        }
    }
})
messages
WAMessage[]
required
Array of message objects
type
MessageUpsertType
required
Type of upsert:
  • 'notify' - Message received while connection was online
  • 'append' - Message from history sync
requestId
string
Present if message was received from the phone due to it being unavailable
messages.update
WAMessageUpdate[]
Emitted when message metadata is updated (status, reactions, edits, etc.).
sock.ev.on('messages.update', (updates) => {
    for(const update of updates) {
        console.log('Message', update.key.id, 'updated')
        if(update.update.status) {
            console.log('New status:', update.update.status)
        }
    }
})
Each update contains:
key
WAMessageKey
required
Message identifier
update
Partial<WAMessage>
required
Updated fields (status, reactions, pollUpdates, etc.)
messages.delete
object
Emitted when messages are deleted.
sock.ev.on('messages.delete', (deletion) => {
    if('keys' in deletion) {
        // Specific messages deleted
        console.log('Deleted messages:', deletion.keys)
    } else {
        // All messages in chat deleted
        console.log('All messages deleted in:', deletion.jid)
    }
})
Two possible formats:
  • { keys: WAMessageKey[] } - Specific messages deleted
  • { jid: string; all: true } - All messages in chat cleared
messages.reaction
Array<{ key: WAMessageKey; reaction: proto.IReaction }>
Emitted when messages receive reactions.
sock.ev.on('messages.reaction', (reactions) => {
    for(const { key, reaction } of reactions) {
        console.log('Message', key.id, 'reacted with:', reaction.text)
        if(!reaction.text) {
            console.log('Reaction removed')
        }
    }
})
If reaction.text is falsy, the reaction was removed.
messages.media-update
Array<{ key: WAMessageKey; media?: object; error?: Boom }>
Emitted when media message metadata is updated.
key
WAMessageKey
required
Message identifier
media
{ ciphertext: Uint8Array; iv: Uint8Array }
Updated media encryption data
error
Boom
Error if media update failed
message-receipt.update
MessageUserReceiptUpdate[]
Emitted when message receipts are updated (read, delivered, played).
sock.ev.on('message-receipt.update', (receipts) => {
    for(const receipt of receipts) {
        console.log('Message', receipt.key.id, 'receipt updated')
    }
})

Chat Events

chats.upsert
Chat[]
Emitted when new chats are created.
sock.ev.on('chats.upsert', (chats) => {
    console.log('New chats:', chats.length)
    for(const chat of chats) {
        console.log('Chat ID:', chat.id)
    }
})
chats.update
ChatUpdate[]
Emitted when chat metadata is updated.
sock.ev.on('chats.update', (updates) => {
    for(const update of updates) {
        console.log('Chat', update.id, 'updated')
        if(update.unreadCount !== undefined) {
            console.log('Unread count:', update.unreadCount)
        }
    }
})
chats.delete
string[]
Emitted when chats are deleted.
sock.ev.on('chats.delete', (deletedChatIds) => {
    console.log('Deleted chats:', deletedChatIds)
})
chats.lock
{ id: string; locked: boolean }
Emitted when a chat is locked or unlocked.

Contact Events

contacts.upsert
Contact[]
Emitted when new contacts are added.
sock.ev.on('contacts.upsert', (contacts) => {
    for(const contact of contacts) {
        console.log('Contact:', contact.id, contact.name)
    }
})
contacts.update
Partial<Contact>[]
Emitted when contact information is updated.

Group Events

groups.upsert
GroupMetadata[]
Emitted when new groups are created or joined.
sock.ev.on('groups.upsert', (groups) => {
    for(const group of groups) {
        console.log('Group:', group.subject)
        console.log('Participants:', group.participants.length)
    }
})
groups.update
Partial<GroupMetadata>[]
Emitted when group metadata is updated (name, description, settings, etc.).
sock.ev.on('groups.update', (updates) => {
    for(const update of updates) {
        console.log('Group', update.id, 'updated')
        if(update.subject) {
            console.log('New name:', update.subject)
        }
    }
})
group-participants.update
object
Emitted when group participants are added, removed, promoted, or demoted.
sock.ev.on('group-participants.update', ({ id, participants, action }) => {
    console.log('Group', id)
    console.log('Action:', action) // 'add', 'remove', 'promote', 'demote'
    console.log('Participants:', participants.map(p => p.id))
})
id
string
required
Group JID
author
string
required
JID of the user who performed the action
participants
GroupParticipant[]
required
Affected participants
action
ParticipantAction
required
Action performed: 'add' | 'remove' | 'promote' | 'demote'
group.join-request
object
Emitted when someone requests to join a group.
sock.ev.on('group.join-request', ({ id, participant, action }) => {
    console.log('Join request in group', id)
    console.log('Participant:', participant)
    console.log('Action:', action) // 'created', 'revoked'
})
id
string
required
Group JID
participant
string
required
JID of the requesting user
action
RequestJoinAction
required
Action type
method
RequestJoinMethod
required
How the request was made
group.member-tag.update
object
Emitted when labels are assigned to group members.
groupId
string
required
Group JID
participant
string
required
Participant JID
label
string
required
Label assigned

Presence Events

presence.update
{ id: string; presences: { [participant: string]: PresenceData } }
Emitted when presence status of contacts changes (typing, recording, online, etc.).
sock.ev.on('presence.update', ({ id, presences }) => {
    console.log('Presence update in', id)
    
    for(const [participant, presence] of Object.entries(presences)) {
        console.log(participant, 'is', presence.lastKnownPresence)
        // 'unavailable', 'available', 'composing', 'recording'
    }
})

History Sync Events

messaging-history.set
object
Emitted when history sync is received (chats, contacts, messages from paired device).
sock.ev.on('messaging-history.set', ({ chats, contacts, messages, isLatest }) => {
    console.log('Received', chats.length, 'chats')
    console.log('Received', contacts.length, 'contacts')
    console.log('Received', messages.length, 'messages')
    console.log('Is latest:', isLatest)
})
chats
Chat[]
required
Chat history
contacts
Contact[]
required
Contact list
messages
WAMessage[]
required
Message history
isLatest
boolean
Whether this is the most recent sync
progress
number | null
Sync progress (0-1)
syncType
proto.HistorySync.HistorySyncType | null
Type of history sync

Blocklist Events

blocklist.set
{ blocklist: string[] }
Emitted when the complete blocklist is set.
sock.ev.on('blocklist.set', ({ blocklist }) => {
    console.log('Blocked users:', blocklist)
})
blocklist.update
{ blocklist: string[]; type: 'add' | 'remove' }
Emitted when users are added to or removed from the blocklist.
sock.ev.on('blocklist.update', ({ blocklist, type }) => {
    if(type === 'add') {
        console.log('Blocked:', blocklist)
    } else {
        console.log('Unblocked:', blocklist)
    }
})

Call Events

call
WACallEvent[]
Emitted when calls are received, accepted, or rejected.
sock.ev.on('call', (calls) => {
    for(const call of calls) {
        console.log('Call from:', call.from)
        console.log('Call status:', call.status) // 'offer', 'accept', 'reject', etc.
        console.log('Is video:', call.isVideo)
        console.log('Is group:', call.isGroup)
    }
})

Label Events

labels.edit
Label
Emitted when a label is created, edited, or deleted.
sock.ev.on('labels.edit', (label) => {
    console.log('Label:', label.id, label.name)
})
labels.association
{ association: LabelAssociation; type: 'add' | 'remove' }
Emitted when a label is associated with or removed from a chat/message.
sock.ev.on('labels.association', ({ association, type }) => {
    console.log('Label', association.labelId, type, 'to', association.chatId)
})

Newsletter Events

newsletter.reaction
object
Emitted when a newsletter message receives a reaction.
id
string
required
Newsletter ID
server_id
string
required
Server message ID
reaction
{ code?: string; count?: number; removed?: boolean }
required
Reaction data
newsletter.view
{ id: string; server_id: string; count: number }
Emitted when newsletter message view count is updated.
newsletter-participants.update
object
Emitted when newsletter participants are updated.
id
string
required
Newsletter ID
user
string
required
User JID
new_role
string
required
New role
action
string
required
Action performed
newsletter-settings.update
{ id: string; update: any }
Emitted when newsletter settings are updated.

Settings Events

settings.update
union
Emitted when WhatsApp settings are updated. Multiple types of settings:
sock.ev.on('settings.update', (setting) => {
    switch(setting.setting) {
        case 'unarchiveChats':
            console.log('Unarchive chats:', setting.value)
            break
        case 'locale':
            console.log('Locale:', setting.value)
            break
        // ... other settings
    }
})
Possible settings:
  • { setting: 'unarchiveChats'; value: boolean }
  • { setting: 'locale'; value: string }
  • { setting: 'disableLinkPreviews'; value: proto.SyncActionValue.IPrivacySettingDisableLinkPreviewsAction }
  • { setting: 'timeFormat'; value: proto.SyncActionValue.ITimeFormatAction }
  • And more…

LID Mapping Events

lid-mapping.update
LIDMapping
Emitted when phone number to LID (Linkable Identifier) mappings are updated.This is used internally for WhatsApp’s multi-device protocol.

Build docs developers (and LLMs) love