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

@kaels/casileys

v0.4.0

Published

Modify Baileys For Bot WhatsApp Changli-MD

Readme

🌸 @kaels/casileys

Logo


🙏 A Note & Apology

[!IMPORTANT] Saya ingin menyampaikan permohonan maaf yang tulus kepada @itsliaaa selaku penulis fork [@itsliaaa/baileys**, yang menjadi dasar awal dari package ini.

Pada awalnya, @kaels/casileys dibuat berdasarkan fork tersebut tanpa memberikan atribusi yang layak — hal itu tidak benar dan saya mengakuinya.

Terima kasih banyak kepada @itsliaaa atas kerja kerasnya dalam membangun dan memelihara fork yang luar biasa ini. Kontribusinya sangat berarti bagi komunitas WhatsApp bot.

Ke depannya, @kaels/casileys akan dikembangkan secara mandiri sebagai proyek independen dengan modifikasi, perbaikan, dan arah yang berbeda — bukan lagi sekadar re-upload. Semua perubahan akan didokumentasikan secara transparan.


✨ Highlights

Package ini dirancang untuk penggunaan produksi dengan fokus pada kejelasan dan keamanan:

  • 🚫 Tanpa obfuscation — mudah dibaca dan diaudit.
  • 🔧 Dikembangkan secara aktif dengan modifikasi dan penyesuaian tersendiri.

[!NOTE] Proyek ini tidak dimaksudkan untuk menggantikan upstream Baileys maupun fork @itsliaaa/baileys.


📋 Table of Contents


📥 Installation

Via package.json:

"dependencies": {
   "@kaels/casileys": "latest"
}

Via terminal:

npm i @kaels/casileys@latest

🧩 Import

// ESM
import { makeWASocket } from '@kaels/casileys'

// CJS
const { makeWASocket } = require('@kaels/casileys')

🌐 Connect to WhatsApp (Quick Step)

import { makeWASocket, delay, DisconnectReason, useMultiFileAuthState } from '@kaels/casileys'
import { Boom } from '@hapi/boom'
import pino from 'pino'

const myPhoneNumber = '6288888888888'

const connectToWhatsApp = async () => {
   const { state, saveCreds } = await useMultiFileAuthState('session')

   const sock = makeWASocket({
      logger: pino({ level: 'silent' }),
      auth: state
   })

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

   sock.ev.on('connection.update', async (update) => {
      const { connection, lastDisconnect } = update

      if (connection === 'connecting' && !sock.authState.creds.registered) {
         await delay(1500)
         const code = await sock.requestPairingCode(myPhoneNumber)
         console.log('🔗 Pairing code:', code)
      }

      if (connection === 'close') {
         const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut
         if (shouldReconnect) connectToWhatsApp()
      }

      if (connection === 'open') {
         console.log('✅ Connected to WhatsApp')
      }
   })

   sock.ev.on('messages.upsert', async ({ messages }) => {
      for (const message of messages) {
         if (!message.message) continue
         await sock.sendMessage(message.key.remoteJid, { text: '👋🏻 Hello world' })
      }
   })
}

connectToWhatsApp()

🔐 Auth State

[!NOTE] Bisa gunakan useSingleFileAuthState sebagai alternatif useMultiFileAuthState. useSingleFileAuthState sudah memiliki mekanisme caching internal, sehingga tidak perlu wrap state.keys dengan makeCacheableSignalKeyStore.


🗄️ Implementing Data Store

[!CAUTION] Sangat disarankan membangun data store sendiri — menyimpan seluruh history chat di memory bisa menyebabkan RAM usage yang tinggi.

import { makeWASocket, makeInMemoryStore, delay, DisconnectReason, useMultiFileAuthState } from '@kaels/casileys'
import { Boom } from '@hapi/boom'
import pino from 'pino'

const storePath = './store.json'

const connectToWhatsApp = async () => {
   const { state, saveCreds } = await useMultiFileAuthState('session')

   const sock = makeWASocket({ logger: pino({ level: 'silent' }), auth: state })

   const store = makeInMemoryStore({ logger: pino({ level: 'silent' }), socket: sock })
   store.bind(sock.ev)

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

   // Baca store dari file
   store.readFromFile(storePath)

   // Simpan store setiap 3 menit
   setInterval(() => store.writeToFile(storePath), 180_000)
}

connectToWhatsApp()

🪪 WhatsApp IDs Explain

| Format | Keterangan | |---|---| | [email protected] | User biasa | | 628xxx@lid | User dengan Local Identifier | | [email protected] | Grup | | 11111111111@bot | Meta AI | | status@broadcast | Stories | | [timestamp]@broadcast | Broadcast list |


✉️ Sending Messages

[!NOTE] jid bisa diambil dari message.key.remoteJid.

🔠 Text

// Teks biasa
sock.sendMessage(jid, { text: '👋🏻 Hello' }, { quoted: message })

// Dengan link preview
sock.sendMessage(jid, {
   text: 'https://www.npmjs.com/package/@kaels/casileys 👆🏻 Check it out!',
   linkPreview: {
      'matched-text': 'https://www.npmjs.com/package/@kaels/casileys',
      title: '🌸 @kaels/casileys',
      description: 'WhatsApp Web API',
      previewType: 0,
      jpegThumbnail: fs.readFileSync('./path/to/image.jpg')
   }
})

🔔 Mention

// Mention spesifik
sock.sendMessage(jid, {
   text: '👋🏻 Hello @628123456789',
   mentions: ['[email protected]']
}, { quoted: message })

// Mention semua member grup
sock.sendMessage(jid, {
   text: '👋🏻 Hello @all',
   mentionAll: true
}, { quoted: message })

😁 Reaction

sock.sendMessage(jid, {
   react: { key: message.key, text: '✨' }
})

📌 Pin Message

sock.sendMessage(jid, {
   pin: message.key,
   time: 86400, // 86400 (1d) | 604800 (7d) | 2592000 (30d)
   type: 1      // 2 untuk unpin
})

➡️ Forward Message

sock.sendMessage(jid, { forward: message, force: true })

👤 Contact

const vcard = 'BEGIN:VCARD\nVERSION:3.0\nFN:Kaelz\nTEL;type=CELL;waid=628123456789:+62 812 3456 789\nEND:VCARD'

sock.sendMessage(jid, {
   contacts: { displayName: 'Kaelz', contacts: [{ vcard }] }
}, { quoted: message })

📍 Location

sock.sendMessage(jid, {
   location: { degreesLatitude: -6.2, degreesLongitude: 106.8, name: '📍 Jakarta' }
}, { quoted: message })

🗓️ Event

sock.sendMessage(jid, {
   event: {
      name: '🎶 Meet & Mingle',
      description: 'Gathering seru bareng komunitas!',
      call: 'audio',
      startDate: new Date(Date.now() + 3_600_000),
      endDate: new Date(Date.now() + 28_800_000),
      location: { name: 'Jakarta', degreesLatitude: -6.2, degreesLongitude: 106.8 }
   }
}, { quoted: message })

📊 Poll

// Poll biasa
sock.sendMessage(jid, {
   poll: {
      name: '🔥 Pilih yang terbaik!',
      values: ['Option A', 'Option B'],
      selectableCount: 1
   }
}, { quoted: message })

💭 Button Response

// Plain button reply
sock.sendMessage(jid, {
   type: 'plain',
   buttonReply: { id: '#Menu', displayText: '✨ Menu' }
}, { quoted: message })

// Interactive flow reply
sock.sendMessage(jid, {
   flowReply: {
      format: 0,
      text: '💭 Response',
      name: 'menu_options',
      paramsJson: JSON.stringify({ id: '#Menu', description: 'Menu Utama' })
   }
}, { quoted: message })

// List reply
sock.sendMessage(jid, {
   listReply: { title: '📄 See More', description: '✨ Menu', id: '#Menu' }
}, { quoted: message })

✨ Rich Response

sock.sendMessage(jid, {
   disclaimerText: 'Contoh Rich Response',
   richResponse: [
      { text: 'Contoh penggunaan:' },
      { language: 'javascript', code: [{ highlightType: 0, codeContent: 'console.log("Hello!")' }] },
      { text: 'Mudah, kan?' }
   ]
})

[!TIP] Import tokenizeCode untuk syntax highlighting otomatis:

import { tokenizeCode } from '@kaels/casileys'

🧾 Message with Code Block

sock.sendMessage(jid, {
   disclaimerText: 'Code Block',
   headerText: '## Contoh Kode',
   contentText: '---',
   code: 'console.log("Hello, World!")',
   language: 'javascript',
   footerText: 'Simpel kan?'
})

🌏 Message with Inline Entities (Links)

sock.sendMessage(jid, {
   disclaimerText: 'Link List',
   headerText: '## Useful Links',
   contentText: '---',
   links: [
      { text: '1. npm', title: 'Package Registry', url: 'https://npmjs.com' },
      { text: '2. GitHub', title: 'Source Code', url: 'https://github.com' }
   ],
   footerText: '---'
})

📋 Message with Table

sock.sendMessage(jid, {
   disclaimerText: 'Tabel Perbandingan',
   headerText: '## Node.js vs Bun vs Deno',
   contentText: '---',
   title: 'Runtime Comparison',
   table: [
      ['', 'Node.js', 'Bun', 'Deno'],
      ['Engine', 'V8', 'JavaScriptCore', 'V8'],
      ['Performance', '4/5', '5/5', '4/5']
   ],
   footerText: 'Pilih yang sesuai kebutuhan!'
})

📁 Sending Media Messages

[!NOTE] Media bisa dikirim sebagai Buffer, { stream: Readable }, atau { url: string } (path lokal / URL).

🖼️ Image

sock.sendMessage(jid, {
   image: { url: './path/to/image.jpg' },
   caption: '🔥 Keren!'
}, { quoted: message })

🎥 Video

sock.sendMessage(jid, {
   video: { url: './path/to/video.mp4' },
   gifPlayback: false, // true untuk GIF
   ptv: false,         // true untuk PTV
   caption: '🎬 Video keren!'
}, { quoted: message })

📃 Sticker

sock.sendMessage(jid, {
   sticker: { url: './path/to/sticker.webp' }
}, { quoted: message })

💽 Audio

sock.sendMessage(jid, {
   audio: { url: './path/to/audio.mp3' },
   ptt: false // true untuk Voice Note
}, { quoted: message })

🗂️ Document

sock.sendMessage(jid, {
   document: { url: './path/to/file.pdf' },
   mimetype: 'application/pdf',
   caption: '📄 Dokumen'
}, { quoted: message })

🖼️ Album (Image & Video)

sock.sendMessage(jid, {
   album: [
      { image: { url: './img1.jpg' }, caption: 'Foto 1' },
      { video: { url: './vid1.mp4' }, caption: 'Video 1' },
      { image: { url: './img2.jpg' }, caption: 'Foto 2' }
   ]
}, { quoted: message })

📦 Sticker Pack

[!IMPORTANT] Jika sharp atau @napi-rs/image tidak terinstall, cover dan stickers harus sudah dalam format WebP.

sock.sendMessage(jid, {
   cover: { url: './cover.webp' },
   stickers: [
      { data: { url: './sticker1.webp' } },
      { data: { url: './sticker2.webp' } }
   ],
   name: '📦 Sticker Pack Keren',
   publisher: 'Kaelz',
   description: '@kaels/casileys'
}, { quoted: message })

👉🏻 Sending Interactive Messages

🔘 Buttons

// Button teks biasa
sock.sendMessage(jid, {
   text: '👆🏻 Pilih salah satu!',
   footer: '@kaels/casileys',
   buttons: [{ text: '👋🏻 Halo', id: '#Halo' }]
}, { quoted: message })

// Button dengan media & native flow
sock.sendMessage(jid, {
   image: { url: './path/to/image.jpg' },
   caption: '👆🏻 Button + List!',
   footer: '@kaels/casileys',
   buttons: [{
      text: '📋 Pilih',
      sections: [{
         title: '✨ Section 1',
         rows: [{ title: '🏷️ Opsi A', description: '', id: '#OpsiA' }]
      }]
   }]
}, { quoted: message })

📋 List

[!NOTE] Hanya berfungsi di private chat (@s.whatsapp.net).

sock.sendMessage(jid, {
   text: '📋 Pilih menu!',
   footer: '@kaels/casileys',
   buttonText: '📋 Buka Menu',
   title: '👋🏻 Menu Bot',
   sections: [{
      title: '🚀 Kategori 1',
      rows: [{ title: '✨ Fitur A', description: 'Deskripsi singkat', rowId: '#FiturA' }]
   }]
}, { quoted: message })

🗄️ Interactive (Native Flow)

// Native flow dengan berbagai tipe button
sock.sendMessage(jid, {
   image: { url: './path/to/image.jpg' },
   caption: '🗄️ Interactive Menu!',
   footer: '@kaels/casileys',
   optionText: '👉🏻 Pilih Opsi',   // optional, wrap semua jadi satu list
   optionTitle: '📄 Opsi Tersedia', // optional
   nativeFlow: [
      { text: '👋🏻 Greeting', id: '#Greeting', icon: 'review' },
      { text: '📞 Telepon', call: '628123456789' },
      { text: '📋 Copy', copy: '@kaels/casileys' },
      { text: '🌐 Buka Web', url: 'https://www.npmjs.com/package/@kaels/casileys', useWebview: true },
      {
         text: '📋 Pilih dari List',
         sections: [{
            title: '✨ Pilihan',
            rows: [{ title: '🏷️ Opsi 1', description: '', id: '#Opsi1' }]
         }],
         icon: 'default'
      }
   ]
}, { quoted: message })

// Carousel
sock.sendMessage(jid, {
   text: '🎠 Carousel!',
   footer: '@kaels/casileys',
   cards: [{
      image: { url: './img1.jpg' },
      caption: '🖼️ Slide 1',
      footer: '📸 Caption',
      nativeFlow: [{ text: '🌐 Detail', url: 'https://npmjs.com', useWebview: true }]
   }, {
      image: { url: './img2.jpg' },
      caption: '🖼️ Slide 2',
      footer: '📸 Caption',
      nativeFlow: [{ text: '👍 Pilih', id: '#Pilih2' }]
   }]
}, { quoted: message })

// Native Flow dengan audio footer
sock.sendMessage(jid, {
   text: '🎵 Dengarkan dulu!',
   audioFooter: { url: './audio.mp3' },
   nativeFlow: [
      { text: '👍🏻 Lanjut', id: '#Next', icon: 'review' },
      { text: '👎🏻 Skip', id: '#Skip', icon: 'default' }
   ]
}, { quoted: message })

🫙 Hydrated Template

sock.sendMessage(jid, {
   title: '👋🏻 Halo!',
   image: { url: './path/to/image.jpg' },
   caption: '🫙 Template Message',
   footer: '@kaels/casileys',
   templateButtons: [
      { text: '👉🏻 Klik Sini', id: '#Klik' },
      { text: '🌐 Website', url: 'https://www.npmjs.com/package/@kaels/casileys' },
      { text: '📞 Hubungi', call: '628123456789' }
   ]
}, { quoted: message })

💳 Sending Payment Messages

// Invite payment
sock.sendMessage(jid, { paymentInviteServiceType: 3 }) // 1, 2, atau 3

// Order
sock.sendMessage(jid, {
   orderText: '🛍️ Pesanan Kamu',
   thumbnail: fs.readFileSync('./thumbnail.jpg')
}, { quoted: message })

// Request payment
sock.sendMessage(jid, {
   text: '💳 Minta Pembayaran',
   requestPaymentFrom: '[email protected]'
})

👁️ Other Message Options

| Flag | Keterangan | |---|---| | ai: true | Tambah ikon AI (private chat only) | | ephemeral: true | Wrap ke ephemeralMessage | | viewOnce: true | View once (V1) | | viewOnceV2: true | View once (V2) | | spoiler: true | Wrap ke spoilerMessage | | groupStatus: true | Group status (grup only) | | isLottie: true | Lottie sticker | | mentionAll: true | Mention semua member grup | | interactiveAsTemplate: true | Wrap interactive ke template | | raw: true | Kirim struktur proto manual |

// Contoh: view once + spoiler
sock.sendMessage(jid, {
   image: { url: './image.jpg' },
   caption: '👁️ Lihat sekali aja!',
   viewOnceV2: true
}, { quoted: message })

// External Ad Reply
sock.sendMessage(jid, {
   text: '📰 Info Penting!',
   externalAdReply: {
      title: '📝 Tahukah kamu?',
      body: 'Fakta menarik hari ini',
      thumbnail: fs.readFileSync('./thumbnail.jpg'),
      largeThumbnail: false,
      url: 'https://www.npmjs.com/package/@kaels/casileys'
   }
}, { quoted: message })

♻️ Modify Messages

// Hapus pesan
sock.sendMessage(jid, { delete: message.key })

// Edit teks
sock.sendMessage(jid, { text: '✏️ Teks yang sudah diedit', edit: message.key })

// Edit caption media
sock.sendMessage(jid, { caption: '✏️ Caption baru', edit: message.key })

🧰 Additional Contents

🏷️ Find User ID (JID | PN / LID)

[!NOTE] ID harus berupa angka saja (tanpa +, (), atau -) dan menyertakan kode negara.

const ids = await sock.findUserId('[email protected]')
console.log(ids)
// Output: { phoneNumber: '[email protected]', lid: '43411111111111@lid' }

🔑 Request Custom Pairing Code

const code = await sock.requestPairingCode('6281111111111', 'KAELZBASE')
console.log('🔗 Pairing code:', code)

🖼️ Image Processing

[!NOTE] Otomatis menggunakan library yang tersedia: sharp, @napi-rs/image, atau jimp.

import { getImageProcessingLibrary } from '@kaels/casileys'

const lib = await getImageProcessingLibrary()

// Jika sharp tersedia
if (lib.sharp?.default) {
   const output = await lib.sharp.default('./image.jpg')
      .resize(512)
      .jpeg({ quality: 80 })
      .toBuffer()
}

👥 Group Management

// Buat grup
const group = await sock.groupCreate('Nama Grup', ['[email protected]'])

// Metadata
const metadata = await sock.groupMetadata(jid)

// Kelola member
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'add')     // tambah
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'remove')  // kick
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'promote') // jadikan admin
sock.groupParticipantsUpdate(jid, ['[email protected]'], 'demote')  // copot admin

