npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kaileys

v7.0.0-rc11

Published

A WebSockets library for interacting with WhatsApp Web

Downloads

153

Readme

Kaileys

npm version License Downloads


✨ Fitur Utama

  • 🚀 Modern & Cepat - Dibangun di atas WhiskeySockets/Baileys dengan teknologi terbaru
  • 🔧 Perbaikan @lid & @jid - Mengatasi masalah @lid ke @pn di grup WhatsApp
  • 📱 Dukungan Multi-Device - Mendukung koneksi multi-device WhatsApp
  • 🔐 Enkripsi End-to-End - Komunikasi terenkripsi penuh
  • 📨 Semua Jenis Pesan - Dukung teks, media, polling, dll.
  • 🔑 Custom Pairing Code - Support pairing code kustom (default: KAELZDEV)
  • 📢 Auto Follow Saluran Update - Otomatis follow saluran update Kaileys (lihat Transparansi)

⚠️ Peringatan

Proyek ini tidak berafiliasi, terkait, diotorisasi, didukung, atau terhubung secara resmi dengan WhatsApp atau anak perusahaannya. Situs resmi WhatsApp ada di whatsapp.com.

Pengelola Kaileys tidak mendukung penggunaan aplikasi ini untuk melanggar Ketentuan Layanan WhatsApp. Kami menekankan tanggung jawab pribadi pengguna untuk menggunakan secara adil dan bertanggung jawab.

Gunakan dengan bijak. Hindari spam. Jangan gunakan otomatisasi berlebihan.


📢 Transparansi

Kaileys secara otomatis mem-follow 2 saluran WhatsApp milik Kaileys saat bot pertama kali terhubung. Saluran ini digunakan untuk:

  • 📣 Informasi update versi terbaru
  • 🐛 Pemberitahuan bug kritis
  • 📋 Changelog & release notes

Jika Anda tidak ingin fitur ini, gunakan versi original @whiskeysockets/baileys.


📦 Instalasi

Versi Stabil (Direkomendasikan)

npm i kaileys

Versi Edge (Fitur Terbaru)

npm i kaileys@latest
# atau
yarn add kaileys@latest

Impor di Kode

const { default: makeWASocket } = require("kaileys")
// atau ES6
import makeWASocket from "kaileys"

🚀 Mulai Cepat

Contoh Dasar

const { default: makeWASocket, DisconnectReason, useMultiFileAuthState } = require('kaileys')
const { Boom } = require('@hapi/boom')

async function connectToWhatsApp() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info_kaileys')
    
    const sock = makeWASocket({
        auth: state,
        printQRInTerminal: true,
        browser: ['Kaileys', 'Desktop', '3.0']
    })

    sock.ev.on('connection.update', (update) => {
        const { connection, lastDisconnect } = update
        if(connection === 'close') {
            const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
            console.log('Koneksi tertutup karena ', lastDisconnect.error, ', reconnecting ', shouldReconnect)
            if(shouldReconnect) {
                connectToWhatsApp()
            }
        } else if(connection === 'open') {
            console.log('✅ Berhasil terhubung ke WhatsApp!')
        }
    })

    sock.ev.on('messages.upsert', async ({ messages }) => {
        for (const m of messages) {
            if (!m.message) continue
            console.log('📱 Pesan baru:', JSON.stringify(m, undefined, 2))
            await sock.sendMessage(m.key.remoteJid!, { 
                text: 'Halo! Saya bot WhatsApp menggunakan Kaileys 🤖' 
            })
        }
    })

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

connectToWhatsApp()

📋 Daftar Isi


🔌 Koneksi Akun

WhatsApp menyediakan API multi-device yang memungkinkan Kaileys terautentikasi sebagai klien WhatsApp sekunder melalui QR code atau pairing code.

Hubungkan dengan QR Code

[!TIP]
Sesuaikan nama browser menggunakan konstanta Browsers. Lihat konfigurasi yang tersedia di bawah.

const { default: makeWASocket, Browsers } = require("kaileys")

const sock = makeWASocket({
    browser: Browsers.ubuntu('My App'),
    printQRInTerminal: true
})

Setelah koneksi berhasil, QR code akan muncul di terminal. Pindai dengan WhatsApp di ponsel Anda untuk login.

Hubungkan dengan Pairing Code

[!IMPORTANT]
Pairing code bukan bagian dari Mobile API. Ini memungkinkan koneksi WhatsApp Web tanpa QR code, tapi hanya satu perangkat.

Nomor telepon harus tanpa +, (), atau -, dan sertakan kode negara.

const { default: makeWASocket } = require("kaileys")

const sock = makeWASocket({
    printQRInTerminal: false
})

// Pairing dengan kode default (KAELZDEV)
if (!sock.authState.creds.registered) {
    const number = '6285134816783'
    const code = await sock.requestPairingCode(number)
    console.log('🔑 Kode Pairing:', code) // Output: KAELZDEV
}

