npm package: @msghub/sdk
Description: Official TypeScript SDK for MsgHub.dev - WhatsApp & messaging APIs for developers
Author: MsgHub.dev
Latest version: 1.0.2

# @msghub/sdk

Official TypeScript SDK for [MsgHub.dev](https://msghub.dev) - WhatsApp & messaging APIs for developers.

## Installation

```bash
npm install @msghub/sdk
# or
yarn add @msghub/sdk
# or
pnpm add @msghub/sdk
```

**Note:** This SDK uses `axios` for HTTP requests to ensure compatibility with both browser and Node.js environments. The `axios` dependency is automatically installed with the SDK.

## Quick Start

```typescript
import { MsgHubClient } from '@msghub/sdk';

// Initialize the client
const client = new MsgHubClient({
  apiKey: 'ba_your_api_key_here'
});

// Send a text message
const result = await client.messages.send('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  message: 'Hello, World!'
});

console.log('Message sent:', result.data);
```

## Features

- ✅ **Type-safe**: Full TypeScript support with comprehensive type definitions
- ✅ **Modern**: Built with modern JavaScript/TypeScript features
- ✅ **Error handling**: Custom error classes for better error handling
- ✅ **Promise-based**: All methods return Promises
- ✅ **Tree-shakeable**: Only import what you need
- ✅ **Well-documented**: Comprehensive JSDoc comments

## API Reference

### Initialization

```typescript
const client = new MsgHubClient({
  apiKey: 'ba_your_api_key_here', // Required: Your API key
  baseUrl: 'https://api.msghub.dev', // Optional: Default API URL
  timeout: 30000, // Optional: Request timeout in ms (default: 30000)
});
```

### Account Management

#### Create a WhatsApp Account

```typescript
const result = await client.accounts.create({
  phoneNumber: '1234567890',
  label: 'My Business Account',
  webhookUrl: 'https://your-server.com/webhook' // Optional
});

// If you provided webhookUrl, msgHub will auto-create the webhook and return the secret once.
// Save it securely and verify webhook calls with the X-Webhook-Secret header.
console.log('Webhook secret (save this):', result.data?.webhook?.secret);
console.log('Account number id:', result.data?.accountNumberId);
```

### Webhooks (receive events on your server)

When your WhatsApp number receives a message, msgHub will POST the event to your webhook URL.

Every webhook request includes:

- Header: `X-Webhook-Secret: <your-secret>`
- JSON body: the forwarded event payload

#### Express example

```ts
import express from "express";
import {
  getWebhookEvent,
  getWebhookMessage,
  verifyWebhookSecret,
  type WebhookEnvelope,
  type WebhookMessageData,
} from "@msghub/sdk";

const app = express();
app.use(express.json());

app.post("/msghub/webhook", (req, res) => {
  if (!verifyWebhookSecret(req.headers, process.env.MSGHUB_WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: "Invalid webhook secret" });
  }

  const payload = req.body as WebhookEnvelope<WebhookMessageData>;
  const event = getWebhookEvent(payload);

  if (event === "message" || event === "message.new") {
    const msg = getWebhookMessage(payload);
    const from = msg.from || msg.jid || msg.sender;
    const text = msg.body || msg.text || msg.message || "";
    console.log("Incoming message:", { from, text });
  }

  // Always ack fast
  return res.status(200).json({ received: true });
});
```

#### Next.js (App Router) route handler example

```ts
import {
  getWebhookEvent,
  verifyWebhookSecret,
  type WebhookEnvelope,
  type WebhookMessageData,
} from "@msghub/sdk";

export async function POST(req: Request) {
  // Works in Node.js runtime (default). If you run in Edge, make sure your env var is available.
  if (!verifyWebhookSecret(req.headers, process.env.MSGHUB_WEBHOOK_SECRET!)) {
    return Response.json({ error: "Invalid webhook secret" }, { status: 401 });
  }

  const payload = (await req.json()) as WebhookEnvelope<WebhookMessageData>;
  const event = getWebhookEvent(payload);
  // do your thing with `payload`

  return Response.json({ received: true, event });
}
```

#### Get Account Status

```typescript
const status = await client.accounts.getStatus('1234567890');
console.log('Account status:', status.data);
```

#### List All Accounts

```typescript
const accounts = await client.accounts.list();
console.log('Your accounts:', accounts.data);
```

### Sending Messages

#### Send Text Message

```typescript
const result = await client.messages.send('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  message: 'Hello, World!',
  reply_message_id: 'optional_message_id' // Optional: Reply to a message
});
```

#### Send Image

```typescript
const result = await client.messages.sendImage('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  image: 'https://example.com/image.jpg', // or base64 string
  caption: 'Check this out!', // Optional
});
```

#### Send Video

```typescript
const result = await client.messages.sendVideo('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  video: 'https://example.com/video.mp4',
  caption: 'Watch this video!', // Optional
});
```

#### Send Audio

```typescript
const result = await client.messages.sendAudio('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  audio: 'https://example.com/audio.mp3',
  ptt: true // Optional: Mark as voice message
});
```

#### Send File

```typescript
const result = await client.messages.sendFile('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  file: 'https://example.com/document.pdf',
  filename: 'document.pdf',
  caption: 'Here is the document' // Optional
});
```

#### Send Contact

```typescript
const result = await client.messages.sendContact('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  contact: {
    displayName: 'John Doe',
    phoneNumber: '1234567890',
    organization: 'Acme Inc.' // Optional
  }
});
```

#### Send Location

```typescript
const result = await client.messages.sendLocation('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  latitude: 40.7128,
  longitude: -74.0060,
  name: 'New York City', // Optional
  address: 'New York, NY, USA' // Optional
});
```

#### Send Link with Preview

```typescript
const result = await client.messages.sendLink('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  url: 'https://example.com',
  text: 'Check out this website!' // Optional
});
```

#### Send Poll

```typescript
const result = await client.messages.sendPoll('1234567890', {
  phone: '6289685028129@s.whatsapp.net',
  question: 'What is your favorite color?',
  options: [
    { name: 'Red' },
    { name: 'Blue' },
    { name: 'Green' }
  ],
  selectableCount: 1 // Optional: Allow multiple selections
});
```

### Message Actions

#### Revoke Message

```typescript
const result = await client.messages.revoke('1234567890', 'message_id');
```

#### Delete Message

```typescript
const result = await client.messages.delete('1234567890', 'message_id');
```

#### React to Message

```typescript
const result = await client.messages.react('1234567890', 'message_id', '👍');
```

#### Edit Message

```typescript
const result = await client.messages.edit('1234567890', 'message_id', 'Updated message text');
```

#### Mark as Read

```typescript
const result = await client.messages.markAsRead('1234567890', 'message_id');
```

#### Star/Unstar Message

```typescript
// Star
await client.messages.star('1234567890', 'message_id');

// Unstar
await client.messages.unstar('1234567890', 'message_id');
```

### Chat Management

#### List Chats

```typescript
const chats = await client.chats.list('1234567890', {
  limit: 25, // Optional
  offset: 0 // Optional
});
```

#### Get Chat Messages

```typescript
const messages = await client.chats.getMessages(
  '1234567890',
  '6289685028129@s.whatsapp.net',
  {
    limit: 50, // Optional
    offset: 0 // Optional
  }
);
```

#### Label Chat

```typescript
const result = await client.chats.label(
  '1234567890',
  '6289685028129@s.whatsapp.net',
  ['important', 'customer']
);
```

#### Pin Chat

```typescript
// Pin
await client.chats.pin('1234567890', '6289685028129@s.whatsapp.net', true);

// Unpin
await client.chats.pin('1234567890', '6289685028129@s.whatsapp.net', false);
```

### User Information

#### Get User Info

```typescript
const userInfo = await client.users.getInfo(
  '1234567890',
  '6289685028129@s.whatsapp.net' // Optional: omit to get your own info
);
```

#### Check if User is on WhatsApp

```typescript
const result = await client.users.check('1234567890', '6289685028129');
console.log('Is on WhatsApp:', result.data?.is_on_whatsapp);
```

#### Get Business Profile

```typescript
const profile = await client.users.getBusinessProfile(
  '1234567890',
  '6289685028129@s.whatsapp.net'
);
```

### Error Handling

The SDK provides custom error classes for better error handling:

```typescript
import {
  MsgHubClient,
  AuthenticationError,
  RateLimitError,
  NotFoundError,
  ValidationError,
  NetworkError,
  TimeoutError
} from '@msghub/sdk';

try {
  const result = await client.messages.send('1234567890', {
    phone: '6289685028129@s.whatsapp.net',
    message: 'Hello!'
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limit exceeded. Retry after:', error.retryAfter);
  } else if (error instanceof NotFoundError) {
    console.error('Resource not found');
  } else if (error instanceof ValidationError) {
    console.error('Validation failed:', error.validationErrors);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  } else if (error instanceof TimeoutError) {
    console.error('Request timeout');
  } else {
    console.error('Unknown error:', error);
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and provides full type definitions. All types are exported for your convenience:

```typescript
import type {
  ClientOptions,
  SendMessageOptions,
  WhatsAppAccount,
  MessageResponse,
  Chat,
  ChatMessage,
  UserInfo,
  BusinessProfile
} from '@msghub/sdk';
```

## Requirements

- Node.js 14.0.0 or higher (or any modern browser)
- TypeScript 5.0.0 or higher (for TypeScript projects)
- axios (automatically installed with the SDK)

## Browser & Node.js Compatibility

This SDK works in both browser and Node.js environments:

- **Browser**: Works in all modern browsers (Chrome, Firefox, Safari, Edge)
- **Node.js**: Works in Node.js 14+ (uses axios for HTTP requests)

The SDK automatically detects the environment and uses the appropriate HTTP client.

## License

MIT