@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/baileysVersi terbaru
npm i @shinryoku/baileys@latest
# atau
yarn add @shinryoku/baileys@latestImport
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
- Gunakan database untuk auth/session di server production.
- Hati-hati dengan
chatModify. - Batasi rate pengiriman pesan.
- 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
notifyduplikat datang denganmessage IDberbeda. - 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.upsertduplikat. - Menambahkan deduplikasi
messages.upsertberbasis identity key pesan dengan cache TTL singkat. - Menormalkan JID private chat (
liddans.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.