// Pairing dengan kode kustom (harus 8 karakter)
if (!sock.authState.creds.registered) {
    const pair = "MYCODE12" // tepat 8 karakter
    const number = '6285134816783'
    const code = await sock.requestPairingCode(number, pair)
    console.log('🔑 Kode Pairing Kustom:', code)
}

[!NOTE] Default pairing code Kaileys adalah KAELZDEV. Kode kustom harus tepat 8 karakter.

Terima Riwayat Lengkap

  1. Setel syncFullHistory ke true.
  2. Untuk koneksi seperti desktop (riwayat pesan lebih banyak), gunakan:
const { default: makeWASocket, Browsers } = require("kaileys")

const sock = makeWASocket({
    browser: Browsers.macOS('Desktop'),
    syncFullHistory: true
})

⚙️ Catatan Penting Konfigurasi Socket

Caching Metadata Grup (Direkomendasikan)

const { default: makeWASocket } = require("kaileys")
const NodeCache = require('node-cache')

const groupCache = new NodeCache({ stdTTL: 5 * 60, useClones: false })

const sock = makeWASocket({
    cachedGroupMetadata: async (jid) => groupCache.get(jid)
})

sock.ev.on('groups.update', async ([event]) => {
    const metadata = await sock.groupMetadata(event.id)
    groupCache.set(event.id, metadata)
})

sock.ev.on('group-participants.update', async (event) => {
    const metadata = await sock.groupMetadata(event.id)
    groupCache.set(event.id, metadata)
})

Perbaiki Sistem Retry & Dekripsi Vote Poll

const sock = makeWASocket({
    getMessage: async (key) => await getMessageFromStore(key)
})

Terima Notifikasi di Aplikasi WhatsApp

const sock = makeWASocket({
    markOnlineOnConnect: false
})

💾 Simpan Info Auth

const makeWASocket = require("kaileys").default
const { useMultiFileAuthState } = require("kaileys")

async function connect() {
    const { state, saveCreds } = await useMultiFileAuthState('auth_info_kaileys')
    const sock = makeWASocket({ auth: state })
    sock.ev.on('creds.update', saveCreds)
}

connect()

[!IMPORTANT]
useMultiFileAuthState menyimpan status auth di folder. Untuk produksi, gunakan database SQL/No-SQL.


🗄️ Implementasi Data Store

Kaileys tidak menyertakan penyimpanan default untuk obrolan, kontak, atau pesan. Namun, implementasi in-memory sederhana disediakan.

[!IMPORTANT]
Sangat direkomendasikan membangun data store sendiri — menyimpan seluruh riwayat obrolan di memori sangat boros RAM.

const makeWASocket = require("kaileys").default
const { makeInMemoryStore } = require("kaileys")

const store = makeInMemoryStore({ })

store.readFromFile('./kaileys_store.json')

setInterval(() => {
    store.writeToFile('./kaileys_store.json')
}, 10_000)

const sock = makeWASocket({ })
store.bind(sock.ev)

sock.ev.on('chats.upsert', () => {
    console.log('dapat obrolan', store.chats.all())
})

sock.ev.on('contacts.upsert', () => {
    console.log('dapat kontak', Object.values(store.contacts))
})

🆔 Penjelasan ID WhatsApp

| Tipe | Format | Contoh | |------|--------|--------| | Personal | [kode negara][nomor]@s.whatsapp.net | [email protected] | | Grup | [id]@g.us | [email protected] | | Siaran | [timestamp]@broadcast | - | | Cerita | status@broadcast | - |


📤 Kirim Pesan

Pesan Teks

await sock.sendMessage(jid, { text: 'halo dunia' })

Pesan Kutipan

await sock.sendMessage(jid, { text: 'halo dunia' }, { quoted: message })

Sebut Pengguna

await sock.sendMessage(jid, {
    text: '@12345678901',
    mentions: ['[email protected]']
})

Teruskan Pesan

const msg = getMessageFromStore()
await sock.sendMessage(jid, { forward: msg })

Pesan Lokasi

await sock.sendMessage(jid, {
    location: {
        degreesLatitude: 24.121231,
        degreesLongitude: 55.1121221
    }
})

Pesan Kontak

const vcard = 'BEGIN:VCARD\n'
            + 'VERSION:3.0\n'
            + 'FN:Jeff Singh\n'
            + 'ORG:Ashoka Uni;\n'
            + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\n'
            + 'END:VCARD'

await sock.sendMessage(id, {
    contacts: {
        displayName: 'Jeff',
        contacts: [{ vcard }]
    }
})

Pesan Reaksi

await sock.sendMessage(jid, {
    react: {
        text: '💖', // kosongkan untuk hapus reaksi
        key: message.key
    }
})

