Chats, Presence & Privacy
The account-level surface of the socket: how your bot appears, what it does with chats, and every privacy switch WhatsApp exposes.
Presence
| Method | Notes |
sendPresenceUpdate(type, toJid?) | type: 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'. Without toJid it sets your global presence; with one, the typing/recording indicator in that chat |
presenceSubscribe(toJid, tcToken?) | Subscribe to a contact's presence β required before presence.update events arrive for them |
readMessages(keys) | Mark messages as read (blue ticks) β the polite bot pattern: read, then reply |
sendReceipt(jid, participant, messageIds, type) / sendReceipts(keys, type) | Lower-level receipt control: 'read' | 'read-self' | 'played' | β¦ |
await sock.sendPresenceUpdate('composing', jid) // "typingβ¦"
await new Promise(r => setTimeout(r, 1200)) // humans don't answer in 0 ms
await sock.sendPresenceUpdate('paused', jid)
await sock.readMessages([m.key])
await sock.sendMessage(jid, { text: 'Here you go.' })
With AunuAntiBan's typing simulation on (the default), text/caption sends do the composing step for you β don't double it.
Profile
| Method | Notes |
profilePictureUrl(jid, type?, timeoutMs?) | type: 'preview' | 'image' β thumbnail or full-size URL. Returns undefined when the picture is private/absent |
updateProfilePicture(jid, content) | Set a profile picture. Since v1.0.4 the crop is centered (upstream cropped top-left) and jimp v1 works again |
removeProfilePicture(jid) | Remove the picture |
updateProfileName(name) / updateProfileStatus(status) | Your account's display name and "about" text |
fetchStatus(...jids) | Status/about text for numbers |
getBusinessProfile(jid) | Business profile (description, email, websites, hours) when the account is a business |
Chat management
| Method | Notes |
chatModify(mod, jid) | The one call behind archive/pin/mute/read state β see the recipes below |
star(jid, messages, star) | Star/unstar specific messages (messages: [{ id, fromMe }]) |
addChatLabel(jid, labelId) / removeChatLabel(jid, labelId) | Business labels on chats |
addMessageLabel(jid, messageId, labelId) / removeMessageLabel(...) | Business labels on individual messages |
addLabel(jid, labelAction) | Create/edit label definitions |
fetchDisappearingDuration(...jids) | Current disappearing-message duration per chat |
updateDefaultDisappearingMode(duration) | Default timer for new chats (seconds) |
// Archive a chat, pin another, mute a loud one for 8 hours
await sock.chatModify({ archive: true }, quietJid)
await sock.chatModify({ pin: true }, importantJid)
await sock.chatModify({ mute: Date.now() + 8 * 60 * 60 * 1000 }, loudJid)
// Mark as unread for yourself, and clear:
await sock.chatModify({ markRead: false }, jid)
await sock.chatModify({ clear: 'all' }, jid)
Blocklist & contacts
| Method | Notes |
fetchBlocklist() | All blocked JIDs |
updateBlockStatus(jid, 'block' | 'unblock') | Block or unblock β changes fire blocklist.update |
onWhatsApp(...jids) | Check which numbers are registered on WhatsApp β { exists, jid }[] (input in international format) |
addOrEditContact(jid, contactAction) / removeContact(jid) | Address-book sync actions |
const [info] = await sock.onWhatsApp('12125550123')
if (info?.exists) console.log('Registered as', info.jid)
Privacy settings β the complete switchboard
Read everything at once with fetchPrivacySettings(); write each switch individually:
| Method | Values |
updateLastSeenPrivacy(value) | 'all' | 'contacts' | 'contact_blacklist' | 'none' (per-switch enums vary slightly β the types enforce them) |
updateProfilePicturePrivacy(value) |
updateStatusPrivacy(value) |
updateGroupsAddPrivacy(value) |
updateOnlinePrivacy(value) | 'all' | 'match_last_seen' |
updateReadReceiptsPrivacy(value) | 'all' | 'none' |
updateCallPrivacy(value) | Who can call the account |
updateMessagesPrivacy(value) | Message-related privacy mode |
updateDisableLinkPreviewsPrivacy(bool) | Stop generating link previews for your own sends |
Privacy is account-wide, not per-bot-session. These switches change the real WhatsApp account's settings and are visible in the phone app. Set them deliberately β ideally once, at provisioning time.