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

@shinryoku/baileys

v0.1.5

Published

WhatsApp Web API Library

Readme


Keunggulan Inti

Dikembangkan untuk melengkapi Baileys dengan fokus pada stabilitas dan pengalaman penggunaan jangka panjang.

  • Core stability patch pada beberapa alur pesan dan metadata.
  • Reconnect flow lebih aman dan efisien.
  • Kompatibel dengan pola penggunaan Baileys yang umum.
  • Banner startup bisa dikustomisasi.

Install

Versi stabil

npm i @shinryoku/baileys

Versi terbaru

npm i @shinryoku/baileys@latest
# atau
yarn add @shinryoku/baileys@latest

Import

const { default: makeWASocket } = require('@shinryoku/baileys')
import makeWASocket from '@shinryoku/baileys'

Quick Start

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

async function connectToWhatsApp() {
  const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')

  const sock = makeWASocket({
    auth: state,
    printQRInTerminal: true,
    browser: ['Marin Kitagawa Bot', 'Chrome', '1.0.0']
  })

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

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

      if (shouldReconnect) connectToWhatsApp()
    } else if (connection === 'open') {
      console.log('Connected to WhatsApp')
    }
  })

  sock.ev.on('messages.upsert', async ({ messages }) => {
    for (const m of messages) {
      if (!m.message) continue
      await sock.sendMessage(m.key.remoteJid, { text: 'Halo! Bot aktif.' })
    }
  })

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

connectToWhatsApp()

Dokumentasi Lengkap

Metode Koneksi

1. Koneksi via QR Code

const { default: makeWASocket, Browsers } = require('@shinryoku/baileys')

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

2. Koneksi via Pairing Code

const { default: makeWASocket } = require('@shinryoku/baileys')

const sock = makeWASocket({ printQRInTerminal: false })

if (!sock.authState.creds.registered) {
  const number = '628xxxxxxxxxx'
  const code = await sock.requestPairingCode(number)
  console.log('Kode Pairing:', code)
}

3. Full History Sync

const { default: makeWASocket, Browsers } = require('@shinryoku/baileys')

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

Konfigurasi Penting

Caching metadata grup

const { default: makeWASocket } = require('@shinryoku/baileys')
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)
})

Data store (memori/file)

const { default: makeWASocket, makeInMemoryStore } = require('@shinryoku/baileys')

const store = makeInMemoryStore({})
store.readFromFile('./marin_store.json')
setInterval(() => {
  store.writeToFile('./marin_store.json')
}, 10_000)

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

Panduan Pengiriman Pesan

Pesan teks, reply, mention

await sock.sendMessage(jid, { text: 'halo dunia' })
await sock.sendMessage(jid, { text: 'halo dunia' }, { quoted: message })
await sock.sendMessage(jid, {
  text: '@62857xxxxxxxxx hai',
  mentions: ['[email protected]'],
})

Forward

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

Lokasi

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

Kontak vCard

const vcard =
  'BEGIN:VCARD\n' +
  'VERSION:3.0\n' +
  'FN:Marin Kitagawa\n' +
  'ORG:Waifu Club;\n' +
  'TEL;type=CELL;type=VOICE;waid=62857xxxxxxxxx:+62 857-xxxx-xxxx\n' +
  'END:VCARD'

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

Reaksi dan pin

await sock.sendMessage(jid, {
  react: { text: '❤️', key: message.key },
})

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

Polling

await sock.sendMessage(jid, {
  poll: {
    name: 'Siapa Waifu Terbaik?',
    values: ['Marin Kitagawa', 'Rem', 'Mikasa'],
    selectableCount: 1,
  },
})

Panduan Media

Kirim gambar

await sock.sendMessage(jid, {
  image: { url: './Media/gambar.png' },
  caption: 'Ini gambar keren',
})

Kirim video/GIF

await sock.sendMessage(jid, {
  video: { url: './Media/video.mp4' },
  caption: 'Nonton yuk',
  gifPlayback: false,
})