Pin Pesan

| Waktu | Detik | |-------|-------| | 24 jam | 86.400 | | 7 hari | 604.800 | | 30 hari | 2.592.000 |

await sock.sendMessage(jid, {
    pin: {
        type: 1, // 0 untuk hapus
        time: 86400,
        key: message.key
    }
})

Pesan Poll

await sock.sendMessage(jid, {
    poll: {
        name: 'Poll Saya',
        values: ['Opsi 1', 'Opsi 2'],
        selectableCount: 1,
        toAnnouncementGroup: false
    }
})

Kirim dengan Pratinjau Tautan

Tambahkan link-preview-js terlebih dahulu:

npm i link-preview-js
await sock.sendMessage(jid, {
    text: 'Halo, ini dikirim menggunakan https://npmjs.com/package/kaileys'
})

Pesan Media

[!NOTE] Bisa gunakan { stream: Stream }, { url: Url }, atau Buffer langsung.

Gif

await sock.sendMessage(jid, {
    video: fs.readFileSync('Media/ma_gif.mp4'),
    caption: 'halo dunia',
    gifPlayback: true
})

Video

await sock.sendMessage(id, {
    video: { url: './Media/ma_gif.mp4' },
    caption: 'halo dunia',
    ptv: false // true untuk video note
})

Audio

await sock.sendMessage(jid, {
    audio: { url: './Media/audio.mp3' },
    mimetype: 'audio/mp4'
})

Gambar

await sock.sendMessage(id, {
    image: { url: './Media/ma_img.png' },
    caption: 'halo dunia'
})

View Once

await sock.sendMessage(id, {
    image: { url: './Media/ma_img.png' },
    viewOnce: true,
    caption: 'halo dunia'
})

✏️ Ubah Pesan

Hapus Pesan (untuk semua)

const msg = await sock.sendMessage(jid, { text: 'halo dunia' })
await sock.sendMessage(jid, { delete: msg.key })

Edit Pesan

await sock.sendMessage(jid, {
    text: 'teks terupdate di sini',
    edit: response.key,
})

🖼️ Manipulasi Pesan Media

Unduh Pesan Media

import { createWriteStream } from 'fs'
import { downloadMediaMessage, getContentType } from 'kaileys'

sock.ev.on('messages.upsert', async ({ messages: [m] }) => {
    if (!m.message) return
    const messageType = getContentType(m)

    if (messageType === 'imageMessage') {
        const stream = await downloadMediaMessage(
            m,
            'stream',
            { },
            {
                logger,
                reuploadRequest: sock.updateMediaMessage
            }
        )
        const writeStream = createWriteStream('./my-download.jpeg')
        stream.pipe(writeStream)
    }
})

Unggah Ulang Pesan Media

await sock.updateMediaMessage(msg)

📞 Tolak Panggilan

await sock.rejectCall(callId, callFrom)

💬 Status Kirim

Baca Pesan

await sock.readMessages([key])

Update Kehadiran

presence bisa: available, composing, recording, paused, unavailable.

await sock.sendPresenceUpdate('available', jid)

📁 Ubah Obrolan

[!IMPORTANT] Jika salah update, WA bisa logout dari semua perangkat.

Arsipkan Obrolan

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({ archive: true, lastMessages: [lastMsgInChat] }, jid)

Bisukan/Buka Bisukan

| Waktu | Milidetik | |-------|-----------| | Hapus | null | | 8 jam | 86.400.000 | | 7 hari | 604.800.000 |

await sock.chatModify({ mute: 8 * 60 * 60 * 1000 }, jid) // bisukan 8 jam
await sock.chatModify({ mute: null }, jid) // buka bisukan

Tandai Dibaca/Tidak Dibaca

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({ markRead: false, lastMessages: [lastMsgInChat] }, jid)

Hapus Pesan untuk Saya

await sock.chatModify({
    clear: {
        messages: [{ id: 'ATWYHDNNWU81732J', fromMe: true, timestamp: '1654823909' }]
    }
}, jid)

Hapus Obrolan

const lastMsgInChat = await getLastMessageInChat(jid)
await sock.chatModify({
    delete: true,
    lastMessages: [{ key: lastMsgInChat.key, messageTimestamp: lastMsgInChat.messageTimestamp }]
}, jid)

Pin/Hapus Pin

await sock.chatModify({ pin: true }, jid) // atau false

Bintangi/Hapus Bintang

await sock.chatModify({
    star: {
        messages: [{ id: 'messageID', fromMe: true }],
        star: true
    }
}, jid)

Pesan Menghilang

| Waktu | Detik | |-------|-------| | Hapus | 0 | | 24 jam | 86.400 | | 7 hari | 604.800 | | 90 hari | 7.776.000 |

