npm package: @saastemly/helpbot-sdk
Description: Official Node.js SDK for the HelpBot API
Latest version: 0.1.0

# @helpbot/sdk

Official Node.js/Bun SDK for the [HelpBot](https://app.helpbot.com) API.

**Zero dependencies.** Requires Node.js 18+ (native `fetch`) or Bun.

## Installation

```bash
npm install @helpbot/sdk
# or
bun add @helpbot/sdk
```

## Quick Start

```ts
import { HelpBot } from '@helpbot/sdk'

const bot = new HelpBot({ apiKey: 'wk_live_abc123' })

const { answer, sources, conversationId } = await bot.chat('How do I reset my password?')
console.log(answer)
```

## Constructor Options

```ts
const bot = new HelpBot({
  apiKey: 'wk_live_abc123',           // Required
  baseUrl: 'https://app.helpbot.com', // Optional (or set HELPBOT_BASE_URL env var)
  timeout: 30_000,                    // Optional, ms (default: 30s)
  fetch: customFetch,                 // Optional, custom fetch implementation
})
```

## API Reference

### Chat

```ts
// Ask a question
const { answer, sources, conversationId } = await bot.chat('How do I reset my password?', {
  sessionId: 'user-session-123', // optional
  language: 'en',                // optional
})

// Submit feedback
await bot.feedback(conversationId, 'yes') // 'yes' | 'no'

// Request human handoff
await bot.handoff(conversationId, { customerEmail: 'user@example.com' })
```

### Sources (Scale plan)

```ts
// List all FAQ sources
const { sources } = await bot.sources.list()

// Add a new source URL
const { source } = await bot.sources.add('https://docs.example.com/faq')

// Re-scrape an existing source
await bot.sources.rescrape(source.id)

// Delete a source
await bot.sources.remove(source.id)
```

### Config

```ts
// Get widget configuration
const config = await bot.config.get()

// Update configuration
const { updated, config: newConfig } = await bot.config.update({
  primaryColor: '#4f46e5',
  botName: 'Support Bot',
  greeting: 'Hi! How can I help?',
})
```

### Analytics (Growth+ plan)

```ts
// Overview stats
const overview = await bot.analytics.overview({ range: '30d' })
console.log(overview.totalQuestions, overview.satisfactionRate)

// Daily activity
const { activity } = await bot.analytics.activity({ range: '7d' })

// List conversations with filtering
const { conversations, totalDocs, totalPages } = await bot.analytics.conversations({
  filter: 'unanswered', // 'all' | 'unanswered' | 'helpful' | 'unhelpful' | 'handoff'
  page: 1,
  limit: 20,
  range: '30d',
  search: 'password',
  sort: '-createdAt',
})
```

### Webhooks (Growth+ plan)

```ts
// Create a webhook
const { webhook } = await bot.webhooks.create({
  url: 'https://example.com/webhook',
  events: ['conversation.created', 'conversation.handoff'],
  description: 'Production webhook',
})
// Save webhook.secret — it's only shown once!

// List webhooks
const { webhooks } = await bot.webhooks.list()

// Delete a webhook
await bot.webhooks.delete(webhook.id)
```

### Webhook Signature Verification

Verify incoming webhook payloads without instantiating the client:

```ts
import { verifyWebhook } from '@helpbot/sdk'

// In your webhook handler (e.g. Express, Hono, etc.)
app.post('/webhook', (req) => {
  const signature = req.headers['x-helpbot-signature']
  const isValid = verifyWebhook(req.rawBody, signature, process.env.WEBHOOK_SECRET)

  if (!isValid) {
    return new Response('Invalid signature', { status: 401 })
  }

  const event = JSON.parse(req.rawBody)
  console.log(event.event, event.data)
})
```

## Error Handling

```ts
import { HelpBotAPIError, HelpBotTimeoutError, HelpBotNetworkError } from '@helpbot/sdk'

try {
  await bot.chat('test')
} catch (err) {
  if (err instanceof HelpBotAPIError) {
    console.log(err.status) // HTTP status code (401, 403, 429, etc.)
    console.log(err.body)   // Parsed JSON error body
  } else if (err instanceof HelpBotTimeoutError) {
    console.log('Request timed out')
  } else if (err instanceof HelpBotNetworkError) {
    console.log('Network error:', err.cause)
  }
}
```

## Webhook Events

| Event | Description |
|---|---|
| `conversation.created` | A new conversation was created |
| `conversation.unanswered` | The AI couldn't answer the question |
| `conversation.feedback` | User submitted feedback |
| `conversation.handoff` | User requested human support |

## License

MIT