// Setting grup
sock.groupSettingUpdate(jid, 'announcement')  // hanya admin bisa chat
sock.groupSettingUpdate(jid, 'not_announcement') // semua bisa chat
sock.groupSettingUpdate(jid, 'locked')        // hanya admin edit info
sock.groupSettingUpdate(jid, 'unlocked')      // semua bisa edit info
sock.groupToggleEphemeral(jid, 86400)         // aktifkan pesan sementara
sock.groupJoinApprovalMode(jid, 'on')         // aktifkan persetujuan member

// Invite
const inviteCode = await sock.groupInviteCode(jid)
sock.groupRevokeInvite(jid)
sock.groupAcceptInvite(inviteCode)
sock.groupLeave(jid)

👥 Community Management

const community = await sock.communityCreate('Nama Komunitas', 'Deskripsi')
const group = await sock.communityCreateGroup('Announcements', ['[email protected]'], communityJid)

sock.communityLinkGroup(groupJid, communityJid)
sock.communityUnlinkGroup(groupJid, communityJid)
sock.communityLeave(jid)

👤 Profile Management

sock.updateProfilePicture(jid, { url: './photo.jpg' })
sock.removeProfilePicture(jid)
sock.updateProfileName('Nama Baru')
sock.updateProfileStatus('Status baru')
sock.sendPresenceUpdate('available', jid)
sock.readMessages([message.key])
sock.updateBlockStatus(jid, 'block')    // blokir
sock.updateBlockStatus(jid, 'unblock')  // buka blokir