await sock.sendMessage(jid, { disappearingMessagesInChat: WA_DEFAULT_EPHEMERAL })
await sock.sendMessage(jid, { text: 'halo' }, { ephemeralExpiration: WA_DEFAULT_EPHEMERAL })
await sock.sendMessage(jid, { disappearingMessagesInChat: false }) // matikan

👤 Query Pengguna

Periksa ID Ada di WhatsApp

const [result] = await sock.onWhatsApp(jid)
if (result.exists) console.log(`${jid} ada di WhatsApp, sebagai jid: ${result.jid}`)

Query Riwayat Obrolan

const msg = await getOldestMessageInChat(jid)
await sock.fetchMessageHistory(50, msg.key, msg.messageTimestamp)

Ambil Status

const status = await sock.fetchStatus(jid)
console.log('status: ' + status)

Ambil Foto Profil

const ppUrl = await sock.profilePictureUrl(jid) // resolusi rendah
const ppUrl = await sock.profilePictureUrl(jid, 'image') // resolusi tinggi

Ambil Kehadiran

sock.ev.on('presence.update', console.log)
await sock.presenceSubscribe(jid)

🔄 Ubah Profil

await sock.updateProfileStatus('Halo Dunia!')
await sock.updateProfileName('Nama Saya')
await sock.updateProfilePicture(jid, { url: './new-profile-picture.jpeg' })
await sock.removeProfilePicture(jid)

👥 Grup

Buat Grup

const group = await sock.groupCreate('Grup Saya', ['[email protected]', '[email protected]'])
console.log('grup dibuat dengan id: ' + group.gid)

Tambah/Hapus/Turunkan/Naikkan

await sock.groupParticipantsUpdate(
    jid,
    ['[email protected]', '[email protected]'],
    'add' // 'remove', 'demote', 'promote'
)

Ubah Pengaturan

await sock.groupSettingUpdate(jid, 'announcement') // hanya admin kirim
await sock.groupSettingUpdate(jid, 'not_announcement') // semua bisa kirim
await sock.groupSettingUpdate(jid, 'locked') // hanya admin ubah info
await sock.groupSettingUpdate(jid, 'unlocked') // semua bisa ubah info

Kode Undangan

const code = await sock.groupInviteCode(jid)
console.log('link: https://chat.whatsapp.com/' + code)

await sock.groupRevokeInvite(jid) // cabut kode

const response = await sock.groupAcceptInvite(code) // gabung via kode

Query Metadata

const metadata = await sock.groupMetadata(jid)
console.log(metadata.id + ', judul: ' + metadata.subject + ', deskripsi: ' + metadata.desc)

Permintaan Gabung

const response = await sock.groupRequestParticipantsList(jid)
await sock.groupRequestParticipantsUpdate(jid, ['[email protected]'], 'approve') // atau 'reject'

🔒 Privasi

await sock.updateBlockStatus(jid, 'block') // blokir
await sock.updateBlockStatus(jid, 'unblock') // buka blokir

const privacySettings = await sock.fetchPrivacySettings(true)
const blocklist = await sock.fetchBlocklist()

await sock.updateLastSeenPrivacy('all') // 'contacts' | 'contact_blacklist' | 'none'
await sock.updateOnlinePrivacy('all') // 'match_last_seen'
await sock.updateProfilePicturePrivacy('all')
await sock.updateStatusPrivacy('all')
await sock.updateReadReceiptsPrivacy('all')
await sock.updateGroupsAddPrivacy('all')

📢 Daftar Siaran & Cerita

await sock.sendMessage(
    jid,
    { image: { url: url }, caption: caption },
    { backgroundColor, font, statusJidList, broadcast: true }
)

const bList = await sock.getBroadcastListInfo('1234@broadcast')
console.log(`nama: ${bList.name}, penerima: ${bList.recipients}`)

🛠️ Fungsi Kustom

Aktifkan Level Debug

const sock = makeWASocket({
    logger: P({ level: 'debug' }),
})

Daftarkan Callback WebSocket

sock.ws.on('CB:edge_routing', (node) => { })
sock.ws.on('CB:edge_routing,id:abcd', (node) => { })
sock.ws.on('CB:edge_routing,id:abcd,routing_info', (node) => { })

💡 Tips & Praktik Terbaik

  • Gunakan Caching — Cache metadata grup untuk performa lebih baik
  • Tangani Rekoneksi — Implementasikan auto-reconnect untuk kestabilan
  • Kelola Store — Gunakan database (MongoDB, PostgreSQL) untuk produksi
  • Penanganan Error — Bungkus panggilan socket dengan try-catch
  • Batas Rate — Hormati batas WhatsApp untuk hindari ban
  • Keamanan — Jangan bagikan kredensial auth; gunakan variabel lingkungan

📄 Lisensi

Didistribusikan di bawah Lisensi MIT. Lihat LICENSE untuk info lebih lanjut.