@ikenxuan/amagi 5.2.0 → 5.4.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
@@ -20,19 +20,8 @@ amagi 将作为一个独立的上游模块,提供给下游 [karin-plugin-kkk](
20
20
  pnpm add @ikenxuan/amagi@latest
21
21
  ```
22
22
 
23
- ## 版本说明 📋
24
23
 
25
- ### v4 版本 (推荐) 🔄
26
-
27
- v4 版本保持向后兼容,是默认导入版本,适合现有项目的平滑迁移。
28
-
29
- ### v5 版本 (测试中 慎用) 🆕
30
-
31
- v5 版本是当前的主要开发版本,提供了更好的错误处理、统一的响应格式和更强的类型安全性。
32
-
33
- ## 快速开始 (v4 版本) 🚀
34
-
35
- ### 基本用法 ✨
24
+ ## 基本用法
36
25
  主要就两个方法,`getDouyinData` 和 `getBilibiliData`。
37
26
 
38
27
  > 它接收三个参数,
@@ -73,22 +62,6 @@ async function example() {
73
62
  example()
74
63
  ```
75
64
 
76
- ## v5 版本完整指南 🆕
77
-
78
- ### v5 版本使用方式
79
-
80
- ```javascript
81
- // v5 版本导入方式
82
- import { createAmagiClient } from '@ikenxuan/amagi/v5'
83
- // 或者
84
- import amagi from '@ikenxuan/amagi/v5'
85
-
86
- const client = createAmagiClient({ douyin: 'your_cookie' })
87
- const result = await client.getDouyinData('搜索数据', { keyword: '测试' })
88
- ```
89
-
90
- ### v5 版本主要变化
91
-
92
65
  #### 1. 统一的响应格式 📦
93
66
 
94
67
  v5 版本所有 API 返回统一的响应格式:
@@ -116,6 +89,8 @@ if (result.success) {
116
89
 
117
90
  #### 3. 类型模式控制 🎯
118
91
 
92
+ > 接口返回数据的类型类型为自动生成,仅供参考,不保证 100% 准确。
93
+
119
94
  支持 `strict` 和 `loose` 两种类型模式:
120
95
 
121
96
  ```javascript
@@ -132,94 +107,6 @@ const looseResult = await client.getDouyinData(
132
107
  )
133
108
  ```
134
109
 
135
- #### 4. 强化的参数验证 🔍
136
- v5 版本引入了 Zod 进行运行时参数验证,确保数据类型安全和参数完整性。
137
- PS: 当前更改已在 v4.5.0 往后的版本实装
138
-
139
- ```javascript
140
- // 自动参数验证
141
- const result = await client.getDouyinData('搜索数据', {
142
- keyword: '测试', // ✅ 必需参数
143
- offset: 0, // ✅ 可选参数,类型正确
144
- count: 20 // ✅ 可选参数,类型正确
145
- })
146
-
147
- // 参数验证失败示例
148
- const invalidResult = await client.getDouyinData('搜索数据', {
149
- // ❌ 缺少必需参数 keyword
150
- offset: 'invalid' // ❌ 类型错误,应为 number
151
- })
152
- // 返回: { success: false, message: '参数验证失败: ...', code: 400 }
153
- ```
154
-
155
- 验证特性:
156
-
157
- - 🔒 类型安全 :确保参数类型正确
158
- - ✅ 必需参数检查 :自动验证必需参数是否存在
159
- - 🎯 值范围验证 :验证数值范围、字符串长度等
160
- - 🛡️ 注入防护 :防止恶意参数注入
161
- - 📝 详细错误信息 :提供具体的验证失败原因
162
-
163
- ```javascript
164
- // 验证错误响应示例
165
- {
166
- code: 400,
167
- message: "参数验证失败",
168
- data: null,
169
- errors: [
170
- {
171
- path: ["keyword"],
172
- message: "必需参数",
173
- code: "invalid_type"
174
- },
175
- {
176
- path: ["offset"],
177
- message: "期望 number 类型,收到 string",
178
- code: "invalid_type"
179
- }
180
- ]
181
- }
182
- ```
183
-
184
- ### v5 版本兼容性更改 🔄
185
-
186
- #### 向后兼容性 ✅
187
-
188
- - **v4 API 完全兼容**:现有的 v4 代码无需修改即可继续使用
189
- - **默认导入保持 v4**:`import Client from '@ikenxuan/amagi'` 仍然使用 v4 版本
190
- - **渐进式迁移**:可以逐步迁移到 v5 版本,无需一次性重写
191
-
192
- #### 迁移指南 📖
193
-
194
- ##### 从 v4 迁移到 v5
195
-
196
- 1. **更新导入语句**:
197
- ```javascript
198
- // v4
199
- import Client from '@ikenxuan/amagi'
200
-
201
- // v5
202
- import Client from '@ikenxuan/amagi/v5'
203
- ```
204
-
205
- 2. **处理响应格式**:
206
- ```javascript
207
- // v4 - 直接返回数据
208
- const data = await amagi.getDouyinData('搜索数据', { keyword: '测试' })
209
-
210
- // v5 - 包装的响应格式
211
- const response = await client.getDouyinData('搜索数据', { keyword: '测试' })
212
- const data = response.data
213
- ```
214
-
215
- #### 破坏性变更 ⚠️
216
-
217
- v5 版本的破坏性变更:
218
-
219
- 1. **响应格式变更**:所有 API 返回包装的响应对象而非直接数据
220
- 2. **服务器方法重命名**:`startClient()` 重命名为 `startServer()`
221
- 3. **错误处理方式**:错误不再抛出异常,而是在响应对象中返回
222
-
223
110
  ## 高级用法 🔧
224
111
 
225
112
  ### 启动本地 HTTP 服务 🌐
@@ -240,86 +127,7 @@ const app = amagi.startClient()
240
127
  - 抖音 API: `http://localhost:4567/api/douyin/...` 📱
241
128
  - bilibili API: `http://localhost:4567/api/bilibili/...` 📺
242
129
 
243
- API 文档: https://amagi.apifox.cn 📝
244
-
245
- ## 平台功能模块 🧩
246
-
247
- PS: 以下功能模块的使用方法与上述基本用法类似,我也不知道为什么要写这个。。。
248
-
249
- ### 抖音功能模块 📱
250
-
251
- 抖音相关功能模块提供了一系列工具和 API 接口,用于获取抖音平台的数据。
252
-
253
- ```javascript
254
- import { douyinUtils } from '@ikenxuan/amagi'
255
-
256
- // 使用签名算法
257
- const mstoken = douyinUtils.sign.Mstoken(107)
258
- const verifyFp = douyinUtils.sign.VerifyFpManager()
259
- const abSign = douyinUtils.sign.AB('需要签名的地址')
260
-
261
- // 使用 API 接口
262
- const videoData = await douyinUtils.api.getWorkInfo(
263
- { ...opt },
264
- 'cookies'
265
- )
266
-
267
- const userInfo = await douyinUtils.api.getUserProfile(
268
- { ...opt },
269
- 'cookies'
270
- )
271
-
272
- // 直接获取数据
273
- const searchResult = await douyinUtils.getDouyinData(
274
- '搜索数据',
275
- { ...opt }
276
- )
277
- ```
278
-
279
- 主要功能:
280
-
281
- - 📹 视频/图集作品数据获取
282
- - 👤 用户信息获取
283
- - 💬 评论数据获取
284
- - 🔍 搜索功能
285
- - 🎬 直播间信息
286
- - 🎵 音乐数据
287
- - 😄 表情数据
288
-
289
- ### bilibili 功能模块 📺
290
-
291
- bilibili 相关功能模块提供了获取 bilibili 平台数据的工具和 API。
292
-
293
- ```javascript
294
- import { bilibiliUtils } from '@ikenxuan/amagi'
295
-
296
- // 获取视频信息
297
- const videoInfo = await bilibiliUtils.api.getVideoInfo({ ...opt })
298
-
299
- // 获取评论数据
300
- const comments = await bilibiliUtils.api.getComments({ ...opt })
301
-
302
- // 直接获取数据
303
- const userInfo = await bilibiliUtils.getBilibiliData(
304
- '用户主页数据',
305
- { ...opt }
306
- )
307
- ```
308
-
309
- 主要功能:
310
-
311
- - 📹 视频信息获取
312
- - 💬 评论数据获取
313
- - 👤 用户信息获取
314
- - 🎬 番剧信息获取
315
- - 📡 直播间信息
316
- - 📊 动态数据获取
317
- - 🔄 AV/BV 号转换
318
-
319
- ## 类型支持 🧰
320
-
321
- 该库提供完整的 TypeScript 类型支持,可以获得良好的代码提示和类型检查。✅
322
- 虽有类型但写得和迷宫一样
130
+ API 文档: https://amagi.apifox.cn 或 https://ikenxuan.github.io/amagi📝
323
131
 
324
132
  ## 许可证 📜
325
133
 
@@ -27,7 +27,7 @@ var express__default = /*#__PURE__*/_interopDefault(express);
27
27
  * GPL-3.0 Licensed
28
28
  */
29
29
 
30
- // node_modules/.pnpm/tsup@8.5.0_@swc+core@1.13.4_tsx@4.20.5_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js
30
+ // node_modules/.pnpm/tsup@8.5.0_@swc+core@1.13.5_tsx@4.20.5_typescript@5.9.2_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
31
31
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
32
32
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
33
33
  var getPackageLogsPath = () => {
@@ -44,6 +44,11 @@ var getPackageLogsPath = () => {
44
44
  return path__default.default.join(packageRoot, "logs");
45
45
  };
46
46
  var logsPath = getPackageLogsPath();
47
+ var getLogLevel = () => {
48
+ const logLevel = process.env.LOG_LEVEL || "info";
49
+ return logLevel;
50
+ };
51
+ var currentLogLevel = getLogLevel();
47
52
  log4js__default.default.configure({
48
53
  appenders: {
49
54
  console: {
@@ -84,7 +89,7 @@ log4js__default.default.configure({
84
89
  }
85
90
  },
86
91
  categories: {
87
- default: { appenders: ["console", "command"], level: "info" },
92
+ default: { appenders: ["console", "command"], level: currentLogLevel },
88
93
  http: { appenders: ["httpConsole", "httpRequest"], level: "debug" }
89
94
  },
90
95
  pm2: true
@@ -1741,6 +1746,43 @@ var DouyinAPI = class {
1741
1746
  };
1742
1747
  return `${baseUrl}?${buildQueryString(params)}`;
1743
1748
  }
1749
+ /**
1750
+ * 获取弹幕数据的接口地址
1751
+ * @param data - 请求参数,包含group_id、item_id等
1752
+ * @returns 完整的接口URL
1753
+ */
1754
+ \u5F39\u5E55(data2) {
1755
+ const baseUrl = "https://www-hj.douyin.com/aweme/v1/web/danmaku/get_v2/";
1756
+ const params = {
1757
+ ...this.getBaseParams(),
1758
+ app_name: "aweme",
1759
+ format: "json",
1760
+ group_id: data2.aweme_id,
1761
+ item_id: data2.aweme_id,
1762
+ start_time: data2.start_time ?? "0",
1763
+ end_time: data2.end_time ?? "32000",
1764
+ duration: data2.duration,
1765
+ update_version_code: "170400",
1766
+ pc_libra_divert: "Windows",
1767
+ support_h265: "1",
1768
+ support_dash: "1",
1769
+ version_code: "170400",
1770
+ version_name: "17.4.0",
1771
+ screen_width: "2328",
1772
+ screen_height: "1310",
1773
+ browser_name: "Edge",
1774
+ browser_version: "140.0.0.0",
1775
+ engine_name: "Blink",
1776
+ engine_version: "140.0.0.0",
1777
+ downlink: "1.55",
1778
+ round_trip_time: "200",
1779
+ webid: "7487210762873685515",
1780
+ msToken: douyinSign.Mstoken(116),
1781
+ verifyFp: fp,
1782
+ fp
1783
+ };
1784
+ return `${baseUrl}?${buildQueryString(params)}`;
1785
+ }
1744
1786
  };
1745
1787
  var createDouyinApiUrls = (userAgent) => {
1746
1788
  return new DouyinAPI(userAgent);
@@ -1763,6 +1805,7 @@ var DouyinData = async (data2, cookie, requestConfig) => {
1763
1805
  const userAgent = (_a = baseRequestConfig.headers) == null ? void 0 : _a["User-Agent"];
1764
1806
  const douyinApiUrls3 = createDouyinApiUrls(userAgent);
1765
1807
  switch (data2.methodType) {
1808
+ case "\u6587\u5B57\u4F5C\u54C1\u6570\u636E":
1766
1809
  case "\u805A\u5408\u89E3\u6790":
1767
1810
  case "\u89C6\u9891\u4F5C\u54C1\u6570\u636E":
1768
1811
  case "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E":
@@ -1987,6 +2030,84 @@ var DouyinData = async (data2, cookie, requestConfig) => {
1987
2030
  });
1988
2031
  return LoginQrcodeStatusData;
1989
2032
  }
2033
+ case "\u5F39\u5E55\u6570\u636E": {
2034
+ const MAX_SEGMENT_DURATION = 32e3;
2035
+ const startTime = data2.start_time ?? 0;
2036
+ const endTime = data2.end_time ?? data2.duration;
2037
+ const totalDuration = endTime - startTime;
2038
+ if (totalDuration <= MAX_SEGMENT_DURATION) {
2039
+ const url = douyinApiUrls3.\u5F39\u5E55({
2040
+ aweme_id: data2.aweme_id,
2041
+ start_time: startTime,
2042
+ end_time: endTime,
2043
+ duration: data2.duration
2044
+ });
2045
+ const DanmakuData = await GlobalGetData2(data2.methodType, {
2046
+ ...baseRequestConfig,
2047
+ url: `${url}&a_bogus=${douyinSign.AB(url, userAgent)}`
2048
+ });
2049
+ return DanmakuData;
2050
+ }
2051
+ const segments = [];
2052
+ let currentStart = startTime;
2053
+ while (currentStart < endTime) {
2054
+ const currentEnd = Math.min(currentStart + MAX_SEGMENT_DURATION, endTime);
2055
+ segments.push({ start: currentStart, end: currentEnd });
2056
+ currentStart = currentEnd;
2057
+ }
2058
+ logger.debug(`\u5F39\u5E55\u6570\u636E\u9700\u8981\u5206${segments.length}\u6BB5\u83B7\u53D6\uFF0C\u603B\u65F6\u957F\uFF1A${totalDuration}ms`);
2059
+ const segmentPromises = segments.map(async (segment, index) => {
2060
+ const url = douyinApiUrls3.\u5F39\u5E55({
2061
+ aweme_id: data2.aweme_id,
2062
+ start_time: segment.start,
2063
+ end_time: segment.end,
2064
+ duration: data2.duration
2065
+ });
2066
+ try {
2067
+ const segmentData = await GlobalGetData2(`${data2.methodType}-\u6BB5${index + 1}`, {
2068
+ ...baseRequestConfig,
2069
+ url: `${url}&a_bogus=${douyinSign.AB(url, userAgent)}`
2070
+ });
2071
+ logger.debug(`\u5F39\u5E55\u7B2C${index + 1}\u6BB5\u83B7\u53D6\u6210\u529F (${segment.start}ms-${segment.end}ms)`);
2072
+ return segmentData;
2073
+ } catch (error) {
2074
+ logger.debug(`\u5F39\u5E55\u7B2C${index + 1}\u6BB5\u83B7\u53D6\u5931\u8D25 (${segment.start}ms-${segment.end}ms):`, error);
2075
+ return null;
2076
+ }
2077
+ });
2078
+ const segmentResults = await Promise.all(segmentPromises);
2079
+ const mergedDanmakuList = [];
2080
+ let totalCount = 0;
2081
+ let finalStartTime = startTime;
2082
+ let finalEndTime = endTime;
2083
+ let finalExtra = null;
2084
+ let finalLogPb = null;
2085
+ let finalStatusCode = 0;
2086
+ segmentResults.forEach((segmentData, index) => {
2087
+ if (segmentData && segmentData.danmaku_list) {
2088
+ mergedDanmakuList.push(...segmentData.danmaku_list);
2089
+ totalCount += segmentData.total || 0;
2090
+ if (index === 0) {
2091
+ finalExtra = segmentData.extra;
2092
+ finalLogPb = segmentData.log_pb;
2093
+ finalStatusCode = segmentData.status_code;
2094
+ }
2095
+ }
2096
+ });
2097
+ mergedDanmakuList.sort((a, b) => (a.offset_time || 0) - (b.offset_time || 0));
2098
+ const finalDanmakuData = {
2099
+ danmaku_list: mergedDanmakuList,
2100
+ start_time: finalStartTime,
2101
+ end_time: finalEndTime,
2102
+ total: mergedDanmakuList.length,
2103
+ // 使用实际合并后的数量
2104
+ status_code: finalStatusCode,
2105
+ extra: finalExtra,
2106
+ log_pb: finalLogPb
2107
+ };
2108
+ logger.debug(`\u5F39\u5E55\u6570\u636E\u5408\u5E76\u5B8C\u6210\uFF0C\u5171\u83B7\u53D6${mergedDanmakuList.length}\u6761\u5F39\u5E55`);
2109
+ return finalDanmakuData;
2110
+ }
1990
2111
  default: {
1991
2112
  logger.warn(`\u672A\u77E5\u7684\u6296\u97F3\u6570\u636E\u63A5\u53E3\uFF1A\u300C${logger.red(data2.methodType)}\u300D`);
1992
2113
  return null;
@@ -2233,7 +2354,7 @@ var smartPositiveInteger = (errorMessage) => {
2233
2354
 
2234
2355
  // src/validation/douyin.ts
2235
2356
  var DouyinWorkParamsSchema = zod.z.object({
2236
- methodType: zod.z.enum(["\u89C6\u9891\u4F5C\u54C1\u6570\u636E", "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E", "\u5408\u8F91\u4F5C\u54C1\u6570\u636E", "\u805A\u5408\u89E3\u6790"]),
2357
+ methodType: zod.z.enum(["\u6587\u5B57\u4F5C\u54C1\u6570\u636E", "\u89C6\u9891\u4F5C\u54C1\u6570\u636E", "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E", "\u5408\u8F91\u4F5C\u54C1\u6570\u636E", "\u805A\u5408\u89E3\u6790"]),
2237
2358
  aweme_id: zod.z.string({ required_error: "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A" }).min(1, "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A")
2238
2359
  });
2239
2360
  var DouyinCommentParamsSchema = zod.z.object({
@@ -2273,7 +2394,37 @@ var DouyinEmojiListParamsSchema = zod.z.object({
2273
2394
  var DouyinEmojiProParamsSchema = zod.z.object({
2274
2395
  methodType: zod.z.literal("\u52A8\u6001\u8868\u60C5\u6570\u636E")
2275
2396
  });
2397
+ var DouyinDanmakuParamsSchema = zod.z.object({
2398
+ methodType: zod.z.literal("\u5F39\u5E55\u6570\u636E"),
2399
+ aweme_id: zod.z.string({ required_error: "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A" }).min(1, "\u89C6\u9891ID\u4E0D\u80FD\u4E3A\u7A7A"),
2400
+ start_time: zod.z.coerce.number().int().min(0).optional(),
2401
+ end_time: zod.z.coerce.number().int().min(0).optional(),
2402
+ duration: zod.z.coerce.number().int().min(0)
2403
+ }).refine(
2404
+ (data2) => {
2405
+ if (data2.end_time !== void 0) {
2406
+ return data2.end_time <= data2.duration;
2407
+ }
2408
+ return true;
2409
+ },
2410
+ {
2411
+ message: "\u83B7\u53D6\u5F39\u5E55\u533A\u95F4\u7684\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u8D85\u8FC7\u89C6\u9891\u603B\u65F6\u957F",
2412
+ path: ["end_time"]
2413
+ }
2414
+ ).refine(
2415
+ (data2) => {
2416
+ if (data2.start_time !== void 0 && data2.end_time !== void 0) {
2417
+ return data2.start_time < data2.end_time;
2418
+ }
2419
+ return true;
2420
+ },
2421
+ {
2422
+ message: "\u83B7\u53D6\u5F39\u5E55\u533A\u95F4\u7684\u5F00\u59CB\u65F6\u95F4\u5FC5\u987B\u5C0F\u4E8E\u7ED3\u675F\u65F6\u95F4",
2423
+ path: ["start_time"]
2424
+ }
2425
+ );
2276
2426
  var DouyinValidationSchemas2 = {
2427
+ "\u6587\u5B57\u4F5C\u54C1\u6570\u636E": DouyinWorkParamsSchema,
2277
2428
  "\u805A\u5408\u89E3\u6790": DouyinWorkParamsSchema,
2278
2429
  "\u89C6\u9891\u4F5C\u54C1\u6570\u636E": DouyinWorkParamsSchema,
2279
2430
  "\u56FE\u96C6\u4F5C\u54C1\u6570\u636E": DouyinWorkParamsSchema,
@@ -2288,7 +2439,8 @@ var DouyinValidationSchemas2 = {
2288
2439
  "\u7533\u8BF7\u4E8C\u7EF4\u7801\u6570\u636E": DouyinQrcodeParamsSchema,
2289
2440
  "Emoji\u6570\u636E": DouyinEmojiListParamsSchema,
2290
2441
  "\u52A8\u6001\u8868\u60C5\u6570\u636E": DouyinEmojiProParamsSchema,
2291
- "\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E": DouyinCommentReplyParamsSchema
2442
+ "\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E": DouyinCommentReplyParamsSchema,
2443
+ "\u5F39\u5E55\u6570\u636E": DouyinDanmakuParamsSchema
2292
2444
  };
2293
2445
  var BilibiliVideoParamsSchema = zod.z.object({
2294
2446
  methodType: zod.z.literal("\u5355\u4E2A\u89C6\u9891\u4F5C\u54C1\u6570\u636E"),
@@ -2457,8 +2609,8 @@ async function getDouyinData(methodType, optionsOrCookie, cookieOrOptions, reque
2457
2609
  ...validatedParams
2458
2610
  };
2459
2611
  const rawData = await DouyinData(apiParams, cookie, config);
2460
- if (rawData.data === "") {
2461
- return createErrorResponse(rawData.amagiError, "\u6296\u97F3\u6570\u636E\u83B7\u53D6\u5931\u8D25");
2612
+ if (rawData.data === "" || rawData.status_code !== 0) {
2613
+ return createErrorResponse(rawData.amagiError, rawData.status_msg || "\u6296\u97F3\u6570\u636E\u83B7\u53D6\u5931\u8D25");
2462
2614
  }
2463
2615
  return createSuccessResponse(rawData, "\u83B7\u53D6\u6210\u529F", 200);
2464
2616
  } catch (error) {
@@ -2999,6 +3151,13 @@ var createBoundDouyinApiMethod = (methodType, cookie, requestConfig) => {
2999
3151
  };
3000
3152
  };
3001
3153
  var douyin = {
3154
+ /**
3155
+ * 获取文字作品数据
3156
+ * @param options 请求参数,包含 aweme_id 和可选的 typeMode
3157
+ * @param cookie 有效的用户 Cookie
3158
+ * @returns 统一格式的API响应,包含文字作品详细信息
3159
+ */
3160
+ getTextWorkInfo: createDouyinApiMethod("\u6587\u5B57\u4F5C\u54C1\u6570\u636E"),
3002
3161
  /**
3003
3162
  * 聚合解析 (视频/图集/合辑)
3004
3163
  * @param options 请求参数,包含 aweme_id 和可选的 typeMode
@@ -3096,10 +3255,22 @@ var douyin = {
3096
3255
  * @param cookie 有效的用户 Cookie
3097
3256
  * @returns 统一格式的API响应,包含直播间详细信息
3098
3257
  */
3099
- getLiveRoomInfo: createDouyinApiMethod("\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E")
3258
+ getLiveRoomInfo: createDouyinApiMethod("\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E"),
3259
+ /**
3260
+ * 获取弹幕数据
3261
+ * @param options 请求参数,包含 aweme_id, 可选的 start_time, end_time, duration 和 typeMode
3262
+ * @returns 统一格式的API响应,包含弹幕数据
3263
+ */
3264
+ getDanmaku: createDouyinApiMethod("\u5F39\u5E55\u6570\u636E")
3100
3265
  };
3101
3266
  var createBoundDouyinApi = (cookie, requestConfig) => {
3102
3267
  return {
3268
+ /**
3269
+ * 获取文字作品数据
3270
+ * @param options 请求参数,包含 aweme_id 和可选的 typeMode
3271
+ * @returns 统一格式的API响应,包含文字作品详细信息
3272
+ */
3273
+ getTextWorkInfo: createBoundDouyinApiMethod("\u6587\u5B57\u4F5C\u54C1\u6570\u636E", cookie, requestConfig),
3103
3274
  /**
3104
3275
  * 聚合解析 (视频/图集/合辑)
3105
3276
  * @param options 请求参数,包含 aweme_id 和可选的 typeMode
@@ -3183,7 +3354,13 @@ var createBoundDouyinApi = (cookie, requestConfig) => {
3183
3354
  * @param options 请求参数,包含 sec_uid 和可选的 typeMode
3184
3355
  * @returns 统一格式的API响应,包含直播间详细信息
3185
3356
  */
3186
- getLiveRoomInfo: createBoundDouyinApiMethod("\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E", cookie, requestConfig)
3357
+ getLiveRoomInfo: createBoundDouyinApiMethod("\u76F4\u64AD\u95F4\u4FE1\u606F\u6570\u636E", cookie, requestConfig),
3358
+ /**
3359
+ * 获取弹幕数据
3360
+ * @param options 请求参数,包含 aweme_id, 可选的 start_time, end_time, duration 和 typeMode
3361
+ * @returns 统一格式的API响应,包含弹幕数据
3362
+ */
3363
+ getDanmaku: createBoundDouyinApiMethod("\u5F39\u5E55\u6570\u636E", cookie, requestConfig)
3187
3364
  };
3188
3365
  };
3189
3366
  var createDouyinRouteHandler = (dataFetcher, methodType, cookie, requestConfig = getDouyinDefaultConfig(cookie)) => {
@@ -3275,6 +3452,11 @@ var createDouyinRoutes = (cookie, requestConfig = getDouyinDefaultConfig(cookie)
3275
3452
  createDouyinValidationMiddleware("\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E"),
3276
3453
  createDouyinRouteHandler(getDouyinData, "\u6307\u5B9A\u8BC4\u8BBA\u56DE\u590D\u6570\u636E", cookie, requestConfig)
3277
3454
  );
3455
+ router.get(
3456
+ "/fetch_work_danmaku",
3457
+ createDouyinValidationMiddleware("\u5F39\u5E55\u6570\u636E"),
3458
+ createDouyinRouteHandler(getDouyinData, "\u5F39\u5E55\u6570\u636E", cookie, requestConfig)
3459
+ );
3278
3460
  return router;
3279
3461
  };
3280
3462
 
@@ -3528,6 +3710,7 @@ exports.BilibiliVideoParamsSchema = BilibiliVideoParamsSchema;
3528
3710
  exports.CreateApp = CreateApp;
3529
3711
  exports.DouyinCommentParamsSchema = DouyinCommentParamsSchema;
3530
3712
  exports.DouyinCommentReplyParamsSchema = DouyinCommentReplyParamsSchema;
3713
+ exports.DouyinDanmakuParamsSchema = DouyinDanmakuParamsSchema;
3531
3714
  exports.DouyinEmojiListParamsSchema = DouyinEmojiListParamsSchema;
3532
3715
  exports.DouyinEmojiProParamsSchema = DouyinEmojiProParamsSchema;
3533
3716
  exports.DouyinMusicParamsSchema = DouyinMusicParamsSchema;