🔐 Privacy Management

sock.updateLastSeenPrivacy('all')          // semua bisa lihat
sock.updateLastSeenPrivacy('contacts')     // kontak saja
sock.updateLastSeenPrivacy('nobody')       // tidak ada
sock.updateOnlinePrivacy('all')
sock.updateProfilePicturePrivacy('contacts')
sock.updateReadReceiptsPrivacy('all')
sock.updateReadReceiptsPrivacy('none')
sock.updateCallPrivacy('everyone')
sock.updateDefaultDisappearingMode(86400)

📣 Newsletter Management

sock.newsletterCreate('Nama Channel', 'Deskripsi')
sock.newsletterFollow('jid@newsletter')
sock.newsletterUnfollow('jid@newsletter')
sock.newsletterMute('jid@newsletter')
sock.newsletterUnmute('jid@newsletter')
sock.newsletterUpdateName('jid@newsletter', 'Nama Baru')
sock.newsletterUpdateDescription('jid@newsletter', 'Deskripsi baru')
sock.newsletterReactMessage('jid@newsletter', '100', '💛')
sock.newsletterDelete('jid@newsletter')

📡 Events

sock.ev.on('connection.update', (update) => {})
sock.ev.on('creds.update', (update) => {})
sock.ev.on('messages.upsert', (update) => {})
sock.ev.on('messages.update', (update) => {})
sock.ev.on('messages.delete', (update) => {})
sock.ev.on('messages.reaction', (update) => {})
sock.ev.on('groups.upsert', (update) => {})
sock.ev.on('groups.update', (update) => {})
sock.ev.on('group-participants.update', (update) => {})
sock.ev.on('contacts.upsert', (update) => {})
sock.ev.on('contacts.update', (update) => {})
sock.ev.on('chats.upsert', (update) => {})
sock.ev.on('chats.update', (update) => {})
sock.ev.on('presence.update', (update) => {})
sock.ev.on('blocklist.set', (update) => {})
sock.ev.on('blocklist.update', (update) => {})
sock.ev.on('call', (update) => {})
sock.ev.on('newsletter.reaction', (update) => {})
sock.ev.on('newsletter.view', (update) => {})
sock.ev.on('settings.update', (update) => {})

📣 Credits

Kredit penuh diberikan kepada para maintainer dan kontributor asli Baileys:

Terima kasih khusus kepada:

[!CAUTION] ⚠️ Modifikasi, penghapusan, atau kesalahan representasi kredit ini dilarang keras. Setiap redistribusi atau fork harus mempertahankan bagian ini dalam bentuk aslinya.