await sock.sendMessage(jid, {
  video: fs.readFileSync('Media/gif.mp4'),
  caption: 'GIF kocak',
  gifPlayback: true,
})

Kirim audio

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

View once

await sock.sendMessage(jid, {
  image: { url: './Media/rahasia.jpg' },
  viewOnce: true,
  caption: 'Jangan disebar ya!',
})

Link preview

await sock.sendMessage(jid, {
  text: 'Kunjungi https://npmjs.com/package/@shinryoku/baileys',
})

Manipulasi Pesan

Hapus pesan

const msg = await sock.sendMessage(jid, { text: 'pesan yang akan dihapus' })
await sock.sendMessage(jid, { delete: msg.key })

Edit pesan

await sock.sendMessage(jid, {
  text: 'teks yang sudah diperbarui v2.0',
  edit: msg.key,
})

Manipulasi Media

Download media

const { downloadMediaMessage, getContentType } = require('@shinryoku/baileys')
const fs = require('fs')

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

  const messageType = getContentType(m.message)
  if (messageType === 'imageMessage') {
    const stream = await downloadMediaMessage(
      m,
      'stream',
      {},
      { reuploadRequest: sock.updateMediaMessage },
    )

    const writeStream = fs.createWriteStream('./downloaded_image.jpeg')
    stream.pipe(writeStream)
  }
})

Upload ulang media

await sock.updateMediaMessage(msg)

Manajemen Panggilan

Tolak panggilan otomatis

sock.ev.on('call', async ({ from, id }) => {
  await sock.rejectCall(id, from)
  console.log(`Panggilan dari ${from} ditolak.`)
})

Status dan Kehadiran

Tandai pesan dibaca

await sock.readMessages([key])

Update presence

await sock.sendPresenceUpdate('composing', jid)
await sock.sendPresenceUpdate('available', jid)

Ubah Obrolan (chatModify)

Hati-hati, salah konfigurasi bisa menyebabkan logout di beberapa perangkat.

Arsipkan/buka arsip

await sock.chatModify({ archive: true, lastMessages: [lastMsg] }, jid)
await sock.chatModify({ archive: false, lastMessages: [lastMsg] }, jid)

Bisukan/buka bisukan

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

Tandai dibaca/tidak dibaca

await sock.chatModify({ markRead: false, lastMessages: [lastMsg] }, jid)

Hapus chat untuk diri sendiri

await sock.chatModify(
  {
    delete: true,
    lastMessages: [{ key: lastMsg.key, messageTimestamp: lastMsg.messageTimestamp }],
  },
  jid,
)

Pin/unpin chat

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

Star pesan

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

Ephemeral message

await sock.sendMessage(jid, { disappearingMessagesInChat: 86400 })
await sock.sendMessage(jid, { text: 'Rahasia' }, { ephemeralExpiration: 86400 })
await sock.sendMessage(jid, { disappearingMessagesInChat: false })

Query Pengguna dan Profil

Cek nomor terdaftar

const [result] = await sock.onWhatsApp('[email protected]')
if (result.exists) console.log('Nomor terdaftar!')

Status dan foto profil

const status = await sock.fetchStatus(jid)
const ppUrl = await sock.profilePictureUrl(jid)
const ppHD = await sock.profilePictureUrl(jid, 'image')
const biz = await sock.getBusinessProfile(jid)

Update profil sendiri

await sock.updateProfileName('Nama Baru Bot')
await sock.updateProfileStatus('Sedang menggunakan @shinryoku/baileys')
await sock.updateProfilePicture('[email protected]', { url: './new.jpg' })
await sock.removeProfilePicture('[email protected]')

Manajemen Grup

Pastikan bot adalah admin grup.

Buat grup

const group = await sock.groupCreate('Grup Marin', ['[email protected]', '[email protected]'])
console.log('Grup ID:', group.gid)

