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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@microfox/whatsapp-business

v1.5.2

Published

WhatsApp Business API SDK: A lightweight, type-safe SDK for interacting with the WhatsApp Business API

Downloads

987

Readme

@microfox/whatsapp-business

A lightweight, type-safe SDK for interacting with the WhatsApp Business API. This SDK provides a simple and intuitive interface to send various types of messages through the WhatsApp Business API.

Features

  • 🔒 Type-safe API with TypeScript
  • 📱 Support for all WhatsApp message types
  • 🚀 Easy to use and integrate
  • 🔄 Built-in error handling
  • 📦 Lightweight and dependency-free
  • 💬 Conversational Components Support
  • 📊 Analytics and insights
  • 🛍️ Commerce settings management
  • 📱 Phone number management
  • 📝 Template management
  • 📸 Media handling
  • ••• Typing indicator support
  • 🔄 Message reactions and contextual replies
  • 📍 Location sharing
  • 👥 Contact sharing
  • 🔄 Interactive messages (buttons, lists, flows)
  • 📱 QR code generation

Installation

npm install @microfox/whatsapp-business

Quick Start

import { WhatsAppBusinessSDK } from '@microfox/whatsapp-business';

// Initialize the SDK
const whatsapp = new WhatsAppBusinessSDK({
  phoneNumberId: process.env.WHATSAPP_BUSINESS_PHONE_NUMBER_ID,
  businessAccountId: process.env.WHATSAPP_BUSINESS_ACCOUNT_ID,
  accessToken: process.env.WHATSAPP_BUSINESS_ACCESS_TOKEN,
});
// Optional parameters
// version: 'v22.0', // Optional: defaults to v22.0
// baseUrl: 'https://graph.facebook.com/v22.0', // Optional: custom base URL

// Send a text message
await whatsapp.sendTextMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Hello from WhatsApp Business API!',
);

Configuration

The SDK requires the following configuration:

interface WhatsAppSDKConfig {
  phoneNumberId: string; // Your WhatsApp Business phone number ID
  businessAccountId: string; // Your WhatsApp Business account ID
  accessToken: string; // Your WhatsApp Business API access token
  version?: string; // Optional: API version (defaults to v22.0)
  baseUrl?: string; // Optional: Custom base URL
}

Conversational Components

Conversational components are in-chat features that make it easier for WhatsApp users to interact with your business. They include ice breakers and commands that users can tap or type to interact with your business.

Important Note: Make sure WHATSAPP_WEBHOOK_URL is set as an environment variable. The Conversational components require whatsapp webhook url.

Ice Breakers

Ice breakers are customizable, tappable text strings that appear in a message thread the first time you chat with a user. You can configure up to 4 ice breakers, each with a maximum of 80 characters.

Commands

Commands are text strings that WhatsApp users can see by typing a forward slash in a message thread. You can define up to 30 commands, each with a maximum of 32 characters for the command name and 256 characters for the description.

Configure Conversational Components

You can configure ice breakers and commands separately or together. Here are examples for each scenario:

Configure Only Ice Breakers

await whatsapp.configureConversationalComponents({
  enable_welcome_message: true,
  prompts: ['Book a flight', 'Plan a vacation', 'Find hotels', 'Rent a car'],
});

Configure Only Commands

await whatsapp.configureConversationalComponents({
  enable_welcome_message: true,
  commands: [
    {
      command_name: 'tickets',
      command_description: 'Book flight tickets',
    },
    {
      command_name: 'hotel',
      command_description: 'Book hotel',
    },
  ],
});

Configure Both Ice Breakers and Commands

await whatsapp.configureConversationalComponents({
  enable_welcome_message: true,
  prompts: ['Book a flight', 'Plan a vacation', 'Find hotels', 'Rent a car'],
  commands: [
    {
      command_name: 'tickets',
      command_description: 'Book flight tickets',
    },
    {
      command_name: 'hotel',
      command_description: 'Book hotel',
    },
  ],
});

Important Note: While Conversational Components can be reconfigured, it's recommended to avoid frequent changes as they can confuse users and disrupt their interaction patterns with your business. It's best to carefully plan your ice breakers and commands before implementation and only update them when absolutely necessary.

Get Current Configuration

const config = await whatsapp.getConversationalComponents();
console.log(config);
// {
//   enable_welcome_message: true,
//   prompts: ["Book a flight", "Plan a vacation"],
//   commands: [
//     { command_name: "tickets", command_description: "Book flight tickets" }
//   ]
// }

Common Message Options

All message types support the following options:

interface MessageOptions {
  recipientType?: 'individual' | 'group'; // Default: 'individual'
}

