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

@aldy11/rekber-bot

v1.3.0

Published

Modifikasi @whiskeysockets/baileys untuk bot rekber (escrow) WhatsApp. Fitur: LID Converter otomatis, rate limiter, auto-reconnect, timeout manager, persistent storage, ESM+CJS.

Readme

🏦 @aldy11/rekber-bot

Modifikasi @whiskeysockets/baileys untuk bot rekening bersama (rekber/escrow) WhatsApp dengan LID Converter otomatis.


✨ Fitur Utama

| Fitur | Keterangan | |---|---| | 🔗 LID Converter | Konversi LID ↔ JID ↔ Phone dari sumber manapun secara otomatis | | 🏦 Rekber Engine | Sistem escrow lengkap dengan status PENDING → DONE | | 🔘 Interactive Msg | Button, List, Carousel, Copy, Call, Location — support WA versi terbaru | | 💾 Database Support | JSON (default), MongoDB, SQLite, MySQL — pluggable adapter | | 🤖 Bot Commands | Command !rekber, !bayar, !terima, dll siap pakai | | 🔄 Auto-patch | LID otomatis diisi dari semua event Baileys | | 🧪 Unit Tested | 45 test semua lulus |


📦 Instalasi

# Clone atau copy folder ini
npm install

Atau jika dipublish ke npm:

npm install @aldy11/rekber-bot

🚀 Quick Start

const { createRekberBot } = require('@aldy11/rekber-bot')

;(async () => {
    const { sock } = await createRekberBot({
        sessionDir:  './auth_info',
        dataDir:     './rekber-data',
        adminPhone:  '628123456789',   // nomor admin/mediator
        prefix:      '!',
        feePercent:  0,               // fee 0% = gratis
    })

    sock.ev.on('connection.update', ({ connection }) => {
        if (connection === 'open') console.log('Bot online!')
    })
})()

Jalankan:

node example/bot.js
# atau
npm start

🔑 Custom Pairing Code

Anda bisa menentukan pairing code sendiri (8 karakter) alih-alih mendapatkan kode random:

const { sock } = await createRekberBot({
    usePairingCode:    true,
    phoneNumber:       '628123456789',
    customPairingCode: 'ABCD1234',    // tepat 8 karakter
})

Atau via .env:

USE_PAIRING_CODE=true
PHONE_NUMBER=628123456789
CUSTOM_PAIRING_CODE=ABCD1234

Catatan: Custom pairing code harus tepat 8 karakter. Jika dikosongkan, Baileys akan generate kode random secara otomatis.


🔗 LID Converter

LID (Linked Device ID) adalah ID baru WhatsApp yang dipakai untuk privasi nomor telepon. Package ini mengkonversi LID secara otomatis dari:

  • Event kontak (contacts.upsert, contacts.update)
  • Pesan masuk (messages.upsert, key.participant, key.participantLid)
  • Update grup (group-participants.update)
  • Manual (register, registerBatch, registerFromContact)

Cara Pakai LidConverter

const { LidConverter } = require('@aldy11/rekber-bot')

const conv = new LidConverter()

// ── Normalisasi input apapun ──────────────────────────────
LidConverter.normalize('081234567890')        // → [email protected]
LidConverter.normalize('lid:123456789')       // → 123456789:0@lid
LidConverter.normalize('[email protected]')         // → [email protected]

// ── Register mapping ──────────────────────────────────────
conv.register('111111:0@lid', '[email protected]')
conv.registerFromContact({ id: '[email protected]', lid: '222:0@lid', name: 'Budi' })
conv.registerBatch(contacts)   // array kontak dari Baileys

// ── Konversi ──────────────────────────────────────────────
conv.lidToJid('111111:0@lid')           // → [email protected]
conv.jidToLid('[email protected]') // → 111111:0@lid
conv.lidToPhone('111111:0@lid')          // → 6281111111111
conv.phoneToLid('6281111111111')         // → 111111:0@lid

