npm package: @idlen/chat-sdk
Description: Idlen Chat SDK for AI chatbot publishers - monetize conversations with contextual ads
Author: Idlen
Latest version: 1.0.5

# @idlen/chat-sdk

Monetize your AI chatbot with contextual, non-intrusive ads. The Idlen Chat SDK analyzes conversation context and serves relevant sponsored content in multiple formats.

## Installation

```bash
npm install @idlen/chat-sdk
```

## Quick Start

### Server-side (Node.js)

```ts
import { IdlenChatAds } from '@idlen/chat-sdk/server';

const ads = new IdlenChatAds({ apiKey: 'idl_pk_...' });

// Auto-extract context from conversation text
const ad = await ads.getAd({
  sessionId: conversationId,
  rawText: userMessage,
});

if (ad) {
  response += ad.renderMarkdown();
}
```

### Vercel AI SDK Middleware

```ts
import { wrapLanguageModel } from 'ai';
import { idlenAdsMiddleware } from '@idlen/chat-sdk/ai-sdk';

const model = wrapLanguageModel({
  model: openai('gpt-4o'),
  middleware: idlenAdsMiddleware({
    apiKey: 'idl_pk_...',
    frequency: 3,       // inject ad every 3 messages
    position: 'append', // 'append' or 'prepend'
  }),
});

const result = await streamText({ model, prompt: '...' });
```

### React

```tsx
import { useIdlenAd } from '@idlen/chat-sdk/react';

function ChatMessage({ message }: { message: string }) {
  const { ad, loading, fetchAd, trackClick } = useIdlenAd({
    apiKey: 'idl_pk_...',
  });

  useEffect(() => {
    fetchAd({ rawText: message, sessionId: 'abc' });
  }, [message]);

  return (
    <div>
      <p>{message}</p>
      {ad && (
        <a href={ad.ctaUrl} onClick={trackClick}>
          {ad.title}
        </a>
      )}
    </div>
  );
}
```

### Vue

```vue
<script setup>
import { useIdlenAd } from '@idlen/chat-sdk/vue';
import { watch } from 'vue';

const props = defineProps(['message']);
const { ad, loading, fetchAd, trackClick } = useIdlenAd({
  apiKey: 'idl_pk_...',
});

watch(() => props.message, (msg) => {
  fetchAd({ rawText: msg, sessionId: 'abc' });
});
</script>

<template>
  <div>
    <p>{{ message }}</p>
    <a v-if="ad" :href="ad.ctaUrl" @click="trackClick">
      {{ ad.title }}
    </a>
  </div>
</template>
```

### Browser (Script Tag)

```html
<script src="https://chat-sdk.idlen.io/v1/chat-sdk.js"></script>
<script>
  idlenChat('init', 'idl_pk_...');

  const ad = await idlenChat('getAd', {
    sessionId: 'session-123',
    context: {
      topics: ['react', 'deployment'],
      intent: 'informational',
      category: 'devtools',
    },
  });

  if (ad) {
    document.getElementById('ad-slot').innerHTML = ad.renderHTML();
  }
</script>
```

## Ad Formats

| Format | Description |
|--------|-------------|
| `chat_sponsored_recommendation` | Suggested tool/product (default) |
| `chat_cta_card` | Call-to-action card with image |
| `chat_contextual_link` | Inline contextual link |
| `chat_sponsored_answer` | Sponsored answer block |

## Context Extraction

The SDK includes a built-in dictionary of 120+ tech topics. Pass `rawText` and context is extracted automatically — no API call needed.

```ts
const ads = new IdlenChatAds({ apiKey: 'idl_pk_...' });

// Manual extraction
const context = ads.extractContext('How do I deploy a Next.js app on Vercel?');
// → { topics: ['nextjs', 'vercel'], intent: 'informational', category: 'devtools' }

// Or let getAd() do it automatically
const ad = await ads.getAd({
  sessionId: 'abc',
  rawText: 'How do I deploy a Next.js app on Vercel?',
});
```

You can also provide context manually:

```ts
const ad = await ads.getAd({
  sessionId: 'abc',
  context: {
    topics: ['react', 'deployment'],
    intent: 'transactional',
    category: 'cloud',
  },
});
```

## Rendering

Each ad has three render methods:

```ts
ad.renderMarkdown();  // For LLM/chat responses
ad.renderHTML();       // For web UIs
ad.renderPlainText();  // For terminals/logs
```

## Tracking

Impressions are tracked automatically when `getAd()` returns an ad. Clicks must be tracked manually:

```ts
// Server
await ads.trackClick(ad.adId, ad.publisherId, ad.requestId);

// React
const { trackClick } = useIdlenAd({ apiKey: '...' });
<button onClick={trackClick}>Learn more</button>

// Browser (uses sendBeacon)
idlenChat('click', adId, publisherId, requestId);
```

## API Reference

### `IdlenChatAds` (Server)

| Method | Description |
|--------|-------------|
| `getAd(request)` | Fetch a contextual ad. Returns `ChatAd \| null` |
| `extractContext(text)` | Extract topics/intent/category from text |
| `trackImpression(token, adId, publisherId)` | Record an impression (auto-called by `getAd`) |
| `trackClick(adId, publisherId, requestId)` | Record a click |

### `idlenAdsMiddleware(options)` (AI SDK)

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | required | Publisher API key |
| `format` | `ChatAdFormat` | `'chat_sponsored_recommendation'` | Ad format |
| `frequency` | `number` | `3` | Inject ad every N messages |
| `position` | `'append' \| 'prepend'` | `'append'` | Where to inject the ad |

### `useIdlenAd(options)` (React / Vue)

Returns `{ ad, loading, error, fetchAd, trackClick }`.

## License

MIT