Text messages have additional options:

interface TextMessageOptions extends MessageOptions {
  previewUrl?: boolean; // Whether to show a preview URL, default: true
}

Message Types

Text Messages

// Basic text message (URL preview enabled by default)
await whatsapp.sendTextMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Hello from WhatsApp Business API!',
  { recipientType: 'individual' }, // Optional
);

// Text message with preview URL disabled
await whatsapp.sendTextMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Check out our website: https://example.com',
  {
    recipientType: 'individual',
    previewUrl: false, // Explicitly disable URL preview
  },
);

// Text message with preview URL enabled (explicit)
await whatsapp.sendTextMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Check out our website: https://example.com',
  {
    recipientType: 'individual',
    previewUrl: true, // Explicitly enable URL preview
  },
);

Media Messages

Image

// Using Media ID (Recommended)
const mediaId = await whatsapp.uploadMedia(file, 'image');
await whatsapp.sendImageMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    id: mediaId,
    caption: 'This is an image caption',
  },
  { recipientType: 'individual' }, // Optional
);

// Using Direct Link (Alternative)
await whatsapp.sendImageMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    link: 'https://example.com/image.jpg',
    caption: 'This is an image caption',
  },
  { recipientType: 'individual' }, // Optional
);

Video

// Using Media ID (Recommended)
const mediaId = await whatsapp.uploadMedia(file, 'video');
await whatsapp.sendVideoMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    id: mediaId,
    caption: 'This is a video caption',
  },
  { recipientType: 'individual' }, // Optional
);

// Using Direct Link (Alternative)
await whatsapp.sendVideoMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    link: 'https://example.com/video.mp4',
    caption: 'This is a video caption',
  },
  { recipientType: 'individual' }, // Optional
);

Document

// Using Media ID (Recommended)
const mediaId = await whatsapp.uploadMedia(file, 'document');
await whatsapp.sendDocumentMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    id: mediaId,
    filename: 'document.pdf',
    caption: 'This is a document caption',
  },
  { recipientType: 'individual' }, // Optional
);

// Using Direct Link (Alternative)
await whatsapp.sendDocumentMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    link: 'https://example.com/document.pdf',
    filename: 'document.pdf',
    caption: 'This is a document caption',
  },
  { recipientType: 'individual' }, // Optional
);

Audio

// Using Media ID (Recommended)
const mediaId = await whatsapp.uploadMedia(file, 'audio');
await whatsapp.sendAudioMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    id: mediaId,
  },
  { recipientType: 'individual' }, // Optional
);

// Using Direct Link (Alternative)
await whatsapp.sendAudioMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    link: 'https://example.com/audio.mp3',
  },
  { recipientType: 'individual' }, // Optional
);

Sticker

// Using Media ID (Recommended)
const mediaId = await whatsapp.uploadMedia(file, 'sticker');
await whatsapp.sendStickerMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    id: mediaId,
  },
  { recipientType: 'individual' }, // Optional
);

// Using Direct Link (Alternative)
await whatsapp.sendStickerMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    link: 'https://example.com/sticker.webp',
  },
  { recipientType: 'individual' }, // Optional
);

Location Messages

// Basic location
await whatsapp.sendLocationMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    longitude: 123.456,
    latitude: 78.901,
  },
  { recipientType: 'individual' }, // Optional
);

// Location with name and address
await whatsapp.sendLocationMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    longitude: 123.456,
    latitude: 78.901,
    name: 'Business Location',
    address: '123 Business Street, City, Country',
  },
  { recipientType: 'individual' }, // Optional
);

Location Request Messages

// Request user's location
await whatsapp.sendLocationRequestMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Please share your location',
  'individual',
);

Contact Messages

// Single contact
await whatsapp.sendContactMessage(
  'RECIPIENT_PHONE_NUMBER',
  [
    {
      name: {
        formatted_name: 'John Doe',
        first_name: 'John',
        last_name: 'Doe',
      },
      phones: [
        {
          phone: '+1234567890',
          type: 'WORK',
        },
      ],
    },
  ],
  { recipientType: 'individual' }, // Optional
);

// Multiple contacts
await whatsapp.sendContactMessage(
  'RECIPIENT_PHONE_NUMBER',
  [
    {
      name: {
        formatted_name: 'John Doe',
        first_name: 'John',
        last_name: 'Doe',
      },
      phones: [
        {
          phone: '+1234567890',
          type: 'WORK',
        },
      ],
    },
    {
      name: {
        formatted_name: 'Jane Smith',
        first_name: 'Jane',
        last_name: 'Smith',
      },
      phones: [
        {
          phone: '+0987654321',
          type: 'CELL',
        },
      ],
    },
  ],
  'individual',
);

