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

ai-md-btns

v2.2.5

Published

WhatsApp Interactive Messages Helper for ai-md-baileys — Buttons, Lists, Carousels, Albums, Polls & more

Readme

ai-md-btns

🚀 The Ultimate WhatsApp Interactive Messages Library for ai-md-baileys

NPM Version NPM Downloads License: MIT Node.js GitHub TypeScript Ready

Send interactive buttons, lists, carousels, polls, albums, code blocks, and 20+ message types with native WhatsApp support — including AI icon support in both group chats & DMs.


✨ Key Features

  • 20+ Message Types - Complete WhatsApp interactive message support
  • 🤖 AI Icon Support - Works in both group chats and direct messages
  • 📸 Auto Media Processing - Handles URLs, buffers, and file paths seamlessly
  • 🎨 Native WhatsApp UI - Uses native nativeFlow for authentic experience
  • 🔄 Smart Universal Sender - One function handles all message types
  • 📦 TypeScript Ready - Full type definitions included
  • Zero Dependencies - Minimal footprint, maximum compatibility

📦 Installation

npm install ai-md-btns ai-md-baileys
# or
yarn add ai-md-btns ai-md-baileys

🚀 Quick Start

Basic Setup

import { makeWASocket } from 'ai-md-baileys';
import { 
  sendButtons, 
  sendCarousel, 
  sendPoll, 
  sendAlbum,
  quickReply,
  urlBtn,
  copyBtn,
  callBtn
} from 'ai-md-btns';

const sock = makeWASocket({ /* your config */ });

Send Quick Reply Buttons

await sendButtons(sock, jid, {
  text: '👋 Choose an option',
  footer: 'Powered by ai-md-btns',
  buttons: [
    { text: '🆘 Help', id: 'help' },
    { text: 'ℹ️ About', id: 'about' },
    { text: '⚙️ Settings', id: 'settings' }
  ]
});

Send Interactive List

await sendList(sock, jid, {
  text: '📂 Select a category',
  title: 'Main Menu',
  buttonText: '📂 Browse',
  sections: [
    {
      title: '🎵 Entertainment',
      rows: [
        { title: 'Music', id: 'music', description: 'Listen to songs' },
        { title: 'Videos', id: 'videos', description: 'Watch content' }
      ]
    },
    {
      title: '🛠️ Utilities',
      rows: [
        { title: 'Download', id: 'download', description: 'Download files' },
        { title: 'Convert', id: 'convert', description: 'Convert media' }
      ]
    }
  ]
});

Send Carousel Cards

await sendCarousel(sock, jid, {
  text: '🏪 Our Products',
  footer: '⬅️ Swipe to see more',
  cards: [
    {
      title: '🔥 Premium Plan',
      caption: 'Unlimited access',
      image: { url: 'https://example.com/premium.jpg' },
      buttons: [quickReply('Buy Now', 'buy_premium')]
    },
    {
      title: '🎵 Music Streaming',
      caption: 'Download songs',
      image: { url: 'https://example.com/music.jpg' },
      buttons: [urlBtn('Listen Now', 'https://spotify.com')]
    },
    {
      title: '💻 Code Editor',
      caption: 'Start coding',
      image: { url: 'https://example.com/code.jpg' },
      buttons: [copyBtn('Copy Code', 'const hello = "world"')]
    }
  ]
});

Send Poll/Vote

await sendPoll(sock, jid, {
  name: '🔥 What\'s your favorite feature?',
  values: ['Carousel Cards', 'List Buttons', 'Native Flow', 'Polls'],
  selectableCount: 1
});

Send Album (Multiple Media)

await sendAlbum(sock, jid, {
  album: [
    { 
      type: 'image', 
      media: 'https://example.com/photo1.jpg', 
      caption: '📸 Beautiful landscape' 
    },
    { 
      type: 'video', 
      media: 'https://example.com/video1.mp4', 
      caption: '🎥 Amazing content' 
    },
    { 
      type: 'image', 
      media: 'https://example.com/photo2.jpg', 
      caption: '📷 Another shot' 
    }
  ]
});

Send Sticker Pack

await sendStickerPack(sock, jid, {
  cover: 'https://example.com/cover.webp',
  stickers: [
    'https://example.com/sticker1.webp',
    'https://example.com/sticker2.webp',
    'https://example.com/sticker3.webp'
  ],
  name: '😂 Funny Stickers',
  publisher: 'Your Bot',
  description: 'Collection of funny stickers'
});

Send Code Block

await sendCodeBlock(sock, jid, {
  headerText: '💻 JavaScript Example',
  contentText: 'Here\'s a simple function',
  code: `function hello() {
  console.log('Hello, World!');
  return 42;
}`,
  language: 'javascript',
  footerText: 'Copy & paste to use'
});