// ── Resolve dari input APAPUN ─────────────────────────────
conv.resolveToJid('081111111111')        // → [email protected]
conv.resolveToJid('111111:0@lid')        // → [email protected]
conv.resolveToJid('[email protected]') // → [email protected]

conv.resolveAll('111111:0@lid')
// → { jid, lid, phone, name, isResolved }

Patch Manual ke Socket Baileys

const { makeWASocket, patchBaileysSock } = require('@aldy11/rekber-bot')

const sock = makeWASocket({ ... })
patchBaileysSock(sock, { debug: true })

// Setelah patch, socket punya method tambahan:
sock.resolveJid('081234567890')    // → JID
sock.resolveSender(msg)            // → JID sender (support LID participant)
sock.resolveAll('lid:12345')       // → { jid, lid, phone, name }
sock.lidConverter                  // → instance LidConverter

🏦 Sistem Rekber

Flow Status Transaksi

PENDING → AGREED → PAID → CONFIRMED → DONE
   ↓                            ↓
CANCELLED                  DISPUTED → REFUNDED

Command Bot

Prefix default: ! — bisa diganti di config, atau dikosongkan untuk mode tanpa prefix.

// Dengan prefix (default)
prefix: '!'   // → !rekber, !help, !bayar ...
prefix: '.'   // → .rekber, .help, .bayar ...

// Tanpa prefix
prefix: ''    // → rekber, help, bayar ...

| Command | Keterangan | |---|---| | rekber @seller 500000 Beli item | Buat transaksi rekber baru | | rekber 628xxx 500000 Beli item | Dengan nomor telepon | | rekber lid:12345 500000 Beli item | Dengan LID | | setuju RKB-XXXXX | Setujui transaksi | | bayar RKB-XXXXX bukti-transfer | Konfirmasi pembayaran | | terima RKB-XXXXX | Konfirmasi barang diterima | | selesai RKB-XXXXX | Finalisasi (dana dilepas) | | sengketa RKB-XXXXX alasan | Buka sengketa | | batal RKB-XXXXX alasan | Batalkan transaksi | | cektx RKB-XXXXX | Lihat info transaksi | | txsaya | Daftar transaksi aktif saya | | ceklid lid:12345 | Resolve LID/JID/nomor | | help | Tampilkan bantuan |

Catatan: Pada mode tanpa prefix, bot hanya merespon kata-kata yang dikenali sebagai command. Pesan biasa tidak akan diproses.

Contoh Output Bot

╔══ 🏦 REKBER ══╗
║ ID: `RKB-M5X1A2BC-0001`
║ Status: 💸 PAID
╠═══════════════╣
║ 👤 Buyer  : @628111xxxxxx
║ 🏪 Seller : @628222xxxxxx
╠═══════════════╣
║ 📦 Item   : Akun Mobile Legends
║ 💰 Nominal: Rp 500.000
╠═══════════════╣
║ 🤝 Buyer setuju : ✅
║ 🤝 Seller setuju: ✅
║ 🧾 Bukti: ref-BCA-12345
╚══════════════════╝

💻 RekberManager (Programmatic)

const { RekberManager, LidConverter } = require('@aldy11/rekber-bot')

const conv = new LidConverter()
const mgr  = new RekberManager(conv, {
    feePercent: 1,      // 1% fee
    feeFixed:   2500,   // + Rp 2.500
    adminJid:   '[email protected]',
})

// Buat transaksi - bisa pakai LID, JID, atau nomor telepon
const tx = mgr.create({
    buyer:  'lid:111111',              // LID
    seller: '[email protected]', // JID
    amount: 500000,
    desc:   'Akun Mobile Legends',
})

// Event listener
mgr.on('created',   tx => console.log('Dibuat:', tx.id))
mgr.on('paid',      tx => console.log('Bayar masuk:', tx.id))
mgr.on('completed', tx => console.log('Selesai:', tx.id))

