@ikenxuan/amagi 7.0.0-beta.1 → 7.0.0-beta.2
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/dist/default/index.cjs +1 -1
- package/dist/default/index.d.ts +2 -2
- package/dist/default/index.mjs +1 -1
- package/dist/exports/compat.cjs +1 -1
- package/dist/exports/compat.d.ts +8 -4
- package/dist/exports/compat.mjs +1 -1
- package/dist/{index-nCXqYNq0.d.ts → index-CySQMTrB.d.ts} +222 -102
- package/dist/{src-AA7Elfxn.mjs → src-B2_6zBtd.mjs} +380 -39
- package/dist/{src-BmVVZLDU.cjs → src-CDlAxv9m.cjs} +379 -38
- package/package.json +3 -3
|
@@ -5094,7 +5094,7 @@ const xiaohongshuJudge = (raw, http) => {
|
|
|
5094
5094
|
const createXiaohongshuCryptoConfig = () => new _ikenxuan_xhshow_ts.CryptoConfig().withOverrides({
|
|
5095
5095
|
DATA_WEB_BUILD: "6.12.3",
|
|
5096
5096
|
SIGNATURE_DATA_TEMPLATE: {
|
|
5097
|
-
x0: "4.3
|
|
5097
|
+
x0: "4.4.3",
|
|
5098
5098
|
x1: "xhs-pc-web",
|
|
5099
5099
|
x2: "Windows",
|
|
5100
5100
|
x3: "",
|
|
@@ -5274,10 +5274,18 @@ const createXiaohongshuGuestCookie$1 = async (send, requestConfig) => {
|
|
|
5274
5274
|
* 小红书签名算法。
|
|
5275
5275
|
*
|
|
5276
5276
|
* 包装 `@ikenxuan/xhshow-ts` 的 `Xhshow` 实例,提供 GET / POST / X-S-Common /
|
|
5277
|
-
* X-T / X-B3-Traceid / 搜索 ID
|
|
5278
|
-
* `contracts/cookie.ts` 的 `getCookieValue`。
|
|
5277
|
+
* X-T / X-B3-Traceid / X-Xray-Traceid / X-Rap-Param / 搜索 ID / 搜索 request_id
|
|
5278
|
+
* 的生成函数。a1 从 cookie 取值的逻辑用 `contracts/cookie.ts` 的 `getCookieValue`。
|
|
5279
5279
|
*
|
|
5280
5280
|
* `Xhshow` 实例是模块级单例,行为与性能无额外开销。
|
|
5281
|
+
*
|
|
5282
|
+
* 上游 2026-02 之后的新协议由这里落地:
|
|
5283
|
+
* - **XYW_ 格式**(`generateXSGetXyw` / `generateXSPostXyw`):数据获取类接口
|
|
5284
|
+
* (`user_posted`、`user/otherinfo` 等)自 2026-03 起以 HTTP 406 拒绝传统 XYS_
|
|
5285
|
+
* 格式,改用基于 AES-128-CBC 的 XYW_ 签名。x-s 值以 `XYW_` 开头。
|
|
5286
|
+
* - **x-rap-param**(`generateXRapParam`):feed / 搜索 / 发布类接口的额外校验头。
|
|
5287
|
+
* - **x-xray-traceid**(`generateXrayTraceid`):追踪头,随现代浏览器每次请求下发。
|
|
5288
|
+
* - **search request_id**(`getSearchRequestId`):搜索接口所需的 `{random}-{ts_ms}`。
|
|
5281
5289
|
*/
|
|
5282
5290
|
/** 模块级 Xhshow 单例 */
|
|
5283
5291
|
const client = new _ikenxuan_xhshow_ts.Xhshow(createXiaohongshuCryptoConfig());
|
|
@@ -5300,6 +5308,34 @@ const generateXSGet = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) =
|
|
|
5300
5308
|
*/
|
|
5301
5309
|
const generateXSPost = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXsPost(path, a1Cookie, clientType, body);
|
|
5302
5310
|
/**
|
|
5311
|
+
* 生成 GET 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
|
|
5312
|
+
*
|
|
5313
|
+
* 数据获取类接口(`user_posted` 等)自 2026-03 起以 HTTP 406 拒绝 XYS_ 格式,
|
|
5314
|
+
* 需改用本函数。返回值以 `XYW_` 开头,走独立于 `signXsGet` 的加密路径。
|
|
5315
|
+
* @param path - API 路径,如 `/api/sns/web/v1/user_posted`
|
|
5316
|
+
* @param a1Cookie - a1 cookie 值
|
|
5317
|
+
* @param clientType - 客户端类型,默认 `'xhs-pc-web'`
|
|
5318
|
+
* @param params - 查询参数对象
|
|
5319
|
+
* @returns XYW_ 格式 X-S 签名
|
|
5320
|
+
*/
|
|
5321
|
+
const generateXSGetXyw = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) => client.signXyw("GET", path, a1Cookie, clientType, params);
|
|
5322
|
+
/**
|
|
5323
|
+
* 生成 POST 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
|
|
5324
|
+
* @param path - API 路径
|
|
5325
|
+
* @param a1Cookie - a1 cookie 值
|
|
5326
|
+
* @param clientType - 客户端类型,默认 `'xhs-pc-web'`
|
|
5327
|
+
* @param body - 请求体对象
|
|
5328
|
+
* @returns XYW_ 格式 X-S 签名
|
|
5329
|
+
*/
|
|
5330
|
+
const generateXSPostXyw = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXyw("POST", path, a1Cookie, clientType, body);
|
|
5331
|
+
/**
|
|
5332
|
+
* 生成 X-Rap-Param 请求头(feed / 搜索 / 发布类接口的额外校验)。
|
|
5333
|
+
* @param api - 请求 API,形如 `//edith.xiaohongshu.com/api/sns/web/v1/feed`(含 host、去协议)
|
|
5334
|
+
* @param body - 请求体对象(GET 传空对象)
|
|
5335
|
+
* @returns Base64 编码的 x-rap-param 字符串
|
|
5336
|
+
*/
|
|
5337
|
+
const generateXRapParam = (api, body = {}) => (0, _ikenxuan_xhshow_ts.xRapParam)(api, body);
|
|
5338
|
+
/**
|
|
5303
5339
|
* 生成 X-S-Common 参数。
|
|
5304
5340
|
* @param cookies - cookie 字符串
|
|
5305
5341
|
* @returns Base64 编码的随机字符串
|
|
@@ -5316,26 +5352,40 @@ const generateXT = () => client.getXT();
|
|
|
5316
5352
|
*/
|
|
5317
5353
|
const generateXB3Traceid = () => client.getB3TraceId();
|
|
5318
5354
|
/**
|
|
5355
|
+
* 生成 X-Xray-Traceid。
|
|
5356
|
+
*
|
|
5357
|
+
* 32 位字符(16 位时间戳+序列 + 16 位随机),随现代浏览器每次请求下发。
|
|
5358
|
+
* @returns X-Xray-Traceid 字符串
|
|
5359
|
+
*/
|
|
5360
|
+
const generateXrayTraceid = () => client.getXrayTraceId();
|
|
5361
|
+
/**
|
|
5319
5362
|
* 生成搜索 ID。
|
|
5320
5363
|
*
|
|
5321
|
-
*
|
|
5322
|
-
*
|
|
5323
|
-
*
|
|
5364
|
+
* 交由上游 `client.getSearchId()`:base36 编码的 `(timestamp_ms << 64) + random`。
|
|
5365
|
+
* 旧的本地实现把 BigInt 与 string 相加,得到「十进制拼 base36 后缀」而非预期的
|
|
5366
|
+
* 位运算结果 —— 上游修正后此处直接复用,不再自行拼装。
|
|
5324
5367
|
* @returns 搜索 ID 字符串
|
|
5325
5368
|
*/
|
|
5326
|
-
const getSearchId = () =>
|
|
5369
|
+
const getSearchId = () => client.getSearchId();
|
|
5327
5370
|
//#endregion
|
|
5328
5371
|
//#region src/platforms/xiaohongshu/sign/signers.ts
|
|
5329
5372
|
/**
|
|
5330
5373
|
* 小红书签名器表。
|
|
5331
5374
|
*
|
|
5332
|
-
*
|
|
5375
|
+
* XYS_(传统)路径:
|
|
5333
5376
|
* - `'xhs-post'`:POST 请求,`x-s` 用 `signXsPost` 对 body 签名
|
|
5334
5377
|
* - `'xhs-get'`:GET 请求,`x-s` 用 `signXsGet` 对 query 签名
|
|
5335
5378
|
* - `'xhs-get-trace'`:GET + `x-b3-traceid`(userNoteList 专用)
|
|
5379
|
+
* - `'xhs-post-rap'`:POST + `x-rap-param`(feed / 搜索 / 发布类接口的额外校验)
|
|
5380
|
+
*
|
|
5381
|
+
* XYW_(2026-03 之后)路径 —— 数据获取类接口以 HTTP 406 拒绝 XYS_,`x-s` 改用
|
|
5382
|
+
* 以 `XYW_` 开头的 AES-128-CBC 签名:
|
|
5383
|
+
* - `'xhs-get-xyw'`:GET,`x-s` 用 `signXyw`
|
|
5384
|
+
* - `'xhs-post-xyw'`:POST,`x-s` 用 `signXyw`
|
|
5385
|
+
* - `'xhs-get-xyw-trace'`:GET XYW + `x-b3-traceid`(userNoteList 专用)
|
|
5336
5386
|
*
|
|
5337
5387
|
* 签名路径取自 `spec.signPath`(build 里填 `apiPath`),不是 `spec.url`:
|
|
5338
|
-
* 小红书签名只用接口路径,与完整 URL 无关。
|
|
5388
|
+
* 小红书签名只用接口路径,与完整 URL 无关。x-rap-param 例外,它要 host + path。
|
|
5339
5389
|
*
|
|
5340
5390
|
* 签名输入:a1 取自 cookie,POST 签名含 body,GET 签名含 query。
|
|
5341
5391
|
*/
|
|
@@ -5343,9 +5393,26 @@ const getSearchId = () => (BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.r
|
|
|
5343
5393
|
const a1Of = (cookie) => getCookieValue(cookie, "a1") ?? "";
|
|
5344
5394
|
/** 签名路径:优先 `spec.signPath`(build 填的 apiPath),缺省取 URL 的 pathname */
|
|
5345
5395
|
const apiPathOf = (spec) => spec.signPath ?? new URL(spec.url).pathname;
|
|
5346
|
-
/**
|
|
5396
|
+
/**
|
|
5397
|
+
* 取签名用的 query 参数:GET 端点在 `build` 里把原始 params 放进 `extra.signParams`。
|
|
5398
|
+
* 小红书 GET 的 x-s 必须覆盖 query(路径 + 参数),只签路径会被判非法请求返回 406。
|
|
5399
|
+
* 无参数端点(emojiList / userProfile)返回空对象,签名退化为只签路径,行为不变。
|
|
5400
|
+
*/
|
|
5401
|
+
const signParamsOf = (spec) => spec.extra?.signParams ?? {};
|
|
5402
|
+
/** x-rap-param 的 api 入参:去协议、保留 `//host/path`(不含 query) */
|
|
5403
|
+
const rapApiOf = (spec) => {
|
|
5404
|
+
const url = new URL(spec.url);
|
|
5405
|
+
return `//${url.host}${url.pathname}`;
|
|
5406
|
+
};
|
|
5407
|
+
/**
|
|
5408
|
+
* 注入 x-s / x-s-common / x-t / x-xray-traceid 四个签名头。
|
|
5409
|
+
*
|
|
5410
|
+
* `x-xray-traceid` 是真实浏览器每次请求都带的追踪头(见 noteComments 的抓包);
|
|
5411
|
+
* 早期只发前三个,`comment/page` 这类接口会因此被判为非法请求,返回 HTTP 406。
|
|
5412
|
+
* 所有平台签名器共用本 helper,因此补上后对全部端点生效。
|
|
5413
|
+
*/
|
|
5347
5414
|
const signHeaders = (spec, ctx, xs) => {
|
|
5348
|
-
const headers = new AmagiHeaders(spec.headers).set("x-s", xs).set("x-s-common", generateXSCommon(ctx.cookie)).set("x-t", String(generateXT()));
|
|
5415
|
+
const headers = new AmagiHeaders(spec.headers).set("x-s", xs).set("x-s-common", generateXSCommon(ctx.cookie)).set("x-t", String(generateXT())).set("x-xray-traceid", generateXrayTraceid());
|
|
5349
5416
|
return {
|
|
5350
5417
|
...spec,
|
|
5351
5418
|
headers: headers.toJSON()
|
|
@@ -5356,9 +5423,9 @@ const xhsPostSigner = (spec, ctx) => {
|
|
|
5356
5423
|
const xs = generateXSPost(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
|
|
5357
5424
|
return signHeaders(spec, ctx, xs);
|
|
5358
5425
|
};
|
|
5359
|
-
/** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web') */
|
|
5426
|
+
/** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web', signParams) */
|
|
5360
5427
|
const xhsGetSigner = (spec, ctx) => {
|
|
5361
|
-
const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web");
|
|
5428
|
+
const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
|
|
5362
5429
|
return signHeaders(spec, ctx, xs);
|
|
5363
5430
|
};
|
|
5364
5431
|
/** GET + x-b3-traceid(userNoteList 专用) */
|
|
@@ -5370,11 +5437,44 @@ const xhsGetTraceSigner = async (spec, ctx) => {
|
|
|
5370
5437
|
headers: headers.toJSON()
|
|
5371
5438
|
};
|
|
5372
5439
|
};
|
|
5440
|
+
/** POST + x-rap-param(feed / 搜索 / 发布类接口的额外校验) */
|
|
5441
|
+
const xhsPostRapSigner = async (spec, ctx) => {
|
|
5442
|
+
const signed = await xhsPostSigner(spec, ctx);
|
|
5443
|
+
const rap = generateXRapParam(rapApiOf(spec), spec.body ?? {});
|
|
5444
|
+
const headers = new AmagiHeaders(signed.headers).set("x-rap-param", rap);
|
|
5445
|
+
return {
|
|
5446
|
+
...signed,
|
|
5447
|
+
headers: headers.toJSON()
|
|
5448
|
+
};
|
|
5449
|
+
};
|
|
5450
|
+
/** XYW GET 签名器:x-s = signXyw('GET', apiPath, a1, 'xhs-pc-web', signParams),绕过数据接口 406 */
|
|
5451
|
+
const xhsGetXywSigner = (spec, ctx) => {
|
|
5452
|
+
const xs = generateXSGetXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
|
|
5453
|
+
return signHeaders(spec, ctx, xs);
|
|
5454
|
+
};
|
|
5455
|
+
/** XYW POST 签名器:x-s = signXyw('POST', apiPath, a1, 'xhs-pc-web', body) */
|
|
5456
|
+
const xhsPostXywSigner = (spec, ctx) => {
|
|
5457
|
+
const xs = generateXSPostXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
|
|
5458
|
+
return signHeaders(spec, ctx, xs);
|
|
5459
|
+
};
|
|
5460
|
+
/** XYW GET + x-b3-traceid(userNoteList 专用,2026-03 之后) */
|
|
5461
|
+
const xhsGetXywTraceSigner = async (spec, ctx) => {
|
|
5462
|
+
const signed = await xhsGetXywSigner(spec, ctx);
|
|
5463
|
+
const headers = new AmagiHeaders(signed.headers).set("x-b3-traceid", generateXB3Traceid());
|
|
5464
|
+
return {
|
|
5465
|
+
...signed,
|
|
5466
|
+
headers: headers.toJSON()
|
|
5467
|
+
};
|
|
5468
|
+
};
|
|
5373
5469
|
/** 平台签名器表,交给 runtime 的 `signers` 查名 */
|
|
5374
5470
|
const createXiaohongshuSigners = () => ({
|
|
5375
5471
|
"xhs-post": xhsPostSigner,
|
|
5376
5472
|
"xhs-get": xhsGetSigner,
|
|
5377
|
-
"xhs-get-trace": xhsGetTraceSigner
|
|
5473
|
+
"xhs-get-trace": xhsGetTraceSigner,
|
|
5474
|
+
"xhs-post-rap": xhsPostRapSigner,
|
|
5475
|
+
"xhs-get-xyw": xhsGetXywSigner,
|
|
5476
|
+
"xhs-post-xyw": xhsPostXywSigner,
|
|
5477
|
+
"xhs-get-xyw-trace": xhsGetXywTraceSigner
|
|
5378
5478
|
});
|
|
5379
5479
|
//#endregion
|
|
5380
5480
|
//#region src/runtime/events.ts
|
|
@@ -7383,7 +7483,7 @@ var DouyinAPI$1 = class {
|
|
|
7383
7483
|
keyword: data.query,
|
|
7384
7484
|
list_type: "single",
|
|
7385
7485
|
need_filter_settings: "1",
|
|
7386
|
-
offset:
|
|
7486
|
+
offset: String(data.offset ?? 0),
|
|
7387
7487
|
pc_libra_divert: "Windows",
|
|
7388
7488
|
pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
|
|
7389
7489
|
query_correct_type: "1",
|
|
@@ -7411,7 +7511,7 @@ var DouyinAPI$1 = class {
|
|
|
7411
7511
|
keyword: data.query,
|
|
7412
7512
|
list_type: "single",
|
|
7413
7513
|
need_filter_settings: "1",
|
|
7414
|
-
offset:
|
|
7514
|
+
offset: String(data.offset ?? 0),
|
|
7415
7515
|
pc_libra_divert: "Windows",
|
|
7416
7516
|
pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
|
|
7417
7517
|
query_correct_type: "1",
|
|
@@ -7438,7 +7538,7 @@ var DouyinAPI$1 = class {
|
|
|
7438
7538
|
keyword: data.query,
|
|
7439
7539
|
list_type: "",
|
|
7440
7540
|
need_filter_settings: "1",
|
|
7441
|
-
offset:
|
|
7541
|
+
offset: String(data.offset ?? 0),
|
|
7442
7542
|
pc_libra_divert: "Windows",
|
|
7443
7543
|
pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
|
|
7444
7544
|
query_correct_type: "1",
|
|
@@ -8281,7 +8381,8 @@ const search = defineEndpoint({
|
|
|
8281
8381
|
"video"
|
|
8282
8382
|
]).default("general").optional().describe("搜索类型,默认综合搜索"),
|
|
8283
8383
|
number: zod.default.coerce.number().int().min(1).optional().describe("目标条数,默认 15"),
|
|
8284
|
-
search_id: zod.default.string().optional().describe("翻页游标,一般不用传")
|
|
8384
|
+
search_id: zod.default.string().optional().describe("翻页游标,一般不用传"),
|
|
8385
|
+
offset: zod.default.coerce.number().int().min(0).optional().describe("翻页偏移,一般不用传")
|
|
8285
8386
|
}),
|
|
8286
8387
|
build: (p, ctx) => {
|
|
8287
8388
|
const searchType = p.type ?? "general";
|
|
@@ -8292,7 +8393,8 @@ const search = defineEndpoint({
|
|
|
8292
8393
|
query: p.query,
|
|
8293
8394
|
type: searchType,
|
|
8294
8395
|
number: p.number,
|
|
8295
|
-
search_id: p.search_id
|
|
8396
|
+
search_id: p.search_id,
|
|
8397
|
+
offset: p.offset
|
|
8296
8398
|
}),
|
|
8297
8399
|
headers: withDouyinReferer(ctx, {
|
|
8298
8400
|
kind: "search",
|
|
@@ -8330,9 +8432,13 @@ const search = defineEndpoint({
|
|
|
8330
8432
|
nextParams: (params, page) => {
|
|
8331
8433
|
const p = page;
|
|
8332
8434
|
const nextSearchId = (typeof p.rid === "string" && p.rid.length > 0 ? p.rid : void 0) ?? (typeof p.log_pb?.impr_id === "string" ? p.log_pb.impr_id : void 0) ?? params.search_id;
|
|
8435
|
+
const currentOffset = params.offset ?? 0;
|
|
8436
|
+
const items = Array.isArray(page && page.user_list) ? page.user_list : page.data ?? [];
|
|
8437
|
+
const nextOffset = typeof p.cursor === "number" && p.cursor > currentOffset ? p.cursor : currentOffset + items.length;
|
|
8333
8438
|
return {
|
|
8334
8439
|
...params,
|
|
8335
|
-
search_id: nextSearchId
|
|
8440
|
+
search_id: nextSearchId,
|
|
8441
|
+
offset: nextOffset
|
|
8336
8442
|
};
|
|
8337
8443
|
}
|
|
8338
8444
|
},
|
|
@@ -11957,8 +12063,15 @@ const SEARCH_NOTE_TYPE = {
|
|
|
11957
12063
|
VIDEO: 1,
|
|
11958
12064
|
IMAGE: 2
|
|
11959
12065
|
};
|
|
11960
|
-
/**
|
|
11961
|
-
|
|
12066
|
+
/**
|
|
12067
|
+
* 构建查询字符串:跳过 null / undefined。
|
|
12068
|
+
*
|
|
12069
|
+
* **编码规则必须与 `@ikenxuan/xhshow-ts` 的签名内部编码完全一致**:只把值里的
|
|
12070
|
+
* `=` 转成 `%3D`,其余字符(含 `,`)原样保留。小红书对 GET 请求按「路径 + 这套
|
|
12071
|
+
* 编码的 query」计算 x-s,若这里用 `encodeURIComponent`(会把 `,` 转成 `%2C`),
|
|
12072
|
+
* 发出去的 query 与被签名的内容不一致,平台返回 HTTP 406。
|
|
12073
|
+
*/
|
|
12074
|
+
const buildQueryString$2 = (params) => Object.entries(params).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${String(value).replace(/=/g, "%3D")}`).join("&");
|
|
11962
12075
|
/** 首页推荐(POST) */
|
|
11963
12076
|
const homeFeed$1 = (data = {}) => ({
|
|
11964
12077
|
apiPath: "/api/sns/web/v1/homefeed",
|
|
@@ -11998,6 +12111,7 @@ const noteComments$1 = (data) => {
|
|
|
11998
12111
|
const params = {
|
|
11999
12112
|
note_id: data.note_id,
|
|
12000
12113
|
cursor: data.cursor ?? "",
|
|
12114
|
+
top_comment_id: "",
|
|
12001
12115
|
image_formats: [
|
|
12002
12116
|
"jpg",
|
|
12003
12117
|
"webp",
|
|
@@ -12007,7 +12121,8 @@ const noteComments$1 = (data) => {
|
|
|
12007
12121
|
};
|
|
12008
12122
|
return {
|
|
12009
12123
|
apiPath: "/api/sns/web/v2/comment/page",
|
|
12010
|
-
Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}
|
|
12124
|
+
Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}`,
|
|
12125
|
+
signParams: params
|
|
12011
12126
|
};
|
|
12012
12127
|
};
|
|
12013
12128
|
/** 用户信息(GET,请求的是 HTML 页,由 judge / decode 层处理) */
|
|
@@ -12030,7 +12145,8 @@ const userNoteList$1 = (data) => {
|
|
|
12030
12145
|
};
|
|
12031
12146
|
return {
|
|
12032
12147
|
apiPath: "/api/sns/web/v1/user_posted",
|
|
12033
|
-
Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}
|
|
12148
|
+
Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}`,
|
|
12149
|
+
signParams: params
|
|
12034
12150
|
};
|
|
12035
12151
|
};
|
|
12036
12152
|
/** 表情列表(GET,无参数) */
|
|
@@ -12156,7 +12272,7 @@ const homeFeed = defineEndpoint({
|
|
|
12156
12272
|
signPath: apiPath
|
|
12157
12273
|
};
|
|
12158
12274
|
},
|
|
12159
|
-
sign: "xhs-post",
|
|
12275
|
+
sign: "xhs-post-rap",
|
|
12160
12276
|
response: type()
|
|
12161
12277
|
});
|
|
12162
12278
|
//#endregion
|
|
@@ -12184,14 +12300,15 @@ const noteComments = defineEndpoint({
|
|
|
12184
12300
|
number: zod.default.coerce.number().int().min(1).max(500).optional().describe("目标条数,默认一页")
|
|
12185
12301
|
}),
|
|
12186
12302
|
build: (p) => {
|
|
12187
|
-
const { Url, apiPath } = noteComments$1(p);
|
|
12303
|
+
const { Url, apiPath, signParams } = noteComments$1(p);
|
|
12188
12304
|
return {
|
|
12189
12305
|
method: "GET",
|
|
12190
12306
|
url: Url,
|
|
12191
|
-
signPath: apiPath
|
|
12307
|
+
signPath: apiPath,
|
|
12308
|
+
extra: { signParams }
|
|
12192
12309
|
};
|
|
12193
12310
|
},
|
|
12194
|
-
sign: "xhs-get",
|
|
12311
|
+
sign: "xhs-get-trace",
|
|
12195
12312
|
paginate: {
|
|
12196
12313
|
maxPageSize: 50,
|
|
12197
12314
|
items: (page) => page.data?.comments ?? [],
|
|
@@ -12241,7 +12358,7 @@ const noteDetail = defineEndpoint({
|
|
|
12241
12358
|
signPath: apiPath
|
|
12242
12359
|
};
|
|
12243
12360
|
},
|
|
12244
|
-
sign: "xhs-post",
|
|
12361
|
+
sign: "xhs-post-rap",
|
|
12245
12362
|
response: type()
|
|
12246
12363
|
});
|
|
12247
12364
|
//#endregion
|
|
@@ -12273,16 +12390,17 @@ const searchNotes = defineEndpoint({
|
|
|
12273
12390
|
signPath: apiPath
|
|
12274
12391
|
};
|
|
12275
12392
|
},
|
|
12276
|
-
sign: "xhs-post",
|
|
12393
|
+
sign: "xhs-post-rap",
|
|
12277
12394
|
response: type()
|
|
12278
12395
|
});
|
|
12279
12396
|
//#endregion
|
|
12280
12397
|
//#region src/platforms/xiaohongshu/endpoints/userNoteList.ts
|
|
12281
12398
|
/**
|
|
12282
|
-
* 用户笔记列表(GET + x-b3-traceid
|
|
12399
|
+
* 用户笔记列表(GET + x-b3-traceid,XYW_ 签名)。
|
|
12283
12400
|
*
|
|
12284
|
-
* 这个端点额外带 `x-b3-traceid`
|
|
12285
|
-
* `'xhs-get-trace'
|
|
12401
|
+
* 这个端点额外带 `x-b3-traceid` 头,且属于数据获取类接口 —— 自 2026-03 起传统
|
|
12402
|
+
* XYS_ 签名会被平台以 HTTP 406 拒绝,因此用 `'xhs-get-xyw-trace'`
|
|
12403
|
+
* (XYW_ GET 签名 + traceid),而不是给所有 GET 都换。
|
|
12286
12404
|
*/
|
|
12287
12405
|
const userNoteList = defineEndpoint({
|
|
12288
12406
|
name: "xiaohongshu.userNoteList",
|
|
@@ -12293,18 +12411,20 @@ const userNoteList = defineEndpoint({
|
|
|
12293
12411
|
},
|
|
12294
12412
|
params: zod.default.object({
|
|
12295
12413
|
user_id: zod.default.string().min(1, { error: "user_id 不能为空" }).describe("用户 ID"),
|
|
12414
|
+
xsec_token: zod.default.string().min(1, { error: "xsec_token 不能为空" }).describe("反爬令牌,随笔记分享链接下发"),
|
|
12296
12415
|
cursor: zod.default.string().optional().describe("翻页游标;传上一页最后一条的 ID,首页不传"),
|
|
12297
12416
|
num: zod.default.coerce.number().int().min(1).max(100).optional().describe("单次请求的笔记条数,默认 30")
|
|
12298
12417
|
}),
|
|
12299
12418
|
build: (p) => {
|
|
12300
|
-
const { Url, apiPath } = userNoteList$1(p);
|
|
12419
|
+
const { Url, apiPath, signParams } = userNoteList$1(p);
|
|
12301
12420
|
return {
|
|
12302
12421
|
method: "GET",
|
|
12303
12422
|
url: Url,
|
|
12304
|
-
signPath: apiPath
|
|
12423
|
+
signPath: apiPath,
|
|
12424
|
+
extra: { signParams }
|
|
12305
12425
|
};
|
|
12306
12426
|
},
|
|
12307
|
-
sign: "xhs-get-trace",
|
|
12427
|
+
sign: "xhs-get-xyw-trace",
|
|
12308
12428
|
response: type()
|
|
12309
12429
|
});
|
|
12310
12430
|
//#endregion
|
|
@@ -14155,6 +14275,21 @@ const RESPONSE_SCHEMAS = {
|
|
|
14155
14275
|
"success"
|
|
14156
14276
|
]
|
|
14157
14277
|
},
|
|
14278
|
+
"xiaohongshu_noteComments": {
|
|
14279
|
+
"type": "object",
|
|
14280
|
+
"properties": {
|
|
14281
|
+
"code": { "type": "number" },
|
|
14282
|
+
"data": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Data" },
|
|
14283
|
+
"msg": { "type": "string" },
|
|
14284
|
+
"success": { "type": "boolean" }
|
|
14285
|
+
},
|
|
14286
|
+
"required": [
|
|
14287
|
+
"code",
|
|
14288
|
+
"data",
|
|
14289
|
+
"msg",
|
|
14290
|
+
"success"
|
|
14291
|
+
]
|
|
14292
|
+
},
|
|
14158
14293
|
"xiaohongshu_noteDetail": {
|
|
14159
14294
|
"type": "object",
|
|
14160
14295
|
"properties": {
|
|
@@ -52884,6 +53019,212 @@ const RESPONSE_SCHEMAS = {
|
|
|
52884
53019
|
"properties": { "capa": { "$ref": "#/components/schemas/xiaohongshu_homeFeed.HomeFeed_V0.Capa" } },
|
|
52885
53020
|
"required": ["capa"]
|
|
52886
53021
|
},
|
|
53022
|
+
"xiaohongshu_noteComments.NoteComments_V0.AtUser": {
|
|
53023
|
+
"type": "object",
|
|
53024
|
+
"properties": {
|
|
53025
|
+
"ai_agent": { "type": "boolean" },
|
|
53026
|
+
"nickname": { "type": "string" },
|
|
53027
|
+
"user_id": { "type": "string" },
|
|
53028
|
+
"xsec_token": { "type": "string" }
|
|
53029
|
+
},
|
|
53030
|
+
"required": [
|
|
53031
|
+
"ai_agent",
|
|
53032
|
+
"nickname",
|
|
53033
|
+
"user_id",
|
|
53034
|
+
"xsec_token"
|
|
53035
|
+
]
|
|
53036
|
+
},
|
|
53037
|
+
"xiaohongshu_noteComments.NoteComments_V0.AudioInfo": {
|
|
53038
|
+
"type": "object",
|
|
53039
|
+
"properties": {
|
|
53040
|
+
"asr_text": { "type": "string" },
|
|
53041
|
+
"audio_id": { "type": "string" },
|
|
53042
|
+
"duration": { "type": "number" },
|
|
53043
|
+
"play_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.PlayInfo" },
|
|
53044
|
+
"tag_text": { "type": "string" }
|
|
53045
|
+
},
|
|
53046
|
+
"required": [
|
|
53047
|
+
"asr_text",
|
|
53048
|
+
"audio_id",
|
|
53049
|
+
"duration",
|
|
53050
|
+
"play_info",
|
|
53051
|
+
"tag_text"
|
|
53052
|
+
]
|
|
53053
|
+
},
|
|
53054
|
+
"xiaohongshu_noteComments.NoteComments_V0.Comment": {
|
|
53055
|
+
"type": "object",
|
|
53056
|
+
"properties": {
|
|
53057
|
+
"at_users": {
|
|
53058
|
+
"type": "array",
|
|
53059
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
|
|
53060
|
+
},
|
|
53061
|
+
"audio_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AudioInfo" },
|
|
53062
|
+
"content": { "type": "string" },
|
|
53063
|
+
"create_time": { "type": "number" },
|
|
53064
|
+
"id": { "type": "string" },
|
|
53065
|
+
"invalid": { "type": "boolean" },
|
|
53066
|
+
"ip_location": { "type": "string" },
|
|
53067
|
+
"like_count": { "type": "string" },
|
|
53068
|
+
"liked": { "type": "boolean" },
|
|
53069
|
+
"note_id": { "type": "string" },
|
|
53070
|
+
"pictures": {
|
|
53071
|
+
"type": "array",
|
|
53072
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
|
|
53073
|
+
},
|
|
53074
|
+
"show_tags": {
|
|
53075
|
+
"type": "array",
|
|
53076
|
+
"items": { "type": "string" }
|
|
53077
|
+
},
|
|
53078
|
+
"status": { "type": "number" },
|
|
53079
|
+
"sub_comment_count": { "type": "string" },
|
|
53080
|
+
"sub_comment_cursor": { "type": "string" },
|
|
53081
|
+
"sub_comment_has_more": { "type": "boolean" },
|
|
53082
|
+
"sub_comments": {
|
|
53083
|
+
"type": "array",
|
|
53084
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.SubComment" }
|
|
53085
|
+
},
|
|
53086
|
+
"user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
|
|
53087
|
+
},
|
|
53088
|
+
"required": [
|
|
53089
|
+
"at_users",
|
|
53090
|
+
"content",
|
|
53091
|
+
"create_time",
|
|
53092
|
+
"id",
|
|
53093
|
+
"invalid",
|
|
53094
|
+
"like_count",
|
|
53095
|
+
"liked",
|
|
53096
|
+
"note_id",
|
|
53097
|
+
"show_tags",
|
|
53098
|
+
"status",
|
|
53099
|
+
"sub_comment_count",
|
|
53100
|
+
"sub_comment_cursor",
|
|
53101
|
+
"sub_comment_has_more",
|
|
53102
|
+
"sub_comments",
|
|
53103
|
+
"user_info"
|
|
53104
|
+
]
|
|
53105
|
+
},
|
|
53106
|
+
"xiaohongshu_noteComments.NoteComments_V0.Data": {
|
|
53107
|
+
"type": "object",
|
|
53108
|
+
"properties": {
|
|
53109
|
+
"comments": {
|
|
53110
|
+
"type": "array",
|
|
53111
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Comment" }
|
|
53112
|
+
},
|
|
53113
|
+
"cursor": { "type": "string" },
|
|
53114
|
+
"has_more": { "type": "boolean" },
|
|
53115
|
+
"time": { "type": "number" },
|
|
53116
|
+
"user_id": { "type": "string" },
|
|
53117
|
+
"xsec_token": { "type": "string" }
|
|
53118
|
+
},
|
|
53119
|
+
"required": [
|
|
53120
|
+
"comments",
|
|
53121
|
+
"cursor",
|
|
53122
|
+
"has_more",
|
|
53123
|
+
"time",
|
|
53124
|
+
"user_id",
|
|
53125
|
+
"xsec_token"
|
|
53126
|
+
]
|
|
53127
|
+
},
|
|
53128
|
+
"xiaohongshu_noteComments.NoteComments_V0.InfoList": {
|
|
53129
|
+
"type": "object",
|
|
53130
|
+
"properties": {
|
|
53131
|
+
"image_scene": { "type": "string" },
|
|
53132
|
+
"url": { "type": "string" }
|
|
53133
|
+
},
|
|
53134
|
+
"required": ["image_scene", "url"]
|
|
53135
|
+
},
|
|
53136
|
+
"xiaohongshu_noteComments.NoteComments_V0.Picture": {
|
|
53137
|
+
"type": "object",
|
|
53138
|
+
"properties": {
|
|
53139
|
+
"height": { "type": "number" },
|
|
53140
|
+
"info_list": {
|
|
53141
|
+
"type": "array",
|
|
53142
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.InfoList" }
|
|
53143
|
+
},
|
|
53144
|
+
"url_default": { "type": "string" },
|
|
53145
|
+
"url_pre": { "type": "string" },
|
|
53146
|
+
"width": { "type": "number" }
|
|
53147
|
+
},
|
|
53148
|
+
"required": [
|
|
53149
|
+
"height",
|
|
53150
|
+
"info_list",
|
|
53151
|
+
"url_default",
|
|
53152
|
+
"url_pre",
|
|
53153
|
+
"width"
|
|
53154
|
+
]
|
|
53155
|
+
},
|
|
53156
|
+
"xiaohongshu_noteComments.NoteComments_V0.PlayInfo": {
|
|
53157
|
+
"type": "object",
|
|
53158
|
+
"properties": { "url": { "type": "string" } },
|
|
53159
|
+
"required": ["url"]
|
|
53160
|
+
},
|
|
53161
|
+
"xiaohongshu_noteComments.NoteComments_V0.SubComment": {
|
|
53162
|
+
"type": "object",
|
|
53163
|
+
"properties": {
|
|
53164
|
+
"at_users": {
|
|
53165
|
+
"type": "array",
|
|
53166
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
|
|
53167
|
+
},
|
|
53168
|
+
"content": { "type": "string" },
|
|
53169
|
+
"create_time": { "type": "number" },
|
|
53170
|
+
"id": { "type": "string" },
|
|
53171
|
+
"invalid": { "type": "boolean" },
|
|
53172
|
+
"ip_location": { "type": "string" },
|
|
53173
|
+
"like_count": { "type": "string" },
|
|
53174
|
+
"liked": { "type": "boolean" },
|
|
53175
|
+
"note_id": { "type": "string" },
|
|
53176
|
+
"pictures": {
|
|
53177
|
+
"type": "array",
|
|
53178
|
+
"items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
|
|
53179
|
+
},
|
|
53180
|
+
"show_tags": {
|
|
53181
|
+
"type": "array",
|
|
53182
|
+
"items": { "type": "string" }
|
|
53183
|
+
},
|
|
53184
|
+
"status": { "type": "number" },
|
|
53185
|
+
"target_comment": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.TargetComment" },
|
|
53186
|
+
"user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
|
|
53187
|
+
},
|
|
53188
|
+
"required": [
|
|
53189
|
+
"at_users",
|
|
53190
|
+
"content",
|
|
53191
|
+
"create_time",
|
|
53192
|
+
"id",
|
|
53193
|
+
"invalid",
|
|
53194
|
+
"like_count",
|
|
53195
|
+
"liked",
|
|
53196
|
+
"note_id",
|
|
53197
|
+
"show_tags",
|
|
53198
|
+
"status",
|
|
53199
|
+
"target_comment",
|
|
53200
|
+
"user_info"
|
|
53201
|
+
]
|
|
53202
|
+
},
|
|
53203
|
+
"xiaohongshu_noteComments.NoteComments_V0.TargetComment": {
|
|
53204
|
+
"type": "object",
|
|
53205
|
+
"properties": {
|
|
53206
|
+
"id": { "type": "string" },
|
|
53207
|
+
"user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
|
|
53208
|
+
},
|
|
53209
|
+
"required": ["id", "user_info"]
|
|
53210
|
+
},
|
|
53211
|
+
"xiaohongshu_noteComments.NoteComments_V0.UserInfo": {
|
|
53212
|
+
"type": "object",
|
|
53213
|
+
"properties": {
|
|
53214
|
+
"ai_agent": { "type": "boolean" },
|
|
53215
|
+
"image": { "type": "string" },
|
|
53216
|
+
"nickname": { "type": "string" },
|
|
53217
|
+
"user_id": { "type": "string" },
|
|
53218
|
+
"xsec_token": { "type": "string" }
|
|
53219
|
+
},
|
|
53220
|
+
"required": [
|
|
53221
|
+
"ai_agent",
|
|
53222
|
+
"image",
|
|
53223
|
+
"nickname",
|
|
53224
|
+
"user_id",
|
|
53225
|
+
"xsec_token"
|
|
53226
|
+
]
|
|
53227
|
+
},
|
|
52887
53228
|
"xiaohongshu_noteDetail.NoteDetail_V0.Data": {
|
|
52888
53229
|
"type": "object",
|
|
52889
53230
|
"properties": {
|
|
@@ -53679,7 +54020,7 @@ const buildOpenApiSpec = (options = {}) => {
|
|
|
53679
54020
|
openapi: "3.1.0",
|
|
53680
54021
|
info: {
|
|
53681
54022
|
title: "amagi HTTP API",
|
|
53682
|
-
version: options.version ?? "7.0.0-beta.
|
|
54023
|
+
version: options.version ?? "7.0.0-beta.2",
|
|
53683
54024
|
description: [
|
|
53684
54025
|
"由端点注册表派生的规范 —— 手写的那份已经漂移,这份不会(`gen-openapi --check` 进 CI)。",
|
|
53685
54026
|
"",
|
|
@@ -56502,7 +56843,7 @@ let DynamicType = /* @__PURE__ */ function(DynamicType) {
|
|
|
56502
56843
|
* 构建后使用 __VERSION__,开发环境从 package.json 读取
|
|
56503
56844
|
*/
|
|
56504
56845
|
const getVersion = () => {
|
|
56505
|
-
return "7.0.0-beta.
|
|
56846
|
+
return "7.0.0-beta.2";
|
|
56506
56847
|
};
|
|
56507
56848
|
const VERSION = getVersion();
|
|
56508
56849
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikenxuan/amagi",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.2",
|
|
4
4
|
"description": "抖音、B站的 web 端相关数据接口基于 Node.js 的实现",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -67,12 +67,12 @@
|
|
|
67
67
|
"registry": "https://registry.npmjs.org"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@ikenxuan/xhshow-ts": "^1.0
|
|
70
|
+
"@ikenxuan/xhshow-ts": "^1.1.0",
|
|
71
71
|
"axios": "^1.19.0",
|
|
72
72
|
"chalk": "6.0.0",
|
|
73
73
|
"express": "^5.2.1",
|
|
74
74
|
"protobufjs": "8.7.1",
|
|
75
75
|
"zod": "4.4.3"
|
|
76
76
|
},
|
|
77
|
-
"timestamp": "2026-09-
|
|
77
|
+
"timestamp": "2026-09-20T16:10:24.326Z"
|
|
78
78
|
}
|