# @d3oxy/msg91

TypeScript SDK for [MSG91](https://msg91.com) APIs - SMS OTP, WhatsApp, and more.

## Features

- Full TypeScript support with comprehensive types
- SMS OTP: Send, Verify, and Resend OTPs
- WhatsApp: Send template messages with headers, buttons, carousels
- Fluent builder pattern for complex WhatsApp messages
- Automatic retries with exponential backoff
- Subpath exports for tree-shaking

## Installation

```bash
# npm
npm install @d3oxy/msg91

# yarn
yarn add @d3oxy/msg91

# pnpm
pnpm add @d3oxy/msg91

# bun
bun add @d3oxy/msg91
```

## Quick Start

```typescript
import { createMsg91Client } from '@d3oxy/msg91';

const msg91 = createMsg91Client({
  authKey: 'your_auth_key_here',
});
```

## SMS OTP

### Send OTP

```typescript
const { data, error } = await msg91.smsOtp.send({
  templateId: 'your_template_id',
  mobile: '919876543210',
  otpLength: 6,
  otpExpiry: 5, // minutes
});

if (error) {
  console.error('Failed to send OTP:', error.message);
} else {
  console.log('OTP sent successfully');
}
```

### Verify OTP

```typescript
const { data, error } = await msg91.smsOtp.verify({
  otp: '123456',
  mobile: '919876543210',
});

if (error) {
  console.error('Verification failed:', error.message);
} else {
  console.log('OTP verified successfully');
}
```

### Resend OTP

```typescript
const { data, error } = await msg91.smsOtp.resend({
  mobile: '919876543210',
  retryType: 'text', // or 'voice'
});
```

## WhatsApp

### Send Template Message

```typescript
const { data, error } = await msg91.whatsapp.send({
  integratedNumber: '919876543210',
  templateName: 'order_confirmation',
  languageCode: 'en',
  recipients: [
    {
      to: '919876543211',
      components: {
        body_1: { type: 'text', value: 'John' },
        body_2: { type: 'text', value: 'Order #12345' },
      },
    },
  ],
});
```

### Using the Template Builder

For complex messages with headers, buttons, or carousels, use the fluent builder:

```typescript
const message = msg91.whatsapp.template()
  .setIntegratedNumber('919876543210')
  .setTemplate('promo_offer', 'en')
  .withImageHeader('https://example.com/banner.jpg')
  .withBodyVariable(1, 'John')
  .withBodyVariable(2, '20% OFF')
  .withUrlButton(1, 'shop-now')
  .withCopyCodeButton(2, 'SAVE20')
  .addRecipient('919876543211')
  .addRecipient(['919876543212', '919876543213'])
  .build();

const { data, error } = await msg91.whatsapp.sendRaw(message);
```

### Builder Methods

| Method | Description |
|--------|-------------|
| `setIntegratedNumber(number)` | Set your integrated WhatsApp number |
| `setTemplate(name, lang?)` | Set template name and language (default: 'en') |
| `addRecipient(to, components?)` | Add recipient(s) with optional components |
| `withTextHeader(value)` | Set text header |
| `withImageHeader(url)` | Set image header |
| `withVideoHeader(url)` | Set video header |
| `withDocumentHeader(url, filename)` | Set document header |
| `withLocationHeader(location)` | Set location header |
| `withBodyVariable(index, value)` | Set body variable (1-indexed) |
| `withUrlButton(index, urlVar)` | Set URL button |
| `withCopyCodeButton(index, code)` | Set copy code button |
| `withCarouselCard(index, type, url)` | Set carousel card header |
| `build()` | Build the final request |

## Configuration Options

```typescript
const msg91 = createMsg91Client({
  authKey: 'your_auth_key',      // Required
  baseUrl: '...',                 // SMS API base URL (optional)
  whatsappBaseUrl: '...',         // WhatsApp API base URL (optional)
  timeout: 30000,                 // Request timeout in ms (default: 30000)
  maxRetries: 2,                  // Max retry attempts (default: 2)
  retryDelay: 1000,               // Delay between retries in ms (default: 1000)
});
```

## Subpath Imports

For tree-shaking or when you only need types:

```typescript
// SMS OTP types only
import type { SendOtpParams, VerifyOtpParams } from '@d3oxy/msg91/sms-otp';

// WhatsApp types only
import type {
  SendWhatsAppMessageParams,
  TemplateComponents,
  WhatsAppMessageRequest,
} from '@d3oxy/msg91/whatsapp';

// WhatsApp template builder
import { WhatsAppTemplateBuilder } from '@d3oxy/msg91/whatsapp';
```

## Error Handling

All methods return `{ data, error }` for predictable error handling:

```typescript
const { data, error } = await msg91.smsOtp.send({ ... });

if (error) {
  // error: { name: string, message: string, code?: string, statusCode?: number }
  console.error(`Error: ${error.message}`);
  return;
}

// data is typed and available
console.log(data.message);
```

### Error Types

```typescript
import {
  Msg91Error,           // Base error class
  Msg91ApiError,        // API returned an error
  Msg91NetworkError,    // Network/connection issues
  Msg91RateLimitError,  // Rate limited
  Msg91ValidationError, // Input validation failed
  Msg91ConfigError,     // Configuration issues
} from 'msg91-js';
```

## API Reference

### SMS OTP Service (`msg91.smsOtp`)

| Method | Description |
|--------|-------------|
| `send(params)` | Send OTP to a mobile number |
| `verify(params)` | Verify OTP entered by user |
| `resend(params)` | Resend OTP via text or voice |

### WhatsApp Service (`msg91.whatsapp`)

| Method | Description |
|--------|-------------|
| `send(params)` | Send WhatsApp template message |
| `sendRaw(request)` | Send raw WhatsApp request |
| `template()` | Create a template builder |

## License

MIT
