Enhanced WhiskeySockets Interactive Buttons with full TypeScript support
This repository provides enhanced WhatsApp interactive buttons functionality for WhiskeySockets (Baileys fork) with comprehensive TypeScript type definitions. The functionality is packaged and published as the npm package baileys-helper which reproduces the binary node structure the official client emits so buttons render correctly for both private & group chats.
By default, WhiskeySockets cannot send interactive buttons while itsukichan can. The root cause is that WhiskeySockets lacks the required binary node wrappers (biz, interactive, native_flow) that WhatsApp expects for interactive messages.
The enhanced functionality provided by the baileys-helper package provides the missing functionality by:
- Detecting button messages using the same logic as itsukichan
- Converting WhiskeySockets'
interactiveButtonsformat to the proper protobuf structure - Adding missing binary nodes (
biz,interactive,native_flow,bot) viaadditionalNodes - Automatically handling private vs group chat requirements
- Full TypeScript support with comprehensive type definitions
- ✅ No modifications to WhiskeySockets or itsukichan folders
- ✅ Full TypeScript Support with 100% type coverage
- ✅ Template functionality removed as requested
- ✅ Automatic binary node injection for button messages
- ✅ Private chat support (adds
botnode withbiz_bot: '1') - ✅ Group chat support (adds only
biznode) - ✅ Backward compatibility (regular messages pass through unchanged)
- ✅ Comprehensive Error Handling with detailed validation
- ✅ 17+ Button Types including quick replies, CTAs, location, payments
- ✅ Dynamic Baileys Compatibility (supports multiple Baileys versions)
npm install baileys-helper @types/node
# or
yarn add baileys-helper @types/nodenpm install baileys-helper
# or
yarn add baileys-helperimport { sendButtons, Button } from 'baileys-helper';
// Define your buttons with full type safety
const buttons: Button[] = [
{
id: 'accept',
title: 'Accept',
type: 'quick_reply'
},
{
id: 'website',
title: 'Visit Website',
type: 'cta_url',
url: 'https://example.com'
}
];
await sendButtons(
socket,
'1234567890@s.whatsapp.net',
buttons,
'Do you accept the terms and conditions?',
'Please choose an option below'
);const { sendButtons } = require('baileys-helper');
const buttons = [
{ id: 'accept', title: 'Accept', type: 'quick_reply' },
{ id: 'website', title: 'Visit Website', type: 'cta_url', url: 'https://example.com' }
];
await sendButtons(
socket,
'1234567890@s.whatsapp.net',
buttons,
'Do you accept the terms and conditions?',
'Please choose an option below'
);This package supports 17+ different WhatsApp interactive button types:
- Quick Reply - Simple response buttons
- CTA URL - Buttons that open websites
- CTA Copy - Buttons that copy text to clipboard
- CTA Call - Buttons that initiate phone calls
- Single Select - In-button picker lists
- Send Location - Location sharing buttons
- Open WebView - Embedded web view buttons
- Review & Pay - Payment processing buttons
- Payment Info - Payment status buttons
- CTA Catalog - Product catalog buttons
- MPM - Merchant payment buttons
- WA Payment Transaction - Transaction details
- Reminder - Schedule reminder buttons
- Cancel Reminder - Remove scheduled reminders
- Address Message - Address selection buttons
- Galaxy Message - Specialized message types
- Automated Greeting - Auto-catalog greetings
High-level convenience function for quick-reply buttons.
import { sendButtons, Button } from 'baileys-helper';
const buttons: Button[] = [
{ id: 'opt1', title: 'Option 1', type: 'quick_reply' },
{ id: 'opt2', title: 'Option 2', type: 'quick_reply' }
];
await sendButtons(
socket,
'1234567890@s.whatsapp.net',
buttons,
'Choose an option:'
);Simplified wrapper for quick-reply buttons with full configuration control.
import {
sendInteractiveButtonsBasic,
Button,
InteractiveMessageConfig
} from 'baileys-helper';
const params = {
socket,
jid: '1234567890@s.whatsapp.net',
config: {
body: 'Choose your preferred option',
footer: 'Select one below',
headerType: 1,
headerText: 'Menu Selection',
headerMedia: {
mediaType: 'image',
mediaUrl: 'https://example.com/menu.jpg',
mediaCaption: 'Choose wisely!'
}
},
buttons: [
{
id: 'menu1',
title: 'Option 1',
type: 'quick_reply'
},
{
id: 'menu2',
title: 'Option 2',
type: 'quick_reply'
}
]
};
await sendInteractiveButtonsBasic(params);Low-level power function for full control over button configuration.
import {
sendInteractiveMessage,
Button,
InteractiveMessageConfig
} from 'baileys-helper';
const buttons: Button[] = [
{
id: 'visit',
title: 'Visit Website',
type: 'cta_url',
url: 'https://example.com'
},
{
id: 'call',
title: 'Call Support',
type: 'cta_call',
phoneNumber: '+1234567890'
},
{
id: 'copy_id',
title: 'Copy Order ID',
type: 'cta_copy',
copyText: 'ORDER-12345'
}
];
await sendInteractiveMessage({
socket,
jid: '1234567890@s.whatsapp.net',
config: {
body: 'Need help with your order?',
footer: 'Our support team is here to help',
headerText: 'Customer Support',
headerType: 1
},
buttons,
format: 'current' // 'legacy', 'current', or 'custom'
});All functions include comprehensive validation with detailed error reporting:
import { validateInteractiveMessage, InteractiveValidationError } from 'baileys-helper';
try {
const validation = validateInteractiveMessage(config, buttons);
if (!validation.isValid) {
console.error('Validation errors:', validation.errors);
console.error('Warnings:', validation.warnings);
}
} catch (error) {
if (error instanceof InteractiveValidationError) {
console.log('Detailed error format:');
console.log(error.formatDetailed());
// Or get JSON format for API responses
console.log('JSON format:', error.toJSON());
}
}The validation system catches:
- Missing or invalid button IDs
- Empty or invalid body text
- Type-specific button validation (URLs, phone numbers, etc.)
- Button count limits
- Missing required fields for specific button types
import {
Button, // Union type for all button types
WASocket, // Baileys socket interface
InteractiveMessageConfig, // Message configuration
ValidationResult // Validation result interface
} from 'baileys-helper';// Individual button interfaces are available
import {
QuickReplyButton,
CTAUrlButton,
CTACopyButton,
CTACallButton,
SendLocationButton,
SingleSelectButton
// ... and more
} from 'baileys-helper';Normalize buttons from multiple legacy formats into the current native_flow format.
import { buildInteractiveButtons } from 'baileys-helper';
const rawButtons = [
{ id: '1', title: 'Button 1' }, // Legacy format
{ id: '2', title: 'Button 2', url: 'https://example.com' },
{
buttonId: '3',
buttonText: { displayText: 'Button 3' } // Old Baileys format
}
];
const normalizedButtons = buildInteractiveButtons(rawButtons);Detect the button type based on button properties.
import { getButtonType } from 'baileys-helper';
const button = { id: '1', title: 'Test', url: 'https://example.com' };
const type = getButtonType(button); // Returns: 'cta_url'Validate button ID format.
import { isValidButtonId } from 'baileys-helper';
console.log(isValidButtonId('valid_id')); // true
console.log(isValidButtonId('')); // false
console.log(isValidButtonId(null)); // falseIf you're already using baileys-helper in JavaScript, TypeScript will automatically infer types:
// JavaScript
const { sendButtons } = require('baileys-helper');
// TypeScript will infer: sendButtons(socket: WASocket, jid: string, buttons: Button[], body: string, footer?: string) => Promise<any>-
Install TypeScript dependencies:
npm install --save-dev typescript @types/node
-
Rename files to
.ts: Your existing JavaScript code will work immediately with type inference. -
Add explicit types gradually:
import { sendButtons, Button } from 'baileys-helper'; const buttons: Button[] = [ { id: '1', title: 'Button 1', type: 'quick_reply' } ];
For complete API documentation, see docs/typescript-api-documentation.md.
For comprehensive examples, see:
examples/typescript-examples.ts- TypeScript examplesexamples/test-all-types.ts- Type system validation tests
git clone https://github.com/your-org/baileys-helper-typescript.git
cd baileys-helper-typescript
npm install
npm run buildnpm run build- Build JavaScript and TypeScript declarationsnpm run build:js- Build JavaScript files onlynpm run build:types- Build TypeScript declarations onlynpm run build:watch- Watch mode for developmentnpm run type-check- Check TypeScript types without buildingnpm run clean- Clean build artifacts
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the ISC License -
- Original BaileysHelper by mehebub648
- WhiskeySockets/Baileys community for the foundation
- TypeScript community for excellent type system patterns