Interactive Messages

Buttons

// Simple buttons
await whatsapp.sendInteractiveMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    type: 'button',
    body: {
      text: 'Choose an option',
    },
    action: {
      buttons: [
        {
          type: 'reply',
          reply: {
            id: 'option1',
            title: 'Option 1',
          },
        },
        {
          type: 'reply',
          reply: {
            id: 'option2',
            title: 'Option 2',
          },
        },
      ],
    },
  },
  { recipientType: 'individual' }, // Optional
);

// Buttons with emojis
await whatsapp.sendInteractiveMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    type: 'button',
    body: {
      text: 'How can we help you?',
    },
    action: {
      buttons: [
        {
          type: 'reply',
          reply: {
            id: 'support',
            title: '💬 Support',
          },
        },
        {
          type: 'reply',
          reply: {
            id: 'sales',
            title: '💰 Sales',
          },
        },
      ],
    },
  },
  { recipientType: 'individual' }, // Optional
);

Lists

// Simple list
await whatsapp.sendInteractiveMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    type: 'list',
    body: {
      text: 'Choose a category',
    },
    action: {
      button: 'Select',
      sections: [
        {
          title: 'Products',
          rows: [
            {
              id: 'product1',
              title: 'Product 1',
              description: 'Description of product 1',
            },
            {
              id: 'product2',
              title: 'Product 2',
              description: 'Description of product 2',
            },
          ],
        },
      ],
    },
  },
  { recipientType: 'individual' }, // Optional
);

// Multiple sections list
await whatsapp.sendInteractiveMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    type: 'list',
    body: {
      text: 'Select a service',
    },
    action: {
      button: 'Choose',
      sections: [
        {
          title: 'Support',
          rows: [
            {
              id: 'support_chat',
              title: 'Chat Support',
              description: '24/7 chat support',
            },
            {
              id: 'support_email',
              title: 'Email Support',
              description: 'Email support team',
            },
          ],
        },
        {
          title: 'Sales',
          rows: [
            {
              id: 'sales_contact',
              title: 'Contact Sales',
              description: 'Talk to our sales team',
            },
            {
              id: 'sales_demo',
              title: 'Request Demo',
              description: 'Schedule a product demo',
            },
          ],
        },
      ],
    },
  },
  { recipientType: 'individual' }, // Optional
);

Call-to-Action (CTA)

// CTA message with URL
await whatsapp.sendInteractiveCtaMessage(
  'RECIPIENT_PHONE_NUMBER',
  'Click the button below to visit our website',
  'https://example.com',
  'individual',
);

Template Messages

// Simple template
await whatsapp.sendTemplateMessage(
  'RECIPIENT_PHONE_NUMBER',
  'hello_world',
  'en_US',
  [
    {
      type: 'body',
      parameters: [
        {
          type: 'text',
          text: 'John',
        },
      ],
    },
  ],
  { recipientType: 'individual' }, // Optional
);

// Template with multiple components
await whatsapp.sendTemplateMessage(
  'RECIPIENT_PHONE_NUMBER',
  'order_confirmation',
  'en_US',
  [
    {
      type: 'header',
      parameters: [
        {
          type: 'text',
          text: 'Order #12345',
        },
      ],
    },
    {
      type: 'body',
      parameters: [
        {
          type: 'text',
          text: 'John',
        },
        {
          type: 'text',
          text: '2 items',
        },
        {
          type: 'text',
          text: '$99.99',
        },
      ],
    },
    {
      type: 'footer',
      text: 'Thank you for your order!',
    },
  ],
  { recipientType: 'individual' }, // Optional
);

Flow Messages

// Simple flow
await whatsapp.sendFlowMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    token: 'flow_token',
    parameters: {
      product_id: '123',
      user_id: '456',
    },
  },
  { recipientType: 'individual' }, // Optional
);

// Flow with header and body
await whatsapp.sendFlowMessage(
  'RECIPIENT_PHONE_NUMBER',
  {
    token: 'flow_token',
    header: {
      type: 'text',
      text: 'Welcome to our service!',
    },
    body: {
      text: 'Please complete the following steps:',
    },
    parameters: {
      flow_id: '789',
      step: '1',
    },
  },
  { recipientType: 'individual' }, // Optional
);

Message Reactions

// Send a reaction to a message
await whatsapp.sendReaction(
  'RECIPIENT_PHONE_NUMBER',
  'message_id',
  '❤️', // Emoji to react with
);

Send Typing Indicator

