@meet-im/meet-bot-jssdk 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,367 +1 @@
1
1
  # @meet-im/meet-bot-jssdk
2
-
3
- MeetIM Chatbot JavaScript SDK - 支持 Long Polling 消息获取、消息发送和媒体文件处理
4
-
5
- ## 安装
6
-
7
- ```bash
8
- pnpm add @meet-im/meet-bot-jssdk
9
- ```
10
-
11
- ## 快速开始
12
-
13
- ### 类实例风格
14
-
15
- ```typescript
16
- import { MeetBot } from '@meet-im/meet-bot-jssdk'
17
-
18
- const bot = new MeetBot({
19
- token: 'bot_id:secret',
20
- useV2: true, // 启用 getUpdatesV2,支持引用消息
21
- })
22
-
23
- bot.on('message', ({ message, quoteMsgMap }) => {
24
- console.log('收到消息:', message.content)
25
-
26
- // 处理引用消息
27
- if (message.quoteSeqID && message.sessionInfo) {
28
- const { getConvID, getQuoteMsgKey } = await import('@meet-im/meet-bot-jssdk')
29
- const convID = getConvID(
30
- message.sessionInfo.firstID,
31
- message.sessionInfo.secondID,
32
- message.sessionInfo.sessionType,
33
- message.sessionInfo.companyID
34
- )
35
- const quoteKey = getQuoteMsgKey(convID, message.quoteSeqID)
36
- const quoteMsg = quoteMsgMap[quoteKey]
37
- if (quoteMsg) {
38
- console.log('引用消息:', quoteMsg.content)
39
- }
40
- }
41
-
42
- if (message.sessionInfo) {
43
- bot.sendMessage(message.sessionInfo, { content: `收到: ${message.content}` })
44
- }
45
- })
46
-
47
- bot.startPolling()
48
- ```
49
-
50
- ### 函数式风格
51
-
52
- ```typescript
53
- import { getUpdatesV2, sendMessage } from '@meet-im/meet-bot-jssdk'
54
-
55
- const token = 'bot_id:secret'
56
- const baseUrl = 'https://staging-meet-api.miyachat.com'
57
-
58
- const { msgs, quoteMsgMap } = await getUpdatesV2({ token, baseUrl })
59
-
60
- for (const { message } of msgs) {
61
- if (message.sessionInfo) {
62
- console.log('收到消息:', message.content)
63
-
64
- await sendMessage({
65
- token,
66
- baseUrl,
67
- sessionInfo: message.sessionInfo,
68
- msgContent: { content: '收到!' },
69
- })
70
- }
71
- }
72
- ```
73
-
74
- ## API 文档
75
-
76
- ### MeetBot 类
77
-
78
- #### 构造函数
79
-
80
- ```typescript
81
- new MeetBot(config: MeetBotConfig)
82
- ```
83
-
84
- | 参数 | 类型 | 必填 | 说明 |
85
- | ------------------ | ------------------ | ---- | ------------------------------------------------------ |
86
- | token | string | 是\* | Bot Token,格式:`bot_id:secret` |
87
- | botId | string \| number | 是\* | Bot ID(与 botToken 配合使用) |
88
- | botToken | string | 是\* | Bot Token(与 botId 配合使用) |
89
- | baseUrl | string | 否 | API 地址,默认 `https://staging-meet-api.miyachat.com` |
90
- | pollingLimit | number | 否 | 每次拉取消息条数,默认 100 |
91
- | longPollingTimeout | number | 否 | 长轮询超时时间(秒),默认 30 |
92
- | useV2 | boolean | 否 | 使用 getUpdatesV2 接口,默认 false |
93
- | logLevel | 'silent' \| 'info' | 否 | 日志级别,默认 'silent' |
94
-
95
- \*token 或 (botId + botToken) 二选一
96
-
97
- #### 方法
98
-
99
- | 方法 | 说明 |
100
- | -------------------------------------- | ------------------ |
101
- | `on(event, handler)` | 监听事件 |
102
- | `off(event, handler)` | 移除事件监听 |
103
- | `startPolling(options?)` | 启动长轮询 |
104
- | `stopPolling()` | 停止轮询 |
105
- | `isPolling()` | 获取轮询状态 |
106
- | `getUpdates(options?)` | 手动获取消息(V1) |
107
- | `getUpdatesV2(options?)` | 手动获取消息(V2) |
108
- | `sendMessage(sessionInfo, msgContent)` | 发送消息 |
109
- | `getUploadURL(params)` | 获取单文件上传地址 |
110
- | `getMultiPartUploadURL(params)` | 获取分片上传地址 |
111
- | `completeMultipartUpload(params)` | 完成分片上传 |
112
- | `getAccessURL(params)` | 获取文件下载地址 |
113
- | `uploadFile(buffer, options)` | 上传文件 |
114
- | `sendMedia(sessionInfo, options)` | 发送媒体消息 |
115
-
116
- #### startPolling options
117
-
118
- | 参数 | 类型 | 默认值 | 说明 |
119
- | -------------- | ------------------------ | ------ | ------------------------------ |
120
- | timeout | number | 30 | 长轮询超时时间(秒) |
121
- | limit | number | 100 | 每次拉取消息条数 |
122
- | retryDelay | number | 1000 | 重试延迟基础时间(毫秒) |
123
- | maxRetries | number | 0 | 最大重试次数(0 表示无限重试) |
124
- | onOffsetUpdate | (offset: number) => void | - | offset 更新回调 |
125
-
126
- #### 事件
127
-
128
- | 事件 | 参数 | 说明 |
129
- | --------------- | -------------------------------------- | ---------- |
130
- | `message` | `{ message: MsgContent, quoteMsgMap }` | 收到新消息 |
131
- | `error` | `Error` | 发生错误 |
132
- | `polling_start` | `void` | 轮询开始 |
133
- | `polling_stop` | `void` | 轮询停止 |
134
-
135
- ### 函数式 API
136
-
137
- #### getUpdates(已废弃)
138
-
139
- ```typescript
140
- getUpdates(params: GetUpdatesParams): Promise<BotUpdate[]>
141
- ```
142
-
143
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
144
- | ------- | ------ | ---- | ------ | ----------------------- |
145
- | token | string | 是 | - | Bot Token |
146
- | baseUrl | string | 否 | - | API 地址 |
147
- | timeout | number | 否 | 0 | Long Polling 超时(秒) |
148
- | offset | number | 否 | 0 | 从该 seqId 之后获取 |
149
- | limit | number | 否 | 100 | 最大返回条数 |
150
-
151
- #### getUpdatesV2(推荐)
152
-
153
- ```typescript
154
- getUpdatesV2(params: GetUpdatesV2Params): Promise<GetUpdatesV2Result>
155
- ```
156
-
157
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
158
- | ------- | ------ | ---- | ------ | ----------------------- |
159
- | token | string | 是 | - | Bot Token |
160
- | baseUrl | string | 否 | - | API 地址 |
161
- | timeout | number | 否 | 0 | Long Polling 超时(秒) |
162
- | limit | number | 否 | 100 | 最大返回条数 |
163
-
164
- 返回值:
165
-
166
- ```typescript
167
- interface GetUpdatesV2Result {
168
- msgs: { message: MsgContent }[]
169
- quoteMsgMap: Record<string, MsgContent> // key: "convID:seqID"
170
- }
171
- ```
172
-
173
- #### sendMessage
174
-
175
- ```typescript
176
- sendMessage(params: SendMessageParams): Promise<SendMessageResult>
177
- ```
178
-
179
- | 参数 | 类型 | 必填 | 说明 |
180
- | ----------- | ----------- | ---- | --------- |
181
- | token | string | 是 | Bot Token |
182
- | baseUrl | string | 否 | API 地址 |
183
- | sessionInfo | SessionInfo | 是 | 会话信息 |
184
- | msgContent | MsgContent | 是 | 消息内容 |
185
-
186
- ### 媒体文件 API
187
-
188
- #### getUploadURL
189
-
190
- 获取单文件上传签名地址。
191
-
192
- ```typescript
193
- getUploadURL(params): Promise<UploadURLResult>
194
- ```
195
-
196
- | 参数 | 类型 | 必填 | 说明 |
197
- | -------------- | ------ | ---- | ---------------- |
198
- | token | string | 是 | Bot Token |
199
- | originFileName | string | 是 | 原始文件名 |
200
- | contentType | string | 是 | MIME 类型 |
201
- | md5 | string | 是 | 格式:`md5_hash` |
202
- | size | number | 是 | 文件大小(字节) |
203
-
204
- #### getAccessURL
205
-
206
- 获取文件下载地址。
207
-
208
- ```typescript
209
- // 方式1:完整参数
210
- getAccessURL({ token, firstId, secondId, sessionType, seqId, fileId })
211
-
212
- // 方式2:使用 sessionInfo
213
- getAccessURL({ token, sessionInfo, seqId, fileId })
214
- ```
215
-
216
- #### uploadFile
217
-
218
- 上传文件(自动选择单文件或分片上传)。
219
-
220
- ```typescript
221
- uploadFile(token, buffer, { fileName, contentType, onProgress? })
222
- ```
223
-
224
- #### sendMedia
225
-
226
- 发送媒体消息(上传并发送)。
227
-
228
- ```typescript
229
- sendMedia(token, sessionInfo, { buffer, fileName, contentType, content?, onProgress? })
230
- ```
231
-
232
- ### 工具函数
233
-
234
- #### getConvID
235
-
236
- 生成会话 ID。
237
-
238
- ```typescript
239
- import { getConvID } from '@meet-im/meet-bot-jssdk'
240
-
241
- const convID = getConvID(firstID, secondID, sessionType, companyID?)
242
- ```
243
-
244
- | 会话类型 | convID 格式 |
245
- | -------- | -------------------------------------- |
246
- | 私聊 (1) | `min:max` 或 `min:max:companyID` |
247
- | 群聊 (3) | `firstID+secondID` 或追加 `+companyID` |
248
- | 频道 | `firstID_secondID` 或追加 `_companyID` |
249
-
250
- #### getQuoteMsgKey
251
-
252
- 生成引用消息的 key。
253
-
254
- ```typescript
255
- import { getQuoteMsgKey } from '@meet-im/meet-bot-jssdk'
256
-
257
- const key = getQuoteMsgKey(convID, seqID) // "convID:seqID"
258
- ```
259
-
260
- ## 类型定义
261
-
262
- ```typescript
263
- type SessionType = 1 | 3 // 1: 私聊, 3: 群聊
264
-
265
- interface SessionInfo {
266
- firstID: number
267
- secondID: number
268
- sessionType: SessionType
269
- companyID?: number
270
- }
271
-
272
- type MsgType = 'NORMAL' | 'RECALL' | 'QUOTE'
273
-
274
- interface AttachmentInfo {
275
- fileID: string | number
276
- fileName?: string
277
- filePath?: string
278
- fileSize?: number
279
- mimeType?: string
280
- fileUrl?: string
281
- }
282
-
283
- interface ExtraInfo {
284
- msgType?: MsgType
285
- attechmentInfo?: AttachmentInfo // 单附件
286
- attechmentInfos?: AttachmentInfo[] // 多附件
287
- [key: string]: unknown
288
- }
289
-
290
- interface MsgContent {
291
- content: string
292
- seqId?: number
293
- timestamp?: number
294
- fromUid?: number
295
- atIds?: number[]
296
- quoteSeqID?: number // 引用消息 seqID
297
- extraInfo?: ExtraInfo
298
- sessionInfo?: SessionInfo
299
- }
300
-
301
- interface BotUpdate {
302
- message?: MsgContent
303
- }
304
-
305
- interface GetUpdatesV2Result {
306
- msgs: { message: MsgContent }[]
307
- quoteMsgMap: Record<string, MsgContent>
308
- }
309
-
310
- interface SendMessageResult {
311
- msgContent: MsgContent
312
- quoteMsg: unknown
313
- userProfileMap: Record<number, unknown>
314
- }
315
- ```
316
-
317
- ## 错误处理
318
-
319
- SDK 提供以下错误类型:
320
-
321
- | 错误类 | 说明 |
322
- | ----------------- | -------------- |
323
- | `MeetBotError` | 基础错误类 |
324
- | `ApiError` | API 返回的错误 |
325
- | `NetworkError` | 网络连接错误 |
326
- | `TimeoutError` | 请求超时错误 |
327
- | `ValidationError` | 参数验证错误 |
328
-
329
- ```typescript
330
- import { ApiError, NetworkError } from '@meet-im/meet-bot-jssdk'
331
-
332
- try {
333
- await bot.sendMessage(sessionInfo, { content: 'Hello' })
334
- } catch (error) {
335
- if (error instanceof ApiError) {
336
- console.error('API 错误:', error.code, error.statusCode)
337
- } else if (error instanceof NetworkError) {
338
- console.error('网络错误:', error.message)
339
- }
340
- }
341
- ```
342
-
343
- ## 开发
344
-
345
- ```bash
346
- # 安装依赖
347
- pnpm install
348
-
349
- # 构建
350
- pnpm build
351
-
352
- # 测试
353
- pnpm test
354
-
355
- # 类型检查
356
- pnpm typecheck
357
-
358
- # 代码格式化
359
- pnpm format
360
-
361
- # 代码检查
362
- pnpm lint
363
- ```
364
-
365
- ## License
366
-
367
- MIT