// Flow transaksi
mgr.agree(tx.id, buyerJid)
mgr.agree(tx.id, sellerJid)
mgr.confirmPayment(tx.id, buyerJid, 'bukti-transfer')
mgr.confirmReceived(tx.id, buyerJid)
mgr.complete(tx.id, buyerJid)

// Format output
console.log(mgr.formatTx(tx.id))

💾 Storage (Persistent)

const { RekberStorage } = require('@aldy11/rekber-bot')

const storage = new RekberStorage('./rekber-data')

// Attach ke manager (auto save + restore)
storage.attachToManager(rekberBot.rekber)

// Manual backup
storage.backup()

// Hapus TX lama > 30 hari
storage.cleanup(30)

// Statistik
console.log(await storage.getStats())
// { adapter: 'json', totalTransactions: 42, lidMappings: 150, dataDir: '/path/...' }

🗄️ Database Adapter

Secara default, data disimpan di file JSON lokal. Tapi kamu bisa pakai database lain dengan adapter yang sudah disediakan:

| Adapter | Package | Install | |---|---|---| | JsonAdapter | — (built-in) | Tidak perlu install | | MongoAdapter | mongodb | npm install mongodb | | SqliteAdapter | better-sqlite3 | npm install better-sqlite3 | | MysqlAdapter | mysql2 | npm install mysql2 |

MongoDB

const { createRekberBot, MongoAdapter } = require('@aldy11/rekber-bot')

const storage = new MongoAdapter('mongodb://localhost:27017', 'rekber-bot')

const { sock } = await createRekberBot({
    storage,
    // ... opsi lain
})

SQLite

const { createRekberBot, SqliteAdapter } = require('@aldy11/rekber-bot')

const storage = new SqliteAdapter('./rekber.db')

const { sock } = await createRekberBot({
    storage,
    // ... opsi lain
})

MySQL / MariaDB

const { createRekberBot, MysqlAdapter } = require('@aldy11/rekber-bot')

const storage = new MysqlAdapter({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'rekber_bot'
})

const { sock } = await createRekberBot({
    storage,
    // ... opsi lain
})

Custom Adapter

Kamu bisa buat adapter sendiri dengan meng-extend StorageAdapter:

const { StorageAdapter } = require('@aldy11/rekber-bot')

class RedisAdapter extends StorageAdapter {
    async init()                  { /* koneksi Redis */ }
    async close()                 { /* tutup koneksi */ }
    async loadTransactions()      { /* load dari Redis */ }
    async saveSingleTransaction() { /* save ke Redis */ }
    // ... implementasi method lainnya
}

Method Umum Semua Adapter

// Statistik
console.log(await storage.getStats())

// Cari transaksi
const pending = await storage.findTransactions({ status: 'PENDING' })
const myTx    = await storage.findTransactions({ buyer: '[email protected]' })

// Ambil satu transaksi
const tx = await storage.getTransaction('RKB-XXXXX')

// Cleanup TX lama > 30 hari
await storage.cleanup(30)

// Tutup koneksi (untuk Mongo/MySQL)
await storage.close()

🔘 Interactive Message (Button, List, Carousel, dll)

Fitur buttonsMessage, listMessage, templateMessage lama sudah diblokir di WhatsApp versi terbaru. Package ini menyediakan InteractiveBuilder yang menggunakan format interactiveMessage + nativeFlowMessage yang didukung penuh di semua versi WA saat ini.

Tipe Button yang Didukung

| Tipe | Method | Keterangan | |---|---|---| | Quick Reply | addReplyButton(text, id) | Tombol balasan cepat | | URL / Link | addUrlButton(text, url) | Buka link di browser | | Copy Code | addCopyButton(text, copyCode) | Salin teks ke clipboard | | Call / Telepon | addCallButton(text, phone) | Tombol telepon | | Location Request | addLocationRequest(text) | Minta user kirim lokasi | | Address | addAddressButton(text) | Minta user kirim alamat | | List Menu | addListMenu(title, sections) | Popup menu pilihan | | Custom / Raw | addRawButton(name, params) | Tipe button custom |

