Skip to Content
Extensions & native()

Extensions & native()

WhatsApp can do things the Chat SDK has no vocabulary for. The adapter exposes them as typed extension methods — narrow any Thread, Channel, or adapter with the guards:

import { isZaileysAdapter, requireZaileysAdapter } from 'chat-adapter-zaileys' bot.onSubscribedMessage(async (thread, message) => { const wa = requireZaileysAdapter(thread) // throws if not a zaileys thread // … })

Extension reference

MethodWhat it does
reply(message, content)Quoted reply — WhatsApp’s native reply bubble. Accepts any postable, media included.
markRead(threadId)Send read receipts (blue ticks) for the chat.
setPresence('available' | 'unavailable')Global online/offline status.
startTyping(threadId)”typing…” indicator (also used by the SDK automatically).
startRecording(threadId)”recording audio…” indicator.
setDisappearing(threadId, seconds)Toggle disappearing messages (0 disables).
sendLocation({ threadId, latitude, longitude, name?, address? })Native map-pin message.
sendPoll({ threadId, question, options, selectableCount? })Native poll — see Polls.
sendSticker(threadId, src)Sticker from webp/png/jpeg — Zaileys converts, animated Lottie included.
sendVoiceNote(threadId, src)Push-to-talk audio bubble.
sendContact(threadId, vcard)Contact card.
forwardMessage(threadId, messageId, toThreadId)Forward to another chat.
pinMessage(threadId, messageId) / unpinMessage(…)Pin / unpin in chat.
fetchGroupParticipants(threadId)Members with isAdmin / isSuperAdmin flags. Throws for non-groups.
getUser(userId)UserInfo from the contact store + profile picture.
openDM(userId)Thread ID for a DM (accepts digits or a jid).
onPollVote(handler)Decrypted poll votes — see Polls.
const wa = requireZaileysAdapter(thread) await wa.markRead(thread.id) await wa.sendLocation({ threadId: thread.id, latitude: -6.2, longitude: 106.8, name: 'Jakarta' }) await wa.sendVoiceNote(thread.id, oggBuffer) const admins = (await wa.fetchGroupParticipants(thread.id)).filter((p) => p.isAdmin)

native() — the everything hatch

One method exposes the entire Zaileys message builder, pre-targeted at a thread. Every content type and modifier from Zaileys → Sending Messages is available:

await wa.native(thread.id).image(buffer, { viewOnce: true }) await wa.native(thread.id).album([ { type: 'image', src: './a.jpg' }, { type: 'image', src: './b.jpg' }, ]) await wa.native(thread.id).list({ title: 'Menu', buttonText: 'Open', sections }) await wa.native(thread.id).event({ name: 'Standup', startTime }) await wa.native(thread.id).text('hey everyone').mentionAll() await wa.native(thread.id).text('secret').disappearing(86_400)

Text · image · video · video note · audio · document · sticker · buttons · carousel · list · poll · location · contact · template · event · group invite · product · album — plus .reply(), .mentions(), .mentionAll(), .disappearing() modifiers. Awaiting the builder returns the sent WAMessageKey.

Messages sent through native() are not tracked for author.isMe echo detection — a minor trade-off for full builder access.

adapter.client — the whole Zaileys client

Everything else lives one property away. Groups, communities, newsletters, privacy, profile, contacts, business catalogs, broadcast, the command framework, plugins, LID↔PN mapping:

whatsapp.client.group.promote(groupJid, [userJid]) whatsapp.client.newsletter.create('My Channel', 'Updates') whatsapp.client.privacy.updateLastSeen('contacts') whatsapp.client.broadcast(jids, (b) => b.text('Announcement'), { rateLimitPerSec: 5 }) whatsapp.client.command('ping', (ctx) => ctx.reply('pong 🏓'))

The complete surface is documented at zeative.github.io/zaileys.