
Selamat Datang di Baileys PontaLabs
Extended from @whiskeysockets/baileys — packed with exclusive patches, AI-rich messages, and advanced WhatsApp features.
Table of Contents
- Why This Fork?
- Features
- Installation
- Quick Start
- Documentation
- API Reference
- Contributing
- License
- Disclaimer
Why This Fork?
This fork builds on top of the original Baileys library with targeted, production-ready patches designed for modern bot development and AI integrations.
| # | Patch | Description |
|---|---|---|
| 01 | Rich Text | AI-styled markdown text via richText |
| 02 | Rich Code Block | Syntax-highlighted code blocks with language support |
| 03 | Rich Table | Structured data tables with headers and rows |
| 04 | Rich Images | Image grid / carousel for AI-generated visuals |
| 05 | Rich Video | Video embeds rendered as AI animated media |
| 06 | Rich Suggestions | Follow-up prompt pills (like native AI chat) |
| 07 | Rich LaTeX | Math formula rendering via GenAILatexItem |
| 08 | Rich Product | Product cards with horizontal scroll carousel |
| 09 | Rich Post | Post cards with author metadata and carousel |
| 10 | Rich Reels | Reels carousel with engagement stats |
| 11 | Rich Sources | Search result source list with favicons |
| 12 | Rich Tip & Footer | Metadata blocks for branding and disclaimers |
| 13 | Rich Mixed | Combine all rich types freely in items arrays |
| 14 | Rich Response | Full array mode with inline citations |
| 15 | Custom Message ID | All outgoing IDs prefixed with PONTASOCKETS |
| 16 | LID Bug Fixes | Full resolution for participant, sender, and admin LID issues |
| 17 | makeInMemoryStore Fix | Stable session handling and store behavior |
| 18 | Newsletter Support | Full channel/newsletter create, follow, react, and admin tools |
| 19 | AI Logo Message | Bot avatar support in message context |
| 20 | Logger Buffer Clear | Prevents memory buildup from log buffers |
| 21 | LID → JID Conversion | Auto-converts LID mentions, sender, and member LIDs to JID |
| 22 | Location + Buttons | Location messages with native list menu and extra buttons |
| 23 | Group Status | Styled group status (text/media) with audience control |
| 24 | Order Status | Interactive order tracking cards with native order_status flow |
Features
✔ Multi-Device Support ✔ End-to-End Encryption
✔ Real-Time Messaging ✔ Session Persistence
✔ Rich AI Bot Messages ✔ Newsletter Management
✔ Group & Channel Management ✔ Inline Citations & LaTeX
✔ Poll, Album, Carousel ✔ LID → JID Auto-Conversion
✔ Product / Post / Reels Cards ✔ Math Formula Rendering
✔ Location + Button Messages ✔ Group Status & Order Status
Installation
# npm
npm install @pontalabs/baileys
# yarn
yarn add @pontalabs/baileys
Quick Start
import makeWASocket, { useMultiFileAuthState } from '@pontalabs/baileys'
async function start() {
const { state, saveCreds } = await useMultiFileAuthState('./sessions')
const sock = makeWASocket({
printQRInTerminal: true,
auth: state
})
sock.ev.on('creds.update', saveCreds)
sock.ev.on('messages.upsert', ({ messages }) => {
console.log('New message:', messages[0].message)
})
}
start()
Documentation
Connecting
QR Code
const sock = makeWASocket({
printQRInTerminal: true,
auth: state
})
Pairing Code
const sock = makeWASocket({
printQRInTerminal: false,
auth: state
})
if (!sock.authState.creds.registered) {
const number = '62xxxx'
const code = await sock.requestPairingCode(number)
// Or custom 8-digit code:
const customCode = await sock.requestPairingCode(number, 'PONTASOCKETS')
console.log(code)
}
Events
Basic Message Listener
sock.ev.on('messages.upsert', ({ messages }) => {
const msg = messages[0]
console.log('From:', msg.key.remoteJid)
console.log('Content:', msg.message)
})
Decrypt Poll Votes
sock.ev.on('messages.update', (m) => {
if (m.pollUpdates) {
console.log('Poll vote received:', m.pollUpdates)
}
})
Sending Messages
sock.sendMessage(jid, content, options?)
// jid — Recipient JID (user or group)
// content — Message payload object
// options — Optional: { quoted, ephemeral, ... }
Standard Messages
Text
await sock.sendMessage(jid, { text: 'Hello!' })
await sock.sendMessage(jid, { text: 'Reply!' }, { quoted: message })
Image
// From file
await sock.sendMessage(jid, {
image: fs.readFileSync('image.jpg'),
caption: 'Caption here'
})
// From URL
await sock.sendMessage(jid, {
image: { url: 'https://example.com/image.jpg' },
caption: 'Downloaded image'
})
Video
await sock.sendMessage(jid, {
video: fs.readFileSync('video.mp4'),
caption: 'Funny clip!'
})
// View Once
await sock.sendMessage(jid, {
video: fs.readFileSync('secret.mp4'),
viewOnce: true
})
Audio / PTT
// Regular audio
await sock.sendMessage(jid, { audio: fs.readFileSync('audio.mp3'), ptt: false })
// Push-to-talk
await sock.sendMessage(jid, {
audio: fs.readFileSync('voice.ogg'),
ptt: true,
waveform: [0, 1, 0, 1, 0]
})
Contact
const vcard = [
'BEGIN:VCARD', 'VERSION:3.0', 'FN:Jeff Singh', 'ORG:Ashoka Uni',
'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890',
'END:VCARD'
].join('\n')
await sock.sendMessage(jid, {
contacts: { displayName: 'Jeff Singh', contacts: [{ vcard }] }
})
Location
await sock.sendMessage(jid, {
location: {
degreesLatitude: 37.422,
degreesLongitude: -122.084,
name: 'Google HQ'
}
})
React
await sock.sendMessage(jid, { react: { text: '👍', key: message.key } })
// Remove reaction
await sock.sendMessage(jid, { react: { text: '', key: message.key } })
Poll
await sock.sendMessage(jid, {
poll: {
name: 'Favorite color?',
values: ['Red', 'Blue', 'Green'],
selectableCount: 1
}
})
Album
await sock.sendAlbumMessage(jid, [
{ image: { url: 'https://example.com/1.jpg' }, caption: 'First' },
{ video: { url: 'https://example.com/clip.mp4' }, caption: 'Second' }
], { quoted: message, delay: 3000 })
Interactive (Native Flow & Carousel)
// Native Flow
await sock.sendMessage(jid, {
text: 'Choose an option:',
title: 'Title',
footer: '© PONTASOCKETS Baileys',
interactive: [{
name: 'quick_reply',
buttonParamsJson: JSON.stringify({ display_text: 'Quick Reply', id: '123' })
}]
})
// Carousel
await sock.sendMessage(jid, {
text: 'Check out our collection!',
title: 'Catalog',
footer: '© PONTASOCKETS Baileys',
cards: [{
image: { url: 'https://example.com/image.jpg' },
title: 'Product Name',
body: 'Product description',
footer: '© PONTASOCKETS',
buttons: [{
name: 'quick_reply',
buttonParamsJson: JSON.stringify({ display_text: 'Select', id: '1' })
}]
}]
})
Pin & Keep
// Pin — 24h = 86400 · 7d = 604800 · 30d = 2592000
await sock.sendMessage(jid, { pin: { type: 1, time: 86400, key: message.key } })
// Keep
await sock.sendMessage(jid, { keep: { key: message.key, type: 1 } })
Location + Buttons
Location message with native list menu (
single_select) and extra buttons — all in onebuttonsMessage.
Location + List Menu
await sock.sendMessage(jid, {
buttonLocation: {
latitude: -6.2088,
longitude: 106.8456,
name: 'Kantor Pusat PontaCT',
address: 'Jl. Sudirman No. 1, Jakarta Pusat',
text: 'Temukan kami di sini:',
footer: '© PontaCT',
thumbnail: 'https://example.com/map-preview.jpg',
listButtonText: 'Pilih Layanan',
listSectionTitle: 'Layanan Tersedia',
listMenu: [
{ title: 'Customer Service', description: 'Lantai 1, Senin–Jumat 08.00–17.00', id: 'cs' },
{ title: 'Kasir & Pembayaran', description: 'Lantai 2, buka setiap hari', id: 'kasir' },
{ title: 'Gudang & Pengiriman', description: 'Gedung B, pintu belakang', id: 'gudang' }
]
}
})
Location + Extra Buttons
await sock.sendMessage(jid, {
buttonLocation: {
latitude: -6.2088,
longitude: 106.8456,
name: 'Toko PontaCT',
address: 'Jl. Kebon Sirih No. 10, Jakarta',
text: 'Kunjungi toko kami!',
footer: '© PontaCT',
thumbnail: 'https://example.com/store.jpg',
extraButtons: [
{ id: 'call', displayText: '📞 Hubungi Kami' },
{ id: 'whatsapp', displayText: '💬 WhatsApp' },
{ id: 'maps', displayText: '🗺️ Buka di Maps' }
]
}
})
Location + List Menu + Extra Buttons
await sock.sendMessage(jid, {
buttonLocation: {
latitude: -6.2088,
longitude: 106.8456,
name: 'Plaza PontaCT',
address: 'Jl. MH Thamrin No. 5, Jakarta',
text: 'Selamat datang di pusat layanan kami.',
footer: 'Buka setiap hari 09.00–21.00',
thumbnail: 'https://example.com/plaza.jpg',
listButtonText: 'Pilih Tujuan',
listSectionTitle: 'Area Tersedia',
listMenu: [
{ title: 'Food Court', description: 'Lt. 1 — lebih dari 30 tenant', id: 'food' },
{ title: 'Cinema', description: 'Lt. 4 — 8 studio', id: 'cinema' },
{ title: 'Customer Care', description: 'Lt. 2 — sebelah eskalator', id: 'care' }
],
extraButtons: [
{ id: 'navigate', displayText: '🧭 Navigasi' },
{ id: 'promo', displayText: '🎁 Promo Hari Ini' }
]
}
})
Fields Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
latitude |
number |
— | 0 |
Latitude coordinate |
longitude |
number |
— | 0 |
Longitude coordinate |
name |
string |
— | 'Location' |
Place name |
address |
string |
— | '' |
Text address |
text |
string |
— | '' |
Message body text |
footer |
string |
— | '' |
Footer text |
thumbnail |
Buffer / URL / path |
— | Map preview image | |
listButtonText |
string |
— | 'Pilih Menu' |
List button label |
listSectionTitle |
string |
— | 'Pilihan' |
List section title |
listMenu |
array |
— | — | Menu rows |
extraButtons |
array |
— | — | Extra buttons |
Order Status
Interactive order tracking card using native
order_statusflow button.
Basic Order Status
await sock.sendMessage(jid, {
orderStatus: {
image: 'https://example.com/order-banner.jpg',
title: 'Status Pesanan',
text: 'Pesanan kamu sedang diproses oleh penjual.',
referenceId: 'ORD-20250629-001',
status: 'PROCESSING',
currency: 'IDR'
}
})
Full Order Status with Total & Tax
await sock.sendMessage(jid, {
orderStatus: {
image: 'https://example.com/order.jpg',
title: 'Update Pesanan #ORD-2025-001',
text: 'Pesananmu sedang dalam perjalanan! 🚚',
footer: 'Estimasi tiba: 2–3 hari kerja',
referenceId: 'ORD-2025-001',
status: 'SHIPPED',
subtotalValue: 15000000,
subtotalOffset: 100,
taxValue: 1500000,
taxOffset: 100,
currency: 'IDR'
}
})
Local Image File
const fs = require('fs')
await sock.sendMessage(jid, {
orderStatus: {
image: fs.readFileSync('./assets/order-confirm.jpg'),
title: 'Pesanan Dikonfirmasi ✅',
text: 'Terima kasih telah berbelanja!',
referenceId: 'ORD-LOCAL-001',
status: 'PROCESSING',
currency: 'IDR'
}
})
Fields Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
image |
Buffer / URL / path |
— | Header card image | |
title |
string |
— | 'Order Status' |
Header title |
text |
string |
— | 'Silakan cek status pesanan Anda.' |
Body text |
footer |
string |
— | 'Powered by PontaCT' |
Footer text |
referenceId |
string |
— | 'PT-001' |
Order reference ID |
status |
string |
— | 'PROCESSING' |
Order status |
subtotalValue |
number |
— | 0 |
Subtotal value (in offset units) |
subtotalOffset |
number |
— | 100 |
Value divider |
taxValue |
number |
— | 0 |
Tax value |
taxOffset |
number |
— | 100 |
Tax divider |
currency |
string |
— | 'IDR' |
Currency code |
Status values:
PROCESSING·SHIPPED·DELIVERED·CANCELLED·REFUNDED
Rich Messages
All rich messages are sent via standard
sendMessageand rendered as AI bot messages in WhatsApp. Use the appropriate key instead oftext,image,video, etc.
Quick jump: Rich Text · Code · Table · Images · Video · Suggestions · LaTeX · Product · Post · Reels · Sources · Tip & Footer · Mixed · Response
Rich Text
AI bot-styled markdown text rendered in
richResponseMessage.
Simple Text
await sock.sendMessage(jid, { richText: 'Halo! Ini pesan dari bot.' }, { quoted: message })
Markdown (bold, italic, inline code)
await sock.sendMessage(jid, {
richText: '*Hasil eksekusi:*\nStatus: `success`\nWaktu: _120ms_'
}, { quoted: message })
Multiple Paragraphs (Array)
await sock.sendMessage(jid, {
richText: ['Baris pertama.', 'Baris kedua.', 'Baris ketiga.']
}, { quoted: message })
Rich Code Block
Syntax-highlighted code. Use
codefor single block,codesfor multiple.
Single Block
await sock.sendMessage(jid, {
code: 'console.log("Hello World")',
language: 'javascript'
}, { quoted: message })
Multiple Blocks
await sock.sendMessage(jid, {
codes: [
{ code: 'SELECT * FROM users WHERE id = 1;', language: 'sql' },
{ code: '{ "id": 1, "name": "Ponta", "role": "admin" }', language: 'json' }
]
}, { quoted: message })
Supported Languages
| Language | Key |
|---|---|
| JavaScript | javascript · js |
| TypeScript | typescript · ts |
| Python | python · py |
| Bash / Shell | bash · sh · zsh |
| Go | go · golang |
| Rust | rust · rs |
| C / C++ | c · h · cpp · c++ |
| C# | csharp · cs |
| CSS / HTML | css · html |
| PowerShell / CMD | powershell · ps1 · cmd · bat |
| SQL / JSON | sql · json |
Rich Table
Structured table with
title,headers, androws.
Simple Table
await sock.sendMessage(jid, {
table: {
title: 'Daftar User',
headers: ['Name', 'Role', 'Status'],
rows: [
['Ponta', 'Admin', 'Active'],
['Yue', 'Member', 'Idle'],
['Frieren', 'Guest', 'Offline']
]
}
}, { quoted: message })
Table without Title
await sock.sendMessage(jid, {
table: {
headers: ['Command', 'Description'],
rows: [
['.ping', 'Cek latency bot'],
['.info', 'Info bot'],
['.help', 'List semua command']
]
}
}, { quoted: message })
Data Only (no header)
await sock.sendMessage(jid, {
table: {
rows: [
['RAM', '512 MB'],
['CPU', '4 Core'],
['Uptime', '99.9%']
]
}
}, { quoted: message })
Rich Images
AI image grid. Single URL = single image, multiple URLs = carousel.
Single Image
await sock.sendMessage(jid, { richImages: 'https://example.com/photo.jpg' }, { quoted: message })
Multiple Images (Grid)
await sock.sendMessage(jid, {
richImages: [
'https://example.com/photo1.jpg',
'https://example.com/photo2.jpg',
'https://example.com/photo3.jpg'
]
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Hasil foto hari ini:' },
{ images: ['https://example.com/1.jpg', 'https://example.com/2.jpg'] }
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Lihat gambarnya:' },
{ images: 'https://example.com/banner.jpg' }
]
}, { quoted: message })
Rich Video
Video embed as AI animated media (
GenAIImaginePrimitivewithimagine_type: ANIMATE).
Shorthand URL
await sock.sendMessage(jid, { richVideo: 'https://example.com/clip.mp4' }, { quoted: message })
Full Options
await sock.sendMessage(jid, {
richVideo: {
url: 'https://example.com/clip.mp4',
mimeType: 'video/mp4', // default: 'video/mp4'
duration: 15, // seconds, default: 10
fallbackText: 'Preview video' // default: '[ VIDEO - PontaCT ]'
}
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Cek videonya:' },
{ videoUrl: 'https://example.com/clip.mp4', duration: 20 }
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Tutorial:' },
{ video: { url: 'https://example.com/tutorial.mp4', duration: 30 } }
]
}, { quoted: message })
Rich Suggestions
Follow-up prompt pills — like native AI chat buttons.
Shorthand
await sock.sendMessage(jid, {
richSuggestions: ['Coba lagi', 'Lihat detail', 'Batalkan']
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Mau lanjut ke mana?' },
{ suggestions: ['Halaman utama', 'Bantuan', 'Hubungi admin'] }
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Hasil pencarian ditemukan.' },
{ suggestions: ['Tampilkan semua', 'Filter ulang', 'Export'] }
]
}, { quoted: message })
Rich LaTeX
Math formula rendering as
GenAILatexIteminline entity.urlpoints to a rendered formula image (PNG/JPG from external LaTeX renderer).
Shorthand URL
await sock.sendMessage(jid, {
richLatex: 'https://latex.codecogs.com/png.latex?E%3Dmc%5E2'
}, { quoted: message })
Full Options
await sock.sendMessage(jid, {
richLatex: {
url: 'https://latex.codecogs.com/png.latex?E%3Dmc%5E2',
text: 'E = mc²', // label & fallback
width: 120, // default: 100
height: 60, // default: 100
font_height: 83.33, // default: 83.33
padding: 15 // default: 15
}
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Rumus energi kinetik:' },
{
latexUrl: 'https://latex.codecogs.com/png.latex?E_k%3D%5Cfrac%7B1%7D%7B2%7Dmv%5E2',
latexText: 'Ek = ½mv²',
latexWidth: 150,
latexHeight: 60
}
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Solusi integral:' },
{ latex: { url: 'https://latex.codecogs.com/png.latex?%5Cint%20x%5E2%20dx', text: '∫x² dx = x³/3 + C' } }
]
}, { quoted: message })
Rich Product
Product card(s) as
GenAIProductItemCardPrimitive. Object = single card, Array = horizontal scroll carousel.
Single Product
await sock.sendMessage(jid, {
richProduct: {
title: 'Sepatu Adidas Samba',
price_display_string: 'Rp 1.200.000',
description: 'Sepatu casual ikonik, tersedia berbagai ukuran.',
retailer_id: 'adidas_store',
thumbnail: { url: 'https://example.com/adidas.jpg', mime_type: 'image/jpeg', width: 300, height: 300 }
}
}, { quoted: message })
Product Carousel
await sock.sendMessage(jid, {
richProduct: [
{
title: 'Sepatu A',
price_display_string: 'Rp 500.000',
thumbnail: { url: 'https://example.com/a.jpg', mime_type: 'image/jpeg', width: 300, height: 300 }
},
{
title: 'Sepatu B',
price_display_string: 'Rp 750.000',
thumbnail: { url: 'https://example.com/b.jpg', mime_type: 'image/jpeg', width: 300, height: 300 }
}
]
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Rekomendasi produk hari ini:' },
{ product: { title: 'Produk X', price_display_string: 'Rp 99.000' } }
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Pilih produkmu:' },
{ product: [{ title: 'A' }, { title: 'B' }] }
]
}, { quoted: message })
Rich Post
Post card(s) as
GenAIPostPrimitive. Object = single post, Array = carousel.
Single Post
await sock.sendMessage(jid, {
richPost: {
title: 'Caption post ini',
author_display_name: '@pontalabs',
author_profile_image: 'https://example.com/avatar.jpg',
media_url: 'https://example.com/post.jpg',
timestamp: Math.floor(Date.now() / 1000)
}
}, { quoted: message })
Post Carousel
await sock.sendMessage(jid, {
richPost: [
{ title: 'Post 1', author_display_name: '@user1', media_url: 'https://example.com/1.jpg' },
{ title: 'Post 2', author_display_name: '@user2', media_url: 'https://example.com/2.jpg' }
]
}, { quoted: message })
Rich Reels
Reels carousel as
GenAIReelPrimitivewithcontentItemsMetadata. Auto-injectsrichResponseSourcesMetadatawithprovider: 'PontaCT'.
Single Reel
await sock.sendMessage(jid, {
richReels: {
title: '@creator_name',
profileIconUrl: 'https://example.com/avatar.jpg',
thumbnailUrl: 'https://example.com/thumb.jpg',
videoUrl: 'https://example.com/reel.mp4',
reels_title: 'Judul reel ini',
likes_count: 12400,
shares_count: 340,
view_count: 89000,
reel_source: 'IG',
is_verified: true
}
}, { quoted: message })
Reels Carousel
await sock.sendMessage(jid, {
richReels: [
{
title: '@creator1',
profileIconUrl: 'https://example.com/av1.jpg',
thumbnailUrl: 'https://example.com/th1.jpg',
videoUrl: 'https://example.com/r1.mp4',
likes_count: 5000,
reel_source: 'IG'
},
{
title: '@creator2',
profileIconUrl: 'https://example.com/av2.jpg',
thumbnailUrl: 'https://example.com/th2.jpg',
videoUrl: 'https://example.com/r2.mp4',
likes_count: 8200,
reel_source: 'TT'
}
]
}, { quoted: message })
Fields Reference
| Field | Type | Default | Description |
|---|---|---|---|
title |
string |
— | Username / creator name |
profileIconUrl |
string |
— | Avatar URL |
thumbnailUrl |
string |
— | Thumbnail cover URL |
videoUrl |
string |
— | Video source URL |
reels_title |
string |
'' |
Reel title |
likes_count |
number |
0 |
Like count |
shares_count |
number |
0 |
Share count |
view_count |
number |
0 |
View count |
reel_source |
string |
'IG' |
Source platform |
is_verified |
boolean |
false |
Verified badge |
Rich Sources
Search result source list as
GenAISearchResultPrimitive. Accepts full objects or shorthand[faviconUrl, sourceUrl, displayName].
Shorthand Array
await sock.sendMessage(jid, {
richSources: [
['https://wikipedia.org/favicon.ico', 'https://wikipedia.org/wiki/Node.js', 'Wikipedia'],
['https://nodejs.org/favicon.ico', 'https://nodejs.org/en/docs', 'Node.js Docs'],
['https://github.com/favicon.ico', 'https://github.com/nodejs/node', 'GitHub']
]
}, { quoted: message })
Full Object
await sock.sendMessage(jid, {
richSources: [
{
source_type: 'THIRD_PARTY',
source_display_name: 'Wikipedia',
source_subtitle: 'wikipedia.org',
source_url: 'https://wikipedia.org/wiki/Node.js',
favicon: { url: 'https://wikipedia.org/favicon.ico', mime_type: 'image/jpeg', width: 16, height: 16 }
}
]
}, { quoted: message })
Mixed Format
await sock.sendMessage(jid, {
richSources: [
['https://wikipedia.org/fav.ico', 'https://wikipedia.org', 'Wikipedia'],
{ source_type: 'THIRD_PARTY', source_display_name: 'Docs', source_url: 'https://docs.example.com' }
]
}, { quoted: message })
Rich Tip & Footer
richTip— small metadata text above/center of message.richFooter— metadata text below message (disclaimer / branding).
Rich Tip
await sock.sendMessage(jid, {
richTip: 'Dihasilkan oleh AI · pontalabs v0.3.4'
}, { quoted: message })
Rich Footer
await sock.sendMessage(jid, {
richFooter: '© 2025 PontaCT · Data bersumber dari layanan publik'
}, { quoted: message })
Inside items / richResponse
// items
await sock.sendMessage(jid, {
items: [
{ text: 'Hasil pencarian:' },
{ sources: [['https://fav.ico', 'https://example.com', 'Example']] },
{ tip: 'AI-generated content' },
{ footer: '© PontaCT Baileys' }
]
}, { quoted: message })
// richResponse
await sock.sendMessage(jid, {
richResponse: [
{ text: 'Summary di sini.' },
{ footer: '© PontaCT · pontalabs' }
]
}, { quoted: message })
Rich Mixed — items
Combine all rich types in any order. Array order = display order.
Valid keys in items:
| Key | Type |
|---|---|
{ text } |
Rich text |
{ code, language } |
Code block |
{ table } |
Table |
{ images } |
Image grid |
{ videoUrl, mimeType?, duration? } |
Video embed |
{ suggestions } |
Suggestion pills |
{ latexUrl, latexText?, latexWidth?, latexHeight? } |
LaTeX formula |
{ product } |
Product card(s) |
{ post } |
Post card(s) |
{ reels } |
Reels carousel |
{ sources } |
Search sources |
{ tip } |
Tip metadata |
{ footer } |
Footer metadata |
Text + Code + Table
await sock.sendMessage(jid, {
items: [
{ text: 'Query yang dijalankan:' },
{ code: 'SELECT id, name, score FROM users ORDER BY score DESC LIMIT 3', language: 'sql' },
{ text: 'Hasil:' },
{
table: {
headers: ['id', 'name', 'score'],
rows: [
['1', 'Ponta', '98'],
['2', 'Yue', '87'],
['3', 'Frieren', '75']
]
}
}
]
}, { quoted: message })
Text + Images + Video + Suggestions
await sock.sendMessage(jid, {
items: [
{ text: '*Konten hari ini*' },
{ images: ['https://example.com/1.jpg', 'https://example.com/2.jpg'] },
{ videoUrl: 'https://example.com/preview.mp4', duration: 15 },
{ suggestions: ['Lihat selengkapnya', 'Bagikan', 'Simpan'] }
]
}, { quoted: message })
Full Mixed (all types)
await sock.sendMessage(jid, {
items: [
{ text: '*Laporan Harian Bot*' },
{ table: { headers: ['Metric', 'Value'], rows: [['Uptime', '99.9%'], ['Messages', '1.2K']] } },
{ code: 'SELECT COUNT(*) FROM messages WHERE date = CURDATE()', language: 'sql' },
{ text: 'Formula uptime:' },
{
latexUrl: 'https://latex.codecogs.com/png.latex?U%3D%5Cfrac%7Bt_u%7D%7Bt_t%7D%5Ctimes100',
latexText: 'U = (tu/tt) × 100'
},
{ sources: [['https://example.com/fav.ico', 'https://example.com', 'Dashboard']] },
{ suggestions: ['Refresh', 'Export PDF'] },
{ footer: 'Auto-generated · PontaCT' }
]
}, { quoted: message })
Rich Response — richResponse
Full array mode supporting all types including inline citations via
inlineEntities.
Valid keys in richResponse:
| Key | Type |
|---|---|
{ text, inlineEntities? } |
Text + optional citation/hyperlink |
{ code, language } |
Code block |
{ table, title? } |
Table |
{ images } |
Image grid |
{ video } |
Video embed |
{ suggestions } |
Suggestion pills |
{ latex } |
LaTeX formula |
{ product } |
Product card(s) |
{ post } |
Post card(s) |
{ reels } |
Reels carousel |
{ sources } |
Search sources |
{ tip } |
Tip metadata |
{ footer } |
Footer metadata |
Inline Citation
await sock.sendMessage(jid, {
richResponse: [
{
text: 'Node.js {{SS_0}}¹{{/SS_0}} adalah runtime JavaScript. Dibuat oleh Ryan Dahl {{SS_1}}²{{/SS_1}} pada 2009.',
inlineEntities: [
{
key: 'SS_0',
metadata: {
reference_id: 1,
reference_url: 'https://nodejs.org',
reference_title: 'Node.js Official',
reference_display_name: 'nodejs.org',
sources: [{
source_type: 'THIRD_PARTY',
source_display_name: 'nodejs.org',
source_subtitle: 'nodejs.org',
source_url: 'https://nodejs.org'
}],
__typename: 'GenAISearchCitationItem'
}
},
{
key: 'SS_1',
metadata: {
reference_id: 2,
reference_url: 'https://wikipedia.org/wiki/Ryan_Dahl',
reference_title: 'Ryan Dahl - Wikipedia',
reference_display_name: 'Wikipedia',
sources: [{
source_type: 'THIRD_PARTY',
source_display_name: 'Wikipedia',
source_subtitle: 'wikipedia.org',
source_url: 'https://wikipedia.org/wiki/Ryan_Dahl'
}],
__typename: 'GenAISearchCitationItem'
}
}
]
}
]
}, { quoted: message })
Full Response — all types at once
await sock.sendMessage(jid, {
richResponse: [
{ text: '*Hasil Pencarian:* Node.js {{SS_0}}¹{{/SS_0}}', inlineEntities: [/* ... */] },
{ images: ['https://example.com/nodejs.png'] },
{ text: 'Cara install:' },
{ code: 'npm install node', language: 'bash' },
{ table: { headers: ['Version', 'LTS', 'Release'], rows: [['22.x', 'Yes', '2024'], ['21.x', 'No', '2023']] } },
{ sources: [['https://nodejs.org/fav.ico', 'https://nodejs.org', 'Node.js']] },
{ suggestions: ['Lihat changelog', 'Download', 'Docs'] },
{ footer: 'PontaCT · pontalabs' }
]
}, { quoted: message })
Newsletter
Get Newsletter Metadata
// By invite code
const newsletter = await sock.newsletterMetadata('invite', '0029Vaf0HPMLdQeZsp3XRp2T')
// By JID
const newsletter = await sock.newsletterMetadata('jid', '120363282083849178@newsletter')
Follow / Unfollow / Mute / Unmute
const nlJid = '120363282083849178@newsletter'
await sock.newsletterFollow(nlJid)
await sock.newsletterUnfollow(nlJid)
await sock.newsletterMute(nlJid)
await sock.newsletterUnmute(nlJid)
Create Newsletter
const newsletter = await sock.newsletterCreate(
'Newsletter Name',
'Description here',
{ url: 'https://example.com/image.jpg' }
)
React to Newsletter Post
await sock.newsletterReactMessage(
'120363282083849178@newsletter',
'12', // server message ID
'🦖' // emoji
)
Groups
Create Group
const group = await sock.groupCreate('Group Title', [
'1234567890@s.whatsapp.net',
'0987654321@s.whatsapp.net'
])
console.log('Group JID:', group.id)
Group Settings
const jid = '123456789@g.us'
await sock.groupSettingUpdate(jid, 'announcement') // admin-only messages
await sock.groupSettingUpdate(jid, 'not_announcement') // all members can send
await sock.groupSettingUpdate(jid, 'locked') // admin-only edit info
await sock.groupSettingUpdate(jid, 'unlocked') // all members can edit info
Add / Remove / Promote / Demote
const participants = ['1234567890@s.whatsapp.net']
await sock.groupParticipantsUpdate(jid, participants, 'add')
await sock.groupParticipantsUpdate(jid, participants, 'remove')
await sock.groupParticipantsUpdate(jid, participants, 'promote')
await sock.groupParticipantsUpdate(jid, participants, 'demote')
Invite Link
const code = await sock.groupInviteCode(jid)
console.log('Link: https://chat.whatsapp.com/' + code)
// Revoke & generate new link
const newCode = await sock.groupRevokeInvite(jid)
Group Metadata
const metadata = await sock.groupMetadata(jid)
console.log('Name:', metadata.subject)
console.log('Participants:', metadata.participants.length)
Group Status
Send group status (
groupStatusMessageV2) with audience control and styling.messagecan be astringor a prepared WAMessage object.
// Text Status
await sock.sendMessage(jid, {
groupStatus: {
message: 'Selamat datang di grup PontaCT! 🎉',
audienceType: 0 // 0 = all members
}
})
// Styled Text Status
await sock.sendMessage(jid, {
groupStatus: {
message: 'Bot aktif kembali! ✅',
audienceType: 0,
backgroundArgb: 0xFF1A1A2E,
textArgb: 0xFFFFFFFF,
font: 4
}
})
// Media Status
const { imageMessage } = await prepareWAMessageMedia(
{ image: { url: 'https://example.com/banner.jpg' } },
{ upload: sock.waUploadToServer }
)
await sock.sendMessage(jid, {
groupStatus: { message: { imageMessage }, audienceType: 0 }
})
Fields Reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
message |
string / object |
— | Status content (string or WAMessage) | |
audienceType |
number |
— | 0 |
Target audience (0 = all) |
backgroundArgb |
number |
— | — | Background ARGB color (text only) |
textArgb |
number |
— | — | Text ARGB color (text only) |
font |
number |
— | — | Font style 0–9 (text only) |
Privacy
Profile Picture
await sock.updateProfilePicture(jid, { url: 'https://example.com/image.jpg' })
await sock.removeProfilePicture(jid)
Block / Unblock
await sock.updateBlockStatus(jid, 'block')
await sock.updateBlockStatus(jid, 'unblock')
Privacy Settings
await sock.updateLastSeenPrivacy('all') // 'all' | 'contacts' | 'none'
await sock.updateOnlinePrivacy('all') // 'all' | 'match_last_seen'
await sock.updateProfilePicturePrivacy('all') // 'all' | 'contacts' | 'none'
await sock.updateReadReceiptsPrivacy('all') // 'all' | 'none'
await sock.updateGroupsAddPrivacy('all') // 'all' | 'contacts'
await sock.updateDefaultDisappearingMode(86400) // 0 = disable
Advanced
Debug Logging
const sock = makeWASocket({
logger: { level: 'debug' }, // 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
auth: state
})
Raw WebSocket Events
sock.ws.on('CB:presence', (json) => {
console.log('Presence update:', json)
})
sock.ws.on('CB:edge_routing', (node) => {
console.log('Edge routing:', node)
})
API Reference
| Method | Description |
|---|---|
makeWASocket(options) |
Create a new WhatsApp socket connection |
useMultiFileAuthState(path) |
Multi-file authentication state manager |
sock.sendMessage(jid, content, opts) |
Send any message type |
sock.sendAlbumMessage(jid, contents, opts) |
Send album/carousel of media |
sock.groupCreate(title, participants) |
Create a new group |
sock.groupMetadata(jid) |
Fetch group metadata |
sock.groupSettingUpdate(jid, setting) |
Update group settings |
sock.groupParticipantsUpdate(jid, participants, action) |
Modify group members |
sock.groupInviteCode(jid) |
Get group invite code |
sock.groupRevokeInvite(jid) |
Revoke and regenerate invite |
sock.newsletterMetadata(type, value) |
Fetch newsletter info |
sock.newsletterCreate(name, desc, picture) |
Create a newsletter |
sock.newsletterFollow(jid) |
Follow a newsletter |
sock.newsletterUnfollow(jid) |
Unfollow a newsletter |
sock.newsletterMute(jid) |
Mute a newsletter |
sock.newsletterUnmute(jid) |
Unmute a newsletter |
sock.newsletterReactMessage(jid, id, emoji) |
React to a newsletter post |
sock.updateProfilePicture(jid, content) |
Update profile picture |
sock.removeProfilePicture(jid) |
Remove profile picture |
sock.updateBlockStatus(jid, status) |
Block or unblock a user |
sock.updateLastSeenPrivacy(value) |
Control last seen visibility |
sock.updateOnlinePrivacy(value) |
Control online status visibility |
sock.updateProfilePicturePrivacy(value) |
Control profile picture visibility |
sock.updateReadReceiptsPrivacy(value) |
Control read receipts |
sock.updateGroupsAddPrivacy(value) |
Control who can add you to groups |
sock.updateDefaultDisappearingMode(seconds) |
Set default disappearing messages |
Contact
| Platform | Link |
|---|---|
| Telegram | @pontact |
| Channel | WhatsApp Channel |
| REST API | api.codeteam.web.id |
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature - Commit your changes:
git commit -m "feat: add something awesome" - Push to your branch:
git push origin feat/your-feature - Open a Pull Request
License
This project is licensed for personal and non-commercial use only.
| Personal use and modification allowed | |
| Redistribution with attribution allowed | |
| Commercial use strictly prohibited | |
| Resale or rebranding prohibited |
Disclaimer
This project is not affiliated with WhatsApp or Meta in any way.
Use at your own risk and refer to WhatsApp's Terms of Service for compliance.