Contoh Lengkap

const { InteractiveBuilder } = require('@aldy11/rekber-bot')

// 1. Builder biasa (semua tipe tombol)
const builder = new InteractiveBuilder('Judul', 'Isi pesan', 'Footer')
    .addReplyButton('Ping', '!ping')
    .addUrlButton('Website', 'https://github.com')
    .addCopyButton('Salin Kode', 'PROMO2024')
    .addCallButton('Hubungi Admin', '+6281234567890')
    .addLocationRequest('Kirim Lokasi')
    .addListMenu('Pilih Menu', [
        {
            title: 'Kategori 1',
            rows: [
                { title: 'Item 1', id: 'cmd_1', description: 'Deskripsi' }
            ]
        }
    ])

// Kirim pakai sock.sendInteractive (cara termudah)
await sock.sendInteractive(chatJid, builder)

// Atau manual via relayMessage
const msg = builder.buildForRelay(chatJid)
await sock.relayMessage(chatJid, msg.message, { messageId: msg.key.id })

Static Factory (Shortcut)

// Quick buttons
const b = InteractiveBuilder.buttons('Pilih:', [
    { text: 'Ya', id: 'yes' },
    { text: 'Tidak', id: 'no' }
], { header: 'Konfirmasi' })

// List
const l = InteractiveBuilder.list('Pilih layanan:', 'Lihat Menu', sections)

// URL
const u = InteractiveBuilder.url('Kunjungi website kami', 'Buka', 'https://...')

// Copy
const c = InteractiveBuilder.copy('Kode promo kamu:', 'Salin', 'DISKON50')

Carousel (Kartu Swipe)

const { CarouselBuilder } = require('@aldy11/rekber-bot')

const carousel = new CarouselBuilder()

carousel.createCard('Akun Game', 'Jual beli akun aman', 'Mulai Rp 50k')
    .addReplyButton('Beli', '!rekber')
    .addUrlButton('Katalog', 'https://...')

carousel.createCard('Top Up', 'Diamond & voucher', 'Termurah')
    .addReplyButton('Pesan', '!rekber')
    .addCopyButton('Salin Promo', 'DISKON20')

await sock.sendInteractive(chatJid, carousel)

Menangkap Response dari Button/List

const { InteractiveResponseParser } = require('@aldy11/rekber-bot')

sock.ev.on('messages.upsert', async ({ messages }) => {
    for (const msg of messages) {
        const response = InteractiveResponseParser.parse(msg)
        if (response) {
            console.log(response.type)  // 'button_reply' | 'list_reply' | 'native_flow'
            console.log(response.id)    // ID yang dipilih user
            console.log(response.title) // Teks yang dipilih
        }
    }
})

🧪 Menjalankan Test

npm test
# atau
node test/test.js
Hasil: 45 passed, 0 failed
🎉 Semua test berhasil!

📁 Struktur File

@aldy11/rekber-bot/
├── index.js                    ← Entry point & factory
├── package.json
├── src/
│   ├── lid/
│   │   └── LidConverter.js     ← Konverter LID utama
│   ├── patches/
│   │   └── patchBaileysSock.js ← Inject ke Baileys socket
│   ├── rekber/
│   │   ├── RekberManager.js    ← Engine transaksi rekber
│   │   └── RekberBot.js        ← Handler command WhatsApp
│   └── utils/
│       ├── helpers.js          ← Utility functions
│       └── RekberStorage.js    ← Persistent storage
├── example/
│   └── bot.js                  ← Contoh bot siap pakai
└── test/
    └── test.js                 ← Unit tests (45 test)

📝 Lisensi

MIT — bebas digunakan dan dimodifikasi.