heisbroken-baileys
v1.0.0
Published
Baileys-compatible WhatsApp Multi-Device API (from scratch implementation)
Downloads
162
Maintainers
Readme
██████╗ ██████╗ ███╗ ██╗███████╗██████╗ ██╔════╝ ██╔═══██╗████╗ ██║██╔════╝██╔══██╗ ██║ ███╗██║ ██║██╔██╗ ██║█████╗ ██████╔╝ ██║ ██║██║ ██║██║╚██╗██║██╔══╝ ██╔══██╗ ╚██████╔╝╚██████╔╝██║ ╚████║███████╗██║ ██║ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝
LONER — From-scratch WhatsApp Web API Version: 1.0.0 | Package: @loner/baileys | License: MIT | Node: >=18.0.0
A complete WhatsApp Multi-Device API implementation built from the protocol level up. Not a wrapper around Baileys.
📚 Table of Contents
- Quick Start
- API Reference
- Events
- Message Types
- Disconnect Reasons
- Button Messages
- List Messages
- Poll Messages
- Location Messages
- Contact Messages
- Feature Modules
- Building From Scratch
🚀 Quick Start
npm install heisbroken-baileys
# or install directly from GitHub
# npm install loner/baileysconst { makeWASocket, useMultiFileAuthState } = require('@loner/baileys')
async function start() {
// Baileys-style auth usage
const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')
const sock = makeWASocket({
auth: state,
printQRInTerminal: true,
})
sock.ev.on('creds.update', saveCreds)
sock.ev.on('messages.upsert', ({ messages }) => {
const msg = messages[0]
const text = msg.message?.conversation || ''
console.log(`Received: ${text}`)
if (text === '!ping') {
sock.sendMessage(msg.key.remoteJid, { text: 'Pong!' })
}
})
sock.ev.on('connection.update', ({ connection }) => {
if (connection === 'open') console.log('✅ Connected!')
})
await sock.connect()
}
start()📦 Documenting this on npm
npm automatically shows this README.md on your package page, so keep this file as your main documentation source.
Recommended package metadata
description: one-line summary shown in search/listingskeywords: helps discoveryhomepage,repository,bugs: adds links on npm pagefiles: controls what gets published
Publish/update flow
npm login
npm version patch
npm publish --access publicFor scoped packages like @loner/baileys, use --access public the first time.
📖 API Reference
makeWASocket(config)
Creates a WhatsApp socket connection. Returns a sock object with all messaging methods.
Parameters:
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| config.auth | { state, auth } | null | Auth state from useMultiFileAuthState() |
| config.authDir | string | './loner_auth' | Directory for auth files |
| config.url | string | 'wss://web.whatsapp.com/ws/chat' | WebSocket URL |
| config.reconnectInterval | number | 5000 | Reconnect delay (ms) |
| config.maxRetries | number | 10 | Max reconnect attempts |
| config.logLevel | string | 'info' | Logger level |
Returns: sock object with methods below:
useMultiFileAuthState(authDir)
Creates a multi-file auth state for session persistence.
const { state, saveCreds, auth } = await useMultiFileAuthState('./auth')Returns:
| Property | Type | Description |
|----------|------|-------------|
| state.creds | object\|null | Stored credentials (null if new) |
| state.keys | object\|null | Stored keys (null if new) |
| saveCreds | function | Call to persist credentials |
| auth | AuthManager | Auth manager instance |
sock.sendMessage(jid, content, opts)
Send any message type. The content object determines the type.
Text message:
await sock.sendMessage('[email protected]', { text: 'Hello!' })Text with quoted message:
await sock.sendMessage(jid, { text: 'Reply text' }, { quoted: msg })Image message:
await sock.sendMessage(jid, {
image: 'https://example.com/image.jpg',
caption: 'Nice pic!'
})Video message:
await sock.sendMessage(jid, {
video: 'https://example.com/video.mp4',
caption: 'Check this out'
})Audio message:
await sock.sendMessage(jid, { audio: 'https://example.com/audio.mp3' })Buttons (Quick Reply)
Send interactive buttons:
await sock.sendMessage(jid, {
text: 'Choose an option:',
buttons: [
{ id: 'opt1', text: 'Option 1' },
{ id: 'opt2', text: 'Option 2' },
{ id: 'opt3', text: 'Option 3' },
]
})List Messages
Send a list with sections and rows:
await sock.sendMessage(jid, {
text: 'Select from the list:',
sections: [
{
title: 'Section 1',
rows: [
{ id: 'row1', title: 'Row 1', description: 'Description 1' },
{ id: 'row2', title: 'Row 2', description: 'Description 2' },
]
},
{
title: 'Section 2',
rows: [
{ id: 'row3', title: 'Row 3' },
]
}
],
buttonText: 'View Options'
})Poll Messages
Send a poll:
await sock.sendMessage(jid, {
poll: {
name: 'What is your favorite language?',
options: ['JavaScript', 'Python', 'Go', 'Rust']
}
})Location Messages
Send a location:
await sock.sendMessage(jid, {
location: {
latitude: 6.5244,
longitude: 3.3792,
name: 'Lagos, Nigeria'
}
})Contact Messages
Send a contact (vCard):
await sock.sendMessage(jid, {
contacts: [{ name: 'John Doe', phone: '2348012345678' }]
})sock.sendReaction(jid, messageId, emoji)
React to a message:
await sock.sendReaction(jid, 'MESSAGE_ID', '👍')sock.editMessage(jid, messageId, newText)
Edit a sent message:
await sock.editMessage(jid, 'MESSAGE_ID', 'Edited text')sock.deleteMessage(jid, messageId)
Delete a message for everyone:
await sock.deleteMessage(jid, 'MESSAGE_ID')sock.readMessages([msgKey])
Mark messages as read:
await sock.readMessages([{ remoteJid: jid, id: 'MSG_ID' }])sock.sendPresenceUpdate(type, jid)
Update presence:
sock.sendPresenceUpdate('available') // Online
sock.sendPresenceUpdate('unavailable') // Offline
sock.sendPresenceUpdate('composing', jid) // Typing
sock.sendPresenceUpdate('recording', jid) // Recording voice👥 Group Operations
// Create a group
await sock.groupCreate('Group Name', ['[email protected]'])
// Get group metadata
await sock.groupMetadata(jid)
// Update subject/description
await sock.groupUpdateSubject(jid, 'New Name')
await sock.groupUpdateDescription(jid, 'Description')
// Manage participants
await sock.groupParticipantsUpdate(jid, ['[email protected]'], 'add')
await sock.groupParticipantsUpdate(jid, ['[email protected]'], 'remove')
await sock.groupParticipantsUpdate(jid, ['[email protected]'], 'promote')
await sock.groupParticipantsUpdate(jid, ['[email protected]'], 'demote')
// Invite codes
await sock.groupGetInviteCode(jid)
await sock.groupRevokeInviteCode(jid)
await sock.groupAcceptInvite('CODE')
// Settings
await sock.groupSettingUpdate(jid, 'announcement') // Only admins can send
await sock.groupSettingUpdate(jid, 'restrict') // Only admins can edit info
await sock.groupToggleEphemeral(jid, 86400) // Disappearing messages👤 Contact Operations
// Block/unblock
await sock.block('[email protected]')
await sock.unblock('[email protected]')
// Profile
await sock.updateProfilePicture(jid, url)
await sock.removeProfilePicture(jid)
await sock.updateProfileStatus('My status')
// Business profile
await sock.updateBusinessProfile({ description, website, email })🔗 Pairing
Phone Number Pairing
const result = await sock.requestPairingCode('2348012345678')
console.log('Code:', result.code)
// User enters this code in WhatsApp > Link a Device > Link Using Phone NumberQR Code
The QR data is emitted via the qr event:
sock.ev.on('qr', (qrData) => {
console.log('Scan this QR:', qrData)
// Display QR code in terminal or web
})📡 Events
sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {})
sock.ev.on('messages.upsert', ({ messages, type }) => {})
sock.ev.on('presence.update', (node) => {})
sock.ev.on('receipt', (node) => {})
sock.ev.on('notification', (node) => {})
sock.ev.on('stream.error', (node) => {})
sock.ev.on('group.update', (node) => {})
sock.ev.on('picture.change', (node) => {})
sock.ev.on('status.update', (node) => {})
sock.ev.on('qr', (qrData) => {})
sock.ev.on('challenge', (data) => {})
sock.ev.on('iq_result', (node) => {})connection.update Event
| Property | Type | Description |
|----------|------|-------------|
| connection | string | 'connecting', 'open', 'close' |
| lastDisconnect.error | Error | The error that caused disconnect |
| lastDisconnect.date | Date | When the disconnect happened |
messages.upsert Event
| Property | Type | Description |
|----------|------|-------------|
| messages | Array | Array of message objects |
| messages[].key | object | { remoteJid, fromMe, id, participant } |
| messages[].message | object | Message content (conversation, imageMessage, etc.) |
| messages[].messageType | string | Type of message |
| messages[].messageTimestamp | number | Unix timestamp |
| type | string | Upsert type ('notify', etc.) |
📋 Message Types
const { WAMessageType } = require('@loner/baileys')
WAMessageType.text // 'text'
WAMessageType.image // 'image'
WAMessageType.video // 'video'
WAMessageType.audio // 'audio'
WAMessageType.document // 'document'
WAMessageType.sticker // 'sticker'
WAMessageType.poll // 'poll'
WAMessageType.location // 'location'
WAMessageType.contact // 'contact'
WAMessageType.reaction // 'reaction'
WAMessageType.list // 'list'
WAMessageType.buttons // 'buttons'
WAMessageType.liveLocation // 'live_location'🔌 Disconnect Reasons
const { DisconnectReason } = require('@loner/baileys')
DisconnectReason.connectionClosed // 'connectionClosed'
DisconnectReason.connectionLost // 'connectionLost'
DisconnectReason.connectionReplaced // 'connectionReplaced'
DisconnectReason.timedOut // 'timedOut'
DisconnectReason.loggedOut // 'loggedOut'
DisconnectReason.badSession // 'badSession'
DisconnectReason.restartRequired // 'restartRequired'🧩 Feature Modules
Access advanced managers directly for full control:
const sock = makeWASocket()
// Group manager
sock.groupManager.getMetadata(jid)
sock.groupManager.create('Name', [participants])
sock.groupManager.setSubject(jid, 'New Name')
sock.groupManager.setDescription(jid, 'Desc')
sock.groupManager.setAnnouncement(jid, true)
sock.groupManager.setDisappearingMessages(jid, 86400)
// Contact manager
sock.contactManager.block(jid)
sock.contactManager.setStatus('My status')
sock.contactManager.setProfilePicture(jid, url)
sock.contactManager.getBusinessProfile(jid)
// Presence manager
sock.presenceManager.online()
sock.presenceManager.offline()
sock.presenceManager.typing(jid)
sock.presenceManager.recording(jid)
// Receipt manager
sock.receiptManager.read(jid, [messageIds])
sock.receiptManager.react(jid, messageId, '👍')
sock.receiptManager.editMessage(jid, messageId, 'new text')
sock.receiptManager.deleteForEveryone(jid, messageId)
// Media manager
sock.mediaManager.encryptMedia(data, 'image')
sock.mediaManager.downloadFromUrl(url)
// Newsletter manager
sock.newsletterManager.getNewsletterInfo(jid)
sock.newsletterManager.subscribe(jid)
sock.newsletterManager.unsubscribe(jid)
// Story manager
sock.storyManager.postText('Status update')
sock.storyManager.postImage(url, { caption: 'Nice' })
sock.storyManager.postVideo(url)
// Chat operations
sock.chatManager.mute(jid, 86400)
sock.chatManager.archive(jid)
sock.chatManager.pin(jid)
sock.chatManager.markUnread(jid)
// Label manager
sock.labelManager.getAll()
sock.labelManager.create('VIP', 3)
sock.labelManager.addToChat(labelId, jid)
// Business manager
sock.businessManager.getCatalog(jid)
sock.businessManager.getProduct(productId, jid)
sock.businessManager.updateProfile({ description, website })
// Device manager
sock.deviceManager.getDevices()
sock.deviceManager.removeDevice(deviceId)
// App state manager
sock.appStateManager.sync(['regular', 'regular_low'])
sock.appStateManager.patch([{ collection: 'regular', value: {} }])
// Multi-device pairing
sock.multiDeviceManager.requestPairingCode('2348012345678')
// History sync
sock.historySync.requestSync()
sock.historySync.getChats()🏗 Architecture
loner/
├── index.js # Public API — makeWASocket(), useMultiFileAuthState()
├── src/
│ ├── binary/ # WhatsApp binary protocol (encoder, decoder, tokens)
│ ├── crypto/ # X25519 ECDH, AES-256-CBC, HMAC-SHA256, HKDF
│ ├── socket/ # WebSocket connection manager + keep-alive
│ ├── auth/ # QR login, phone pairing, credential persistence
│ ├── messages/ # Message builders, location, receipts
│ ├── groups/ # Group management (create, manage, settings)
│ ├── contacts/ # Block, profile, business, privacy
│ ├── presence/ # Online/typing/recording indicators
│ ├── media/ # Encrypted media upload/download
│ ├── newsletter/ # Channels/newsletter support
│ ├── stories/ # Status posts & privacy
│ ├── chat/ # Mute, archive, pin, clear
│ ├── labels/ # Create, manage, assign labels
│ ├── business/ # Catalog, products, collections
│ ├── device/ # List/remove linked devices
│ ├── appstate/ # App state sync
│ └── sync/ # History sync🧪 Testing
npm testTests cover: binary protocol round-trip, crypto operations, message builders, auth manager, full API surface.
📄 License
MIT — built from scratch, not a fork. Use freely.
