> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/vanilla-typescript/best-practices-and-type-definitions.md).

# 最佳实践与类型定义

## 最佳实践

### 1. 在发送消息前检查连接

```ts
if (client.state.isConnected) {
  client.sendUserTextMessage('你好');
}
```

### 2. 处理错误

```ts
try {
  await client.connect(config);
} catch (err) {
  console.error('连接失败', err);
}
```

### 3. 在需要时取消订阅事件

```ts
const off = client.on('message', handler);
off();
```

### 4. 清理时断开连接

```ts
window.addEventListener('beforeunload', () => {
  client.disconnect();
});
```

### 5. 使用 stateChange 保持 UI 响应

```ts
client.on('stateChange', updateUI);
```

***

## **核心类型：**

```typescript
import type {
  ConvaiClient,
  ConvaiConfig,
  ConvaiClientState,
  ChatMessage,
  IConvaiClient,
} from '@convai/web-sdk';
```

**控制接口：**

```typescript
import type {
  AudioControls,
  VideoControls,
  ScreenShareControls,
} from '@convai/web-sdk';
```

**口型同步类型：**

```typescript
import type {
  BlendshapeQueue,
  BlendshapeMapper,
  BlendshapeFormat,
  BlendshapeMappingConfig,
  BlendshapeNameMapping,
  OptimizedBlendshapeOutput,
} from '@convai/web-sdk';
```

**配置接口：**

```typescript
interface ConvaiConfig {
  apiKey: string;                    // 必需：您的 API 密钥
  characterId: string;                // 必需：角色 ID
  endUserId?: string;                 // 可选：用于记忆和分析
  url?: string;                       // 可选：自定义 API 端点
  enableVideo?: boolean;              // 启用视频/屏幕共享（默认：false）
  startWithVideoOn?: boolean;         // 启动时开启摄像头（默认：false）
  startWithAudioOn?: boolean;         // 启动时开启麦克风（默认：false）
  ttsEnabled?: boolean;               // 启用 TTS（默认：true）
  enableLipsync?: boolean;            // 启用 blendshape（默认：false）
  blendshapeConfig?: {
    format?: 'arkit' | 'mha';         // 形变格式（默认：'mha'）
  };
  actionConfig?: {                    // 可选：角色动作
    actions: string[];
    characters: Array<{ name: string; bio: string }>;
    objects: Array<{ name: string; description: string }>;
    currentAttentionObject?: string;
  };
}
```

***

## 客户端状态管理

该 `ConvaiClientState` 接口可完整查看会话状态：

```typescript
interface ConvaiClientState {
  isConnected: boolean;     // 已连接到角色
  isConnecting: boolean;    // 连接进行中
  isListening: boolean;     // 正在监听用户
  isThinking: boolean;      // 正在处理回复
  isSpeaking: boolean;      // 角色正在说话
  agentState: string;       // 组合状态
}
```

**智能体状态值：**

* `'disconnected'` - 未连接
* `'connected'` - 已连接但空闲
* `'listening'` - 正在主动监听用户
* `'thinking'` - 正在处理用户输入
* `'speaking'` - 角色正在响应

**用法：**

```typescript
// React
const { state } = convaiClient;
if (state.isSpeaking) {
  console.log('角色正在说话');
}

// 原生 JavaScript
client.on('stateChange', (state) => {
  console.log('状态：', state.agentState);
});
```

***

## 事件系统

SDK 使用事件驱动架构处理状态变化和消息：

**可用事件：**

| 事件                        | Parameters                   | 说明          |
| ------------------------- | ---------------------------- | ----------- |
| `stateChange`             | `(state: ConvaiClientState)` | 连接/活动状态已更改  |
| `message`                 | `(message: ChatMessage)`     | 收到新消息       |
| `messagesChange`          | `(messages: ChatMessage[])`  | 消息历史已更新     |
| `connect`                 | `()`                         | 成功连接        |
| `disconnect`              | `()`                         | 已与角色断开连接    |
| `error`                   | `(error: Error)`             | 发生错误        |
| `botReady`                | `()`                         | 机器人已准备好接收消息 |
| `userTranscriptionChange` | `(transcription: string)`    | 用户语音转录已更新   |

**用法：**

```typescript
// 订阅事件
const unsubscribe = client.on('stateChange', (state) => {
  console.log('状态已更改：', state);
});

// 取消订阅
unsubscribe();

// 或者手动
client.off('stateChange', callback);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/convai-web-sdk/vanilla-typescript/best-practices-and-type-definitions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