Send Table

await sendTable(sock, jid, {
  headerText: '📊 Sales Report',
  title: 'Q4 2024',
  table: [
    ['Product', 'Units', 'Revenue'],
    ['Widget A', '150', '$1,500'],
    ['Widget B', '200', '$2,000'],
    ['Widget C', '180', '$1,800']
  ],
  footerText: 'End of report'
});

Send Location

await sendLocation(sock, jid, {
  lat: 40.7128,
  lng: -74.0060,
  name: '📍 New York City'
});

Send Contact

await sendContact(sock, jid, {
  displayName: 'John Doe',
  vcard: `BEGIN:VCARD
VERSION:3.0
FN:John Doe
TEL:+1234567890
EMAIL:[email protected]
END:VCARD`
});

🔒 Spoiler Messages (Hidden Until Tapped)

import { sendSpoilerText, sendSpoilerImage, sendSpoilerVideo, sendSpoilerAudio } from 'ai-md-btns';

// Text spoiler
await sendSpoilerText(sock, jid, 'This is a secret message! Tap to reveal 🔓');

// Image spoiler
await sendSpoilerImage(sock, jid, 'https://example.com/secret.jpg', '🔒 Hidden image');

// Video spoiler
await sendSpoilerVideo(sock, jid, 'https://example.com/secret.mp4', '🔒 Hidden video');

// Audio spoiler
await sendSpoilerAudio(sock, jid, 'https://example.com/secret.mp3', { ptt: false });

// Any media type
await sendSpoilerMedia(sock, jid, 'https://example.com/file.mp4', 'video', '🔒 Spoiler');

🤖 AI Icon Support

Enable AI-powered message styling (works in both group chats and DMs):

// Works in both GC and DM ✅
await sendButtons(sock, jid, {
  text: '🤖 AI-Powered Assistant',
  ai: true, // ← Enable AI icon
  buttons: [
    { text: 'Ask AI', id: 'ask_ai' },
    { text: 'Learn More', id: 'ai_info' }
  ]
});

// AI icon auto-disabled in groups if you prefer
await sendCodeBlock(sock, jid, {
  code: 'console.log("Hello");',
  language: 'javascript',
  ai: false // ← Optional: force disable
});

Note: AI icon is automatically disabled for interactive messages (buttons, lists, carousels) as WhatsApp doesn't support it there.


🎯 Button Builders

Helper functions for creating interactive buttons:

import { quickReply, urlBtn, copyBtn, callBtn, listSection } from 'ai-md-btns';

// Quick Reply Button - Sends command ID back
quickReply('Menu', '.menu', 'home');

// URL Button - Opens link in browser/webview
urlBtn('Visit Website', 'https://example.com', true);

// Copy Button - Copies text to clipboard
copyBtn('Copy License', 'MIT-12345-ABC');

// Call Button - Initiates phone call
callBtn('Call Support', '+1-800-123-4567');

// List Section - For structured menu items
listSection('Categories', [
  { title: 'Music', id: 'music', description: 'Music files' },
  { title: 'Videos', id: 'videos', description: 'Video files' }
]);

📊 Complete Method Reference

Interactive Messages

| Method | Description | GC | DM | AI Icon | |--------|-------------|----|----|---------| | sendButtons() | Quick reply buttons via nativeFlow | ✅ | ✅ | ❌ | | sendList() | Interactive list menu | ✅ | ✅ | ❌ | | sendNativeFlow() | Raw native flow buttons | ✅ | ✅ | ❌ | | sendCarousel() | Swipeable carousel cards | ✅ | ✅ | ❌ | | sendTemplate() | Hydrated template message | ✅ | ✅ | ❌ | | sendInteractiveMessage() | Convert v1.x interactive format | ✅ | ✅ | ❌ |

Media Messages

| Method | Description | GC | DM | AI Icon | Auto Media | |--------|-------------|----|----|---------|-----------| | sendAlbum() | Multiple images/videos | ✅ | ✅ | ❌ | ✅ | | sendStickerPack() | Sticker pack | ✅ | ✅ | ❌ | ✅ | | sendSpoilerImage() | Hidden image | ✅ | ✅ | ✅ | ✅ | | sendSpoilerVideo() | Hidden video | ✅ | ✅ | ✅ | ✅ | | sendSpoilerAudio() | Hidden audio | ✅ | ✅ | ✅ | ✅ | | sendSpoilerText() | Hidden text | ✅ | ✅ | ✅ | - |

Content Messages