Update member

await sock.groupParticipantsUpdate(
  jid,
  ['[email protected]'],
  'add',
)

Update info grup

await sock.groupUpdateSubject(jid, 'Nama Baru')
await sock.groupUpdateDescription(jid, 'Deskripsi baru')
await sock.groupSettingUpdate(jid, 'announcement')
await sock.groupSettingUpdate(jid, 'not_announcement')

Kode undangan

const code = await sock.groupInviteCode(jid)
await sock.groupRevokeInvite(jid)
await sock.groupAcceptInvite('CODEINVITE')
await sock.groupAcceptInviteV4(jid, groupInviteMessage)

Metadata dan join request

const meta = await sock.groupMetadata(jid)
const allGroups = await sock.groupFetchAllParticipating()
const requests = await sock.groupRequestParticipantsList(jid)
await sock.groupRequestParticipantsUpdate(jid, ['[email protected]'], 'approve')

Fitur grup lain

await sock.groupToggleEphemeral(jid, 86400)
await sock.groupMemberAddMode(jid, 'admin_add')
await sock.groupMemberAddMode(jid, 'all_member_add')

Privasi dan Block

await sock.updateBlockStatus(jid, 'block')
await sock.updateBlockStatus(jid, 'unblock')

const settings = await sock.fetchPrivacySettings(true)
await sock.updateLastSeenPrivacy('all')
await sock.updateOnlinePrivacy('all')
await sock.updateProfilePicturePrivacy('contacts')
await sock.updateStatusPrivacy('contacts')
await sock.updateReadReceiptsPrivacy('none')
await sock.updateGroupsAddPrivacy('contacts')

Broadcast dan Status

await sock.sendMessage('status@broadcast', {
  image: { url: './story.jpg' },
  caption: 'Halo status!',
  statusJidList: ['[email protected]'],
  broadcast: true,
})

Tips dan Praktik Terbaik

  1. Gunakan database untuk auth/session di server production.
  2. Hati-hati dengan chatModify.
  3. Batasi rate pengiriman pesan.
  4. Pairing code umumnya lebih praktis untuk deployment.

Changelog

0.1.5 - 2026-02-15

  • Perbaikan untuk kasus bot lama idle lalu kembali dipakai: pesan private yang replay lewat jalur berbeda (append/notify) kini terdeteksi sebagai duplikat.
  • Deduplikasi fingerprint private message diperkuat dengan deteksi replay lintas jalur dan replay timestamp berdekatan.
  • Mengurangi kasus response dobel setelah delay saat bot kembali aktif.

0.1.4 - 2026-02-14

  • Perbaikan lanjutan duplikasi response di private chat saat event notify duplikat datang dengan message ID berbeda.
  • Menambahkan deduplikasi berbasis fingerprint payload untuk pesan private masuk (notify) termasuk text, button/list/template/interactive response, serta caption media.
  • Mencegah command diproses dua kali akibat duplikasi delivery PN/LID yang sebelumnya masih bisa memicu kirim button/media dobel.

0.1.3 - 2026-02-14

  • Perbaikan respon bot ganda di chat pribadi yang terjadi karena event messages.upsert duplikat.
  • Menambahkan deduplikasi messages.upsert berbasis identity key pesan dengan cache TTL singkat.
  • Menormalkan JID private chat (lid dan s.whatsapp.net) pada dedupe key agar satu pesan tidak diproses dua kali.

Dukungan

Project ini gratis dan open-source. Dukungan kamu berarti untuk pengembangan fitur berikutnya.

  • Saweria: https://saweria.co/shinryoku
  • GitHub: https://github.com/johannes2803

Disclaimer

Project ini tidak berafiliasi dengan WhatsApp Inc. atau Meta Platforms, Inc. Gunakan dengan bijak, jangan untuk spam atau aktivitas ilegal.


Lisensi

Distributed under GPL-3.0. Lihat LICENSE.