The typing indicator shows the user that you are preparing a response. This is a good practice for improving user experience when it will take a few seconds to respond.

await whatsapp.sendTypingIndicator({
  messageId: 'MESSAGE_ID',
  type: 'text', // Optional, defaults to 'text'
});

Note: The typing indicator will be dismissed automatically after 25 seconds or when you send a response, whichever comes first. Only use this feature when you are actually going to respond to the user.

Message Replies

// Text reply
await whatsapp.sendReply(
  'RECIPIENT_PHONE_NUMBER',
  'text',
  'Thank you for your message!',
  'message_id',
  { recipientType: 'individual' }, // Optional
);

// Media reply (image, video, document, audio, sticker)
await whatsapp.sendReply(
  'RECIPIENT_PHONE_NUMBER',
  'image',
  {
    id: 'MEDIA_ID',
    caption: 'Here is the image you requested',
  },
  'message_id',
  { recipientType: 'individual' }, // Optional
);

// Location reply
await whatsapp.sendReply(
  'RECIPIENT_PHONE_NUMBER',
  'location',
  {
    longitude: 123.456,
    latitude: 78.901,
    name: 'Business Location',
    address: '123 Business Street, City, Country',
  },
  'message_id',
  'individual',
);

// Contact reply
await whatsapp.sendReply(
  'RECIPIENT_PHONE_NUMBER',
  'contacts',
  [
    {
      name: {
        formatted_name: 'John Doe',
        first_name: 'John',
        last_name: 'Doe',
      },
      phones: [
        {
          phone: '+1234567890',
          type: 'WORK',
        },
      ],
    },
  ],
  'message_id',
  'individual',
);

// Interactive reply
await whatsapp.sendReply(
  'RECIPIENT_PHONE_NUMBER',
  'interactive',
  {
    type: 'button',
    body: {
      text: 'Choose an option',
    },
    action: {
      buttons: [
        {
          type: 'reply',
          reply: {
            id: 'option1',
            title: 'Option 1',
          },
        },
      ],
    },
  },
  'message_id',
  'individual',
);

Message Management

// Mark single message as read
await whatsapp.markMessageAsRead('MESSAGE_ID');

// Mark multiple messages as read
await whatsapp.markMessagesAsRead(['MESSAGE_ID_1', 'MESSAGE_ID_2']);

Media Management

// Upload media
const mediaId = await whatsapp.uploadMedia(file, 'image');

// Download media
const mediaData = await whatsapp.downloadMedia('MEDIA_ID');

// Get media URL
const mediaUrl = await whatsapp.getMediaUrl('MEDIA_ID');

Phone Number Management

// Register phone
await whatsapp.registerPhone('PHONE_NUMBER', 'PIN');

// Deregister phone
await whatsapp.deregisterPhone('PHONE_NUMBER');

// Get phone numbers
const phoneNumbers = await whatsapp.getPhoneNumbers();

// Get QR code
const qrCode = await whatsapp.getQRCode();

Business Profile

// Get business profile
const profile = await whatsapp.getBusinessProfile();

// Update business profile
const updatedProfile = await whatsapp.updateBusinessProfile({
  about: 'We provide excellent customer service',
  address: '123 Business Street, City, Country',
  description: 'Leading provider of business solutions',
  email: '[email protected]',
  website: 'https://business.com',
});

Analytics

// Get daily analytics
const analytics = await whatsapp.getAnalytics({
  start: '2024-01-01',
  end: '2024-01-31',
  granularity: 'DAY',
});

// Get hourly analytics
const hourlyAnalytics = await whatsapp.getAnalytics({
  start: '2024-01-01T00:00:00Z',
  end: '2024-01-01T23:59:59Z',
  granularity: 'HOUR',
});

Commerce Settings

// Get commerce settings
const settings = await whatsapp.getCommerceSettings();

// Update commerce settings
const updatedSettings = await whatsapp.updateCommerceSettings({
  catalog_id: 'CATALOG_ID',
  is_catalog_visible: true,
  cart_enabled: true,
  cart_expiration_time: 3600,
});

Error Handling

The SDK throws a WhatsAppBusinessSDKError for API errors with the following properties:

class WhatsAppBusinessSDKError extends Error {
  code: number;
  originalError: any;
}

Example error handling:

try {
  await whatsapp.sendTextMessage('RECIPIENT_PHONE_NUMBER', 'Hello!');
} catch (error) {
  if (error instanceof WhatsAppBusinessSDKError) {
    console.error(`Error ${error.code}: ${error.message}`);
    console.error('Original error:', error.originalError);
  }
}

Contributing

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

License

This project is licensed under the MIT License - see the LICENSE file for details.