| Method | Description | GC | DM | AI Icon | |--------|-------------|----|----|---------| | sendCodeBlock() | Syntax-highlighted code | ✅ | ✅ | ✅ | | sendLinks() | Inline clickable links | ✅ | ✅ | ✅ | | sendTable() | Data tables | ✅ | ✅ | ✅ | | sendRichResponse() | Rich formatted content | ✅ | ✅ | ✅ |

Engagement Messages

| Method | Description | GC | DM | AI Icon | |--------|-------------|----|----|---------| | sendPoll() | Polls & voting | ✅ | ✅ | ✅ | | sendEvent() | Calendar events | ✅ | ✅ | ✅ |

Commerce Messages

| Method | Description | GC | DM | AI Icon | Auto Media | |--------|-------------|----|----|---------|-----------| | sendProduct() | Product catalog | ✅ | ✅ | ✅ | ✅ |

Utility Messages

| Method | Description | GC | DM | AI Icon | |--------|-------------|----|----|---------| | sendLocation() | Location pin | ✅ | ✅ | ✅ | | sendContact() | Contact vCard | ✅ | ✅ | ✅ |

Universal Sender

| Method | Description | |--------|-------------| | smartSend() | Auto-detects message type & processes all media |


🎨 Media Handling

All functions that accept media support multiple input formats:

// URL string
await sendSpoilerImage(sock, jid, 'https://example.com/image.jpg', 'Caption');

// Object with URL
await sendSpoilerImage(sock, jid, { url: 'https://example.com/image.jpg' }, 'Caption');

// File path
await sendSpoilerImage(sock, jid, { path: './local/image.jpg' }, 'Caption');

// Buffer
await sendSpoilerImage(sock, jid, { buffer: Buffer.from(...) }, 'Caption');

🔄 Smart Universal Sender

Use smartSend() for maximum flexibility:

const messageObj = {
  text: 'Hello World',
  image: 'https://example.com/image.jpg',
  caption: 'Beautiful image',
  ai: true,
  buttons: [{ text: 'React', id: 'react' }]
};

await smartSend(sock, jid, messageObj, quoted);

🔧 Requirements

  • Node.js >= 20.x
  • ai-md-baileys >= 3.1.3

📚 API Documentation

Configuration Options

Common Options (All Methods)

{
  ai?: boolean;           // Enable AI icon (auto-disabled in groups for unsupported types)
  quoted?: object;        // Reply to a message
  text?: string;          // Main message text
  footer?: string;        // Footer text
}

Media Options

// Media can be:
// - URL string: 'https://example.com/image.jpg'
// - URL object: { url: 'https://...' }
// - File path: { path: './local/image.jpg' }
// - Buffer: { buffer: Buffer.from(...) }
// - Direct buffer: Buffer.from(...)

🌟 Best Practices

1. Always Use Quoted References

await sendButtons(sock, jid, {
  text: 'Reply to this',
  buttons: [{ text: 'OK', id: 'ok' }]
}, { quoted: msg });

2. Handle Media Errors

const result = await sendSpoilerImage(sock, jid, invalidUrl, 'Caption');
if (!result) {
  console.error('Failed to process image');
}

3. Use AI Icon Wisely

// Only enable AI for AI-related features
await sendCodeBlock(sock, jid, {
  code: 'const x = await ai.generate();',
  ai: true // Makes sense here
});

4. Optimize Media

// Use optimized URLs or compress before sending
await sendCarousel(sock, jid, {
  cards: [
    {
      image: 'https://cdn.example.com/optimized-500x500.jpg', // Good size
      title: 'Optimized'
    }
  ]
});

🐛 Troubleshooting

Media Not Loading

  • Ensure URLs are publicly accessible
  • Check file paths exist and are readable
  • Verify conn.waUploadToServer is configured

AI Icon Not Showing

  • AI icon only works in DM with ai: true
  • Automatically disabled in group chats
  • Not supported with button/list messages

Spoiler Messages Not Hidden

  • Requires updated ai-md-baileys version
  • Client must support spoiler messages
  • Some older WhatsApp versions may not hide

📝 TypeScript Support

import type { WASocket } from 'ai-md-baileys';
import { sendButtons, sendCarousel } from 'ai-md-btns';

async function sendMenu(sock: WASocket, jid: string) {
  await sendButtons(sock, jid, {
    text: 'Menu',
    buttons: [
      { text: 'Option 1', id: 'opt1' },
      { text: 'Option 2', id: 'opt2' }
    ]
  });
}

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


📄 License

MIT © SystemvError Inc


👨‍💻 Author

SystemvError - Creator & Maintainer


🔗 Related Projects


⭐ Support

If you find this project helpful, please star it on GitHub!

Happy coding! 🚀