@iflyrpa/actions 3.0.1 → 3.0.2-beta.1
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/bundle.js +1762 -770
- package/dist/bundle.js.map +1 -1
- package/dist/index.js +1981 -989
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1981 -989
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils/douyin/imageUploader.d.ts +3 -2
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -8734,9 +8734,7 @@ var __webpack_exports__ = {};
|
|
|
8734
8734
|
origin: ()=>utils_origin
|
|
8735
8735
|
});
|
|
8736
8736
|
var package_namespaceObject = JSON.parse('{"i8":"0.1.0-beta.1"}');
|
|
8737
|
-
var package_namespaceObject_0 = {
|
|
8738
|
-
i8: "3.0.0"
|
|
8739
|
-
};
|
|
8737
|
+
var package_namespaceObject_0 = JSON.parse('{"i8":"3.0.2-beta.0"}');
|
|
8740
8738
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
8741
8739
|
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
8742
8740
|
const external_node_http_namespaceObject = require("node:http");
|
|
@@ -23385,6 +23383,9 @@ var __webpack_exports__ = {};
|
|
|
23385
23383
|
case "ERR_BAD_REQUEST":
|
|
23386
23384
|
_message = "请求出现错误,请检查请求参数!";
|
|
23387
23385
|
break;
|
|
23386
|
+
case "ERR_BAD_RESPONSE":
|
|
23387
|
+
_message = `服务器响应异常 (${error.response?.status ?? "unknown"}),请稍后重试!`;
|
|
23388
|
+
break;
|
|
23388
23389
|
case "ERR_CANCELED":
|
|
23389
23390
|
errorResponse.code = 414;
|
|
23390
23391
|
_message = "请求连接超时,请稍候重试!";
|
|
@@ -23435,6 +23436,9 @@ var __webpack_exports__ = {};
|
|
|
23435
23436
|
const isRetry = [
|
|
23436
23437
|
0,
|
|
23437
23438
|
500,
|
|
23439
|
+
502,
|
|
23440
|
+
503,
|
|
23441
|
+
504,
|
|
23438
23442
|
599
|
|
23439
23443
|
].includes(handledError.code);
|
|
23440
23444
|
if (Rtimes < retries && isRetry) {
|
|
@@ -28415,7 +28419,7 @@ var __webpack_exports__ = {};
|
|
|
28415
28419
|
data: null
|
|
28416
28420
|
});
|
|
28417
28421
|
const MockPublish = false;
|
|
28418
|
-
const DisabledReq =
|
|
28422
|
+
const DisabledReq = false;
|
|
28419
28423
|
const scanRetryMaxCount = 60;
|
|
28420
28424
|
const waitQrcodeResultMaxTime = 2000 * scanRetryMaxCount;
|
|
28421
28425
|
const rpaServer = async (task, params)=>{
|
|
@@ -34213,7 +34217,7 @@ var __webpack_exports__ = {};
|
|
|
34213
34217
|
this.authCache = null;
|
|
34214
34218
|
this.authExpireTime = 0;
|
|
34215
34219
|
this.AUTH_REFRESH_BUFFER = 300000;
|
|
34216
|
-
this.CONCURRENT_LIMIT =
|
|
34220
|
+
this.CONCURRENT_LIMIT = 10;
|
|
34217
34221
|
this.UPLOAD_DELAY = 1000;
|
|
34218
34222
|
this.UPLOAD_TIMEOUT = 300000;
|
|
34219
34223
|
this.TOS_UPLOAD_TIMEOUT = 600000;
|
|
@@ -34242,16 +34246,17 @@ var __webpack_exports__ = {};
|
|
|
34242
34246
|
const aBogus = imageUploader_getABogus(`https://creator.douyin.com/web/api/media/upload/auth/v5/?${queryString}`, {}, this.headers["user-agent"]);
|
|
34243
34247
|
this.queryParams.a_bogus = aBogus;
|
|
34244
34248
|
const newQueryString = new URLSearchParams(this.queryParams).toString();
|
|
34245
|
-
const uploadAuth = await this.proxyHttp.api({
|
|
34246
|
-
|
|
34247
|
-
|
|
34248
|
-
|
|
34249
|
-
|
|
34250
|
-
|
|
34251
|
-
|
|
34252
|
-
|
|
34253
|
-
|
|
34254
|
-
|
|
34249
|
+
const uploadAuth = await this.withRetry(()=>this.proxyHttp.api({
|
|
34250
|
+
method: "get",
|
|
34251
|
+
url: `https://creator.douyin.com/web/api/media/upload/auth/v5/?${newQueryString}`,
|
|
34252
|
+
headers: {
|
|
34253
|
+
...this.headers,
|
|
34254
|
+
"Content-Type": "application/json"
|
|
34255
|
+
}
|
|
34256
|
+
}, {
|
|
34257
|
+
timeout: 300000,
|
|
34258
|
+
retries: 0
|
|
34259
|
+
}), 3, 1000, "获取上传凭证");
|
|
34255
34260
|
if (!uploadAuth.auth) throw new Error(uploadAuth.status_msg || "获取上传权限失败");
|
|
34256
34261
|
try {
|
|
34257
34262
|
const authData = JSON.parse(uploadAuth.auth);
|
|
@@ -34291,19 +34296,19 @@ var __webpack_exports__ = {};
|
|
|
34291
34296
|
};
|
|
34292
34297
|
const result = generateAuthorization(addrParamsConfig).authorization;
|
|
34293
34298
|
const addrParamsQueryString = canonicalQueryString(addrParamsConfig.params);
|
|
34294
|
-
const response = await this.proxyHttp.api({
|
|
34295
|
-
|
|
34296
|
-
|
|
34297
|
-
|
|
34298
|
-
|
|
34299
|
-
|
|
34300
|
-
|
|
34301
|
-
|
|
34302
|
-
|
|
34303
|
-
|
|
34304
|
-
|
|
34305
|
-
|
|
34306
|
-
|
|
34299
|
+
const response = await this.withRetry(()=>this.proxyHttp.api({
|
|
34300
|
+
method: "get",
|
|
34301
|
+
url: `https://imagex.bytedanceapi.com/?${addrParamsQueryString}`,
|
|
34302
|
+
headers: {
|
|
34303
|
+
...this.headers,
|
|
34304
|
+
Authorization: result,
|
|
34305
|
+
"Content-Type": "application/json",
|
|
34306
|
+
"X-amz-date": amzDate,
|
|
34307
|
+
"X-amz-security-token": authData.SessionToken
|
|
34308
|
+
}
|
|
34309
|
+
}, {
|
|
34310
|
+
timeout: this.UPLOAD_TIMEOUT
|
|
34311
|
+
}), 3, 1000, "获取上传地址");
|
|
34307
34312
|
if (!response) throw new Error("获取上传地址失败: 响应为空");
|
|
34308
34313
|
if (response.ResponseMetadata?.Error) throw new Error(`ImageX错误: ${response.ResponseMetadata.Error.Code} - ${response.ResponseMetadata.Error.Message}`);
|
|
34309
34314
|
if (!response.Result) {
|
|
@@ -34334,23 +34339,24 @@ var __webpack_exports__ = {};
|
|
|
34334
34339
|
console.log(`上传至: ${uploadUrl.substring(0, 80)}...`);
|
|
34335
34340
|
console.log(`文件大小: ${imageInfo.size} bytes, CRC32: ${imageInfo.md5}`);
|
|
34336
34341
|
try {
|
|
34337
|
-
const uploadImgResp = await this.proxyHttp.api({
|
|
34338
|
-
|
|
34339
|
-
|
|
34340
|
-
|
|
34341
|
-
|
|
34342
|
-
|
|
34343
|
-
|
|
34344
|
-
|
|
34345
|
-
|
|
34346
|
-
|
|
34347
|
-
|
|
34348
|
-
|
|
34349
|
-
|
|
34350
|
-
|
|
34351
|
-
|
|
34352
|
-
|
|
34353
|
-
|
|
34342
|
+
const uploadImgResp = await this.withRetry(()=>this.proxyHttp.api({
|
|
34343
|
+
method: "post",
|
|
34344
|
+
url: uploadUrl,
|
|
34345
|
+
headers: {
|
|
34346
|
+
...this.headers,
|
|
34347
|
+
Authorization: uploadAddr.auth,
|
|
34348
|
+
"Content-crc32": imageInfo.md5,
|
|
34349
|
+
"Content-Type": "application/octet-stream",
|
|
34350
|
+
"Content-Length": imageInfo.size.toString()
|
|
34351
|
+
},
|
|
34352
|
+
data: fileBuffer,
|
|
34353
|
+
httpAgent: this.uploadAgent,
|
|
34354
|
+
httpsAgent: this.uploadAgent,
|
|
34355
|
+
maxBodyLength: 1 / 0,
|
|
34356
|
+
maxContentLength: 1 / 0
|
|
34357
|
+
}, {
|
|
34358
|
+
timeout: this.TOS_UPLOAD_TIMEOUT
|
|
34359
|
+
}), 5, 3000, "TOS上传");
|
|
34354
34360
|
console.log("TOS 上传响应:", uploadImgResp);
|
|
34355
34361
|
const isSuccess = uploadImgResp && (2000 === uploadImgResp.code || 200 === uploadImgResp.status || 200 === uploadImgResp.statusCode || uploadImgResp.data && uploadImgResp.data.crc32 || "Success" === uploadImgResp.message);
|
|
34356
34362
|
if (!isSuccess) throw new Error(`上传失败: ${JSON.stringify(uploadImgResp)}`);
|
|
@@ -34371,20 +34377,22 @@ var __webpack_exports__ = {};
|
|
|
34371
34377
|
async processSingleImage(imageUrl, index, total) {
|
|
34372
34378
|
console.log(`\n[${index + 1}/${total}] 处理图片: ${imageUrl.substring(0, 50)}...`);
|
|
34373
34379
|
const fileName = getFilenameFromUrl(imageUrl);
|
|
34374
|
-
const localPath = external_node_path_default().
|
|
34380
|
+
const localPath = external_node_path_default().resolve(this.tmpCachePath, fileName);
|
|
34375
34381
|
try {
|
|
34376
34382
|
await downloadImage(imageUrl, localPath);
|
|
34377
34383
|
console.log(`图片下载完成: ${localPath}`);
|
|
34384
|
+
const imageInfo = await this.getImageInfo(localPath);
|
|
34385
|
+
console.log(`图片信息: ${imageInfo.width}x${imageInfo.height}, ${imageInfo.size} bytes`);
|
|
34386
|
+
const auth = await this.getValidAuth();
|
|
34387
|
+
const uploadAddr = await this.getUploadAddress(auth);
|
|
34388
|
+
const result = await this.uploadToTOS(imageInfo, uploadAddr);
|
|
34389
|
+
this.safeDeleteFile(localPath);
|
|
34390
|
+
return result;
|
|
34378
34391
|
} catch (error) {
|
|
34379
|
-
|
|
34380
|
-
|
|
34381
|
-
|
|
34382
|
-
|
|
34383
|
-
const auth = await this.getValidAuth();
|
|
34384
|
-
const uploadAddr = await this.getUploadAddress(auth);
|
|
34385
|
-
const result = await this.uploadToTOS(imageInfo, uploadAddr);
|
|
34386
|
-
this.safeDeleteFile(localPath);
|
|
34387
|
-
return result;
|
|
34392
|
+
console.error(`[${index + 1}/${total}] 图片上传失败,已跳过: ${imageUrl}`, error?.message ?? error);
|
|
34393
|
+
this.safeDeleteFile(localPath);
|
|
34394
|
+
return null;
|
|
34395
|
+
}
|
|
34388
34396
|
}
|
|
34389
34397
|
async getImageInfo(localPath) {
|
|
34390
34398
|
const stats = external_node_fs_default().statSync(localPath);
|
|
@@ -34417,13 +34425,11 @@ var __webpack_exports__ = {};
|
|
|
34417
34425
|
const globalIndex = i + idx;
|
|
34418
34426
|
return this.processSingleImage(url, globalIndex, total);
|
|
34419
34427
|
});
|
|
34420
|
-
|
|
34421
|
-
|
|
34422
|
-
|
|
34423
|
-
|
|
34424
|
-
|
|
34425
|
-
throw error;
|
|
34426
|
-
}
|
|
34428
|
+
const batchResults = await Promise.all(batchPromises);
|
|
34429
|
+
const successResults = batchResults.filter((r)=>null !== r);
|
|
34430
|
+
results.push(...successResults);
|
|
34431
|
+
const failedCount = batchResults.length - successResults.length;
|
|
34432
|
+
if (failedCount > 0) console.warn(`批次 ${batchIndex} 中有 ${failedCount} 张图片上传失败`);
|
|
34427
34433
|
if (i + this.CONCURRENT_LIMIT < total) {
|
|
34428
34434
|
console.log(`等待 ${this.UPLOAD_DELAY}ms...`);
|
|
34429
34435
|
await this.delay(this.UPLOAD_DELAY);
|
|
@@ -34435,6 +34441,7 @@ var __webpack_exports__ = {};
|
|
|
34435
34441
|
async uploadCover(coverUrl) {
|
|
34436
34442
|
console.log("\n========== 上传封面 ==========\n");
|
|
34437
34443
|
const result = await this.processSingleImage(coverUrl, 0, 1);
|
|
34444
|
+
if (!result) console.error(`封面图上传失败,已跳过: ${coverUrl}`);
|
|
34438
34445
|
return result;
|
|
34439
34446
|
}
|
|
34440
34447
|
safeDeleteFile(filePath) {
|
|
@@ -34448,6 +34455,17 @@ var __webpack_exports__ = {};
|
|
|
34448
34455
|
delay(ms) {
|
|
34449
34456
|
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
34450
34457
|
}
|
|
34458
|
+
async withRetry(fn, retries = 3, delayMs = 1000, label = "") {
|
|
34459
|
+
for(let attempt = 1; attempt <= retries; attempt++)try {
|
|
34460
|
+
return await fn();
|
|
34461
|
+
} catch (err) {
|
|
34462
|
+
if (attempt === retries) throw err;
|
|
34463
|
+
const waitTime = delayMs * attempt;
|
|
34464
|
+
console.warn(`${label} 第 ${attempt} 次失败,${waitTime}ms 后重试:`, err?.message ?? err);
|
|
34465
|
+
await this.delay(waitTime);
|
|
34466
|
+
}
|
|
34467
|
+
throw new Error("unreachable");
|
|
34468
|
+
}
|
|
34451
34469
|
destroy() {
|
|
34452
34470
|
this.uploadAgent.destroy();
|
|
34453
34471
|
}
|
|
@@ -34644,14 +34662,16 @@ var __webpack_exports__ = {};
|
|
|
34644
34662
|
const uploader = new DouyinImageUploader(proxyHttp, headers, publishParams, tmpCachePath);
|
|
34645
34663
|
if (params.coverImage) {
|
|
34646
34664
|
const cover = await uploader.uploadCover(params.coverImage);
|
|
34647
|
-
|
|
34648
|
-
|
|
34649
|
-
|
|
34650
|
-
|
|
34651
|
-
|
|
34652
|
-
|
|
34653
|
-
|
|
34654
|
-
|
|
34665
|
+
if (cover) {
|
|
34666
|
+
publishData.item.common.images.push({
|
|
34667
|
+
uri: cover.uri,
|
|
34668
|
+
width: cover.width,
|
|
34669
|
+
height: cover.height
|
|
34670
|
+
});
|
|
34671
|
+
publishData.item.cover = {
|
|
34672
|
+
poster: cover.uri
|
|
34673
|
+
};
|
|
34674
|
+
}
|
|
34655
34675
|
}
|
|
34656
34676
|
if (params.banners && params.banners.length > 0) {
|
|
34657
34677
|
const banners = params.banners.filter((i)=>i !== params.coverImage);
|
|
@@ -34677,11 +34697,15 @@ var __webpack_exports__ = {};
|
|
|
34677
34697
|
}
|
|
34678
34698
|
if (!response || !response.data) return;
|
|
34679
34699
|
const responseData = response.data;
|
|
34680
|
-
if (response && responseData?.status_code && 0 !== responseData.status_code)
|
|
34681
|
-
|
|
34682
|
-
|
|
34683
|
-
|
|
34684
|
-
|
|
34700
|
+
if (response && responseData?.status_code && 0 !== responseData.status_code) {
|
|
34701
|
+
const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
|
|
34702
|
+
if (4 === responseData.status_code) task.logger.warn(`抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
|
|
34703
|
+
return {
|
|
34704
|
+
code: errorCode,
|
|
34705
|
+
message: responseData.status_msg || "文章发布异常,请稍后重试。",
|
|
34706
|
+
data: responseData
|
|
34707
|
+
};
|
|
34708
|
+
}
|
|
34685
34709
|
});
|
|
34686
34710
|
task._timerRecord.PrePublish = Date.now();
|
|
34687
34711
|
if (MockPublish) {
|
|
@@ -34764,7 +34788,9 @@ var __webpack_exports__ = {};
|
|
|
34764
34788
|
"x-tt-session-dtrait": sessionDtrait || ""
|
|
34765
34789
|
}
|
|
34766
34790
|
}, {
|
|
34767
|
-
timeout: 60000
|
|
34791
|
+
timeout: 60000,
|
|
34792
|
+
retries: 3,
|
|
34793
|
+
retryDelay: 2000
|
|
34768
34794
|
});
|
|
34769
34795
|
reportLogger({
|
|
34770
34796
|
token: params.huiwenToken || "",
|
|
@@ -34777,9 +34803,8 @@ var __webpack_exports__ = {};
|
|
|
34777
34803
|
platform: "douyin",
|
|
34778
34804
|
publishParams: publishData
|
|
34779
34805
|
});
|
|
34780
|
-
|
|
34781
|
-
task.logger.warn(
|
|
34782
|
-
task.logger.warn(JSON.stringify(publishData));
|
|
34806
|
+
task.logger.warn("发布结果");
|
|
34807
|
+
task.logger.warn(JSON.stringify(publishResult));
|
|
34783
34808
|
const isSuccess = 0 === publishResult.status_code;
|
|
34784
34809
|
const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
34785
34810
|
const data = isSuccess ? publishResult.item_id || "" : "";
|
|
@@ -43471,291 +43496,6 @@ var __webpack_exports__ = {};
|
|
|
43471
43496
|
if ("server" === params.actionType) return xiaohongshuLogin_rpa_server_rpaServer(task, params);
|
|
43472
43497
|
return executeAction(xiaohongshuLogin_rpa_rpaAction)(task, params);
|
|
43473
43498
|
};
|
|
43474
|
-
const FictionalRendition = classic_schemas_object({
|
|
43475
|
-
type: literal("fictional-rendition")
|
|
43476
|
-
});
|
|
43477
|
-
const AIGenerated = classic_schemas_object({
|
|
43478
|
-
type: literal("ai-generated")
|
|
43479
|
-
});
|
|
43480
|
-
const SourceStatement = classic_schemas_object({
|
|
43481
|
-
type: literal("source-statement"),
|
|
43482
|
-
childType: classic_schemas_enum([
|
|
43483
|
-
"self-labeling",
|
|
43484
|
-
"self-shooting",
|
|
43485
|
-
"transshipment"
|
|
43486
|
-
]),
|
|
43487
|
-
shootingLocation: custom().optional(),
|
|
43488
|
-
shootingDate: classic_schemas_string().optional(),
|
|
43489
|
-
sourceMedia: classic_schemas_string().optional()
|
|
43490
|
-
});
|
|
43491
|
-
schemas_union([
|
|
43492
|
-
FictionalRendition,
|
|
43493
|
-
AIGenerated,
|
|
43494
|
-
SourceStatement
|
|
43495
|
-
]);
|
|
43496
|
-
const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
|
|
43497
|
-
banners: classic_schemas_array(classic_schemas_string()),
|
|
43498
|
-
title: classic_schemas_string(),
|
|
43499
|
-
content: classic_schemas_string(),
|
|
43500
|
-
address: custom().optional(),
|
|
43501
|
-
selfDeclaration: custom().optional(),
|
|
43502
|
-
topic: classic_schemas_array(custom()).optional(),
|
|
43503
|
-
proxyLoc: classic_schemas_string().optional(),
|
|
43504
|
-
localIP: classic_schemas_string().optional(),
|
|
43505
|
-
huiwenToken: classic_schemas_string().optional(),
|
|
43506
|
-
visibleRange: classic_schemas_enum([
|
|
43507
|
-
"public",
|
|
43508
|
-
"private",
|
|
43509
|
-
"friends"
|
|
43510
|
-
]),
|
|
43511
|
-
isImmediatelyPublish: classic_schemas_boolean().optional(),
|
|
43512
|
-
scheduledPublish: classic_schemas_string().optional(),
|
|
43513
|
-
collectionId: classic_schemas_string().optional(),
|
|
43514
|
-
collectionBind: custom().optional(),
|
|
43515
|
-
groupBind: custom().optional(),
|
|
43516
|
-
noteCopyBind: classic_schemas_boolean().optional(),
|
|
43517
|
-
coProduceBind: classic_schemas_boolean().optional(),
|
|
43518
|
-
originalBind: classic_schemas_boolean().optional()
|
|
43519
|
-
});
|
|
43520
|
-
const xiaohongshuPublish = async (_task, _params)=>({
|
|
43521
|
-
code: 414,
|
|
43522
|
-
data: "",
|
|
43523
|
-
message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
|
|
43524
|
-
});
|
|
43525
|
-
const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
|
|
43526
|
-
const xiaohongshuWebCommentAction = async (_task, params)=>{
|
|
43527
|
-
if (DisabledReq) return utils_response(414, "点赞相关操作失败", {});
|
|
43528
|
-
const headers = {
|
|
43529
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43530
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43531
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43532
|
-
};
|
|
43533
|
-
const args = [
|
|
43534
|
-
{
|
|
43535
|
-
headers
|
|
43536
|
-
},
|
|
43537
|
-
_task.logger,
|
|
43538
|
-
params.proxyLoc,
|
|
43539
|
-
params.localIP,
|
|
43540
|
-
params.accountId
|
|
43541
|
-
];
|
|
43542
|
-
const http = new Http(...args);
|
|
43543
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
43544
|
-
if (!a1Cookie) return {
|
|
43545
|
-
code: 414,
|
|
43546
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
43547
|
-
data: []
|
|
43548
|
-
};
|
|
43549
|
-
if (!params.note_id && !params.comment_id && !params.action) return {
|
|
43550
|
-
code: 414,
|
|
43551
|
-
message: "参数缺失,请检查后重试!",
|
|
43552
|
-
data: {}
|
|
43553
|
-
};
|
|
43554
|
-
const actionParams = {
|
|
43555
|
-
note_id: params.note_id,
|
|
43556
|
-
comment_id: params.comment_id
|
|
43557
|
-
};
|
|
43558
|
-
let likeActionRes = {
|
|
43559
|
-
code: 500,
|
|
43560
|
-
success: false,
|
|
43561
|
-
msg: ""
|
|
43562
|
-
};
|
|
43563
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
43564
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
43565
|
-
return acc;
|
|
43566
|
-
}, {});
|
|
43567
|
-
switch(params.action){
|
|
43568
|
-
case "like":
|
|
43569
|
-
{
|
|
43570
|
-
const likeAction = "/api/sns/web/v1/comment/like";
|
|
43571
|
-
const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
|
|
43572
|
-
likeActionRes = await http.api({
|
|
43573
|
-
method: "post",
|
|
43574
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
|
|
43575
|
-
data: actionParams,
|
|
43576
|
-
headers: likeActionXsHeader
|
|
43577
|
-
}, {
|
|
43578
|
-
retries: 3,
|
|
43579
|
-
retryDelay: 20,
|
|
43580
|
-
timeout: 3000
|
|
43581
|
-
});
|
|
43582
|
-
break;
|
|
43583
|
-
}
|
|
43584
|
-
case "dislike":
|
|
43585
|
-
{
|
|
43586
|
-
const dislikeMentions = "/api/sns/web/v1/comment/dislike";
|
|
43587
|
-
const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
|
|
43588
|
-
likeActionRes = await http.api({
|
|
43589
|
-
method: "post",
|
|
43590
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
|
|
43591
|
-
data: actionParams,
|
|
43592
|
-
headers: dislikeXsHeader
|
|
43593
|
-
}, {
|
|
43594
|
-
retries: 3,
|
|
43595
|
-
retryDelay: 20,
|
|
43596
|
-
timeout: 3000
|
|
43597
|
-
});
|
|
43598
|
-
break;
|
|
43599
|
-
}
|
|
43600
|
-
default:
|
|
43601
|
-
return {
|
|
43602
|
-
code: 414,
|
|
43603
|
-
message: "参数action错误,请重试!",
|
|
43604
|
-
data: {}
|
|
43605
|
-
};
|
|
43606
|
-
}
|
|
43607
|
-
const isSuccess = 0 === likeActionRes.code;
|
|
43608
|
-
const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43609
|
-
const data = isSuccess ? likeActionRes.success : {};
|
|
43610
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43611
|
-
};
|
|
43612
|
-
const xiaohongshuWebIntimacySearch = async (_task, params)=>{
|
|
43613
|
-
if (DisabledReq) return utils_response(0, "搜索@列表数据成功", []);
|
|
43614
|
-
const headers = {
|
|
43615
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43616
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43617
|
-
origin: "https://www.xiaohongshu.com"
|
|
43618
|
-
};
|
|
43619
|
-
const args = [
|
|
43620
|
-
{
|
|
43621
|
-
headers
|
|
43622
|
-
},
|
|
43623
|
-
_task.logger,
|
|
43624
|
-
params.proxyLoc,
|
|
43625
|
-
params.localIP,
|
|
43626
|
-
params.accountId
|
|
43627
|
-
];
|
|
43628
|
-
const http = new Http(...args);
|
|
43629
|
-
let intimacyDetail = [];
|
|
43630
|
-
const res = await http.api({
|
|
43631
|
-
method: "get",
|
|
43632
|
-
url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
|
|
43633
|
-
...params.searchValue ? {
|
|
43634
|
-
params: {
|
|
43635
|
-
keyword: params.searchValue,
|
|
43636
|
-
page: 1,
|
|
43637
|
-
rows: 30
|
|
43638
|
-
}
|
|
43639
|
-
} : {}
|
|
43640
|
-
}, {
|
|
43641
|
-
retries: 3,
|
|
43642
|
-
retryDelay: 20,
|
|
43643
|
-
timeout: 3000
|
|
43644
|
-
});
|
|
43645
|
-
const isSuccess = 0 === res.code;
|
|
43646
|
-
if (isSuccess) intimacyDetail = res.data.items;
|
|
43647
|
-
const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43648
|
-
return utils_response(isSuccess ? 0 : 414, message, intimacyDetail);
|
|
43649
|
-
};
|
|
43650
|
-
const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
|
|
43651
|
-
const xiaohongshuWebMsgRead = async (_task, params)=>{
|
|
43652
|
-
if (DisabledReq) return utils_response(414, "Read指定Tab失败", {});
|
|
43653
|
-
const headers = {
|
|
43654
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43655
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43656
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43657
|
-
};
|
|
43658
|
-
const args = [
|
|
43659
|
-
{
|
|
43660
|
-
headers
|
|
43661
|
-
},
|
|
43662
|
-
_task.logger,
|
|
43663
|
-
params.proxyLoc,
|
|
43664
|
-
params.localIP,
|
|
43665
|
-
params.accountId
|
|
43666
|
-
];
|
|
43667
|
-
const http = new Http(...args);
|
|
43668
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
43669
|
-
if (!a1Cookie) return {
|
|
43670
|
-
code: 414,
|
|
43671
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
43672
|
-
data: []
|
|
43673
|
-
};
|
|
43674
|
-
if (!params.type) return {
|
|
43675
|
-
code: 414,
|
|
43676
|
-
message: "参数缺失,请检查后重试!",
|
|
43677
|
-
data: {}
|
|
43678
|
-
};
|
|
43679
|
-
const replyParams = {
|
|
43680
|
-
type: params.type
|
|
43681
|
-
};
|
|
43682
|
-
const fatchMentions = "/api/sns/web/v1/message/read";
|
|
43683
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
43684
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
43685
|
-
return acc;
|
|
43686
|
-
}, {});
|
|
43687
|
-
const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
|
|
43688
|
-
const res = await http.api({
|
|
43689
|
-
method: "post",
|
|
43690
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
|
|
43691
|
-
data: replyParams,
|
|
43692
|
-
headers: fatchMentionsXsHeader
|
|
43693
|
-
}, {
|
|
43694
|
-
retries: 3,
|
|
43695
|
-
retryDelay: 20,
|
|
43696
|
-
timeout: 3000
|
|
43697
|
-
});
|
|
43698
|
-
const isSuccess = 0 === res.code;
|
|
43699
|
-
const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43700
|
-
const data = isSuccess ? res.success : {};
|
|
43701
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43702
|
-
};
|
|
43703
|
-
const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
|
|
43704
|
-
const xiaohongshuWebMsgReply = async (_task, params)=>{
|
|
43705
|
-
if (DisabledReq) return utils_response(414, "评论回复失败", {});
|
|
43706
|
-
const headers = {
|
|
43707
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43708
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43709
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43710
|
-
};
|
|
43711
|
-
const args = [
|
|
43712
|
-
{
|
|
43713
|
-
headers
|
|
43714
|
-
},
|
|
43715
|
-
_task.logger,
|
|
43716
|
-
params.proxyLoc,
|
|
43717
|
-
params.localIP,
|
|
43718
|
-
params.accountId
|
|
43719
|
-
];
|
|
43720
|
-
const http = new Http(...args);
|
|
43721
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
43722
|
-
if (!a1Cookie) return {
|
|
43723
|
-
code: 414,
|
|
43724
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
43725
|
-
data: []
|
|
43726
|
-
};
|
|
43727
|
-
if (!params.note_id || !params.target_comment_id || !params.content) return {
|
|
43728
|
-
code: 414,
|
|
43729
|
-
message: "参数缺失,请检查后重试!",
|
|
43730
|
-
data: {}
|
|
43731
|
-
};
|
|
43732
|
-
const replyParams = {
|
|
43733
|
-
at_users: params.at_users ?? [],
|
|
43734
|
-
content: params.content,
|
|
43735
|
-
note_id: params.note_id,
|
|
43736
|
-
target_comment_id: params.target_comment_id
|
|
43737
|
-
};
|
|
43738
|
-
const replyPath = "/api/sns/web/v1/comment/post";
|
|
43739
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
43740
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
43741
|
-
return acc;
|
|
43742
|
-
}, {});
|
|
43743
|
-
const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
|
|
43744
|
-
const res = await http.api({
|
|
43745
|
-
method: "post",
|
|
43746
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
|
|
43747
|
-
data: replyParams,
|
|
43748
|
-
headers: replyXsHeader
|
|
43749
|
-
}, {
|
|
43750
|
-
retries: 3,
|
|
43751
|
-
retryDelay: 20,
|
|
43752
|
-
timeout: 3000
|
|
43753
|
-
});
|
|
43754
|
-
const isSuccess = 0 === res.code;
|
|
43755
|
-
const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43756
|
-
const data = isSuccess ? res.data : {};
|
|
43757
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43758
|
-
};
|
|
43759
43499
|
let _windowCache = null;
|
|
43760
43500
|
const getWindow = ()=>{
|
|
43761
43501
|
if (_windowCache) return _windowCache;
|
|
@@ -43811,336 +43551,7 @@ var __webpack_exports__ = {};
|
|
|
43811
43551
|
};
|
|
43812
43552
|
}
|
|
43813
43553
|
}
|
|
43814
|
-
const
|
|
43815
|
-
const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
|
|
43816
|
-
const xiaohongshuWebNoteFeed = async (_task, params)=>{
|
|
43817
|
-
if (DisabledReq) return utils_response(414, "获取指定文章详情失败", {});
|
|
43818
|
-
const headers = {
|
|
43819
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43820
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43821
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43822
|
-
};
|
|
43823
|
-
const args = [
|
|
43824
|
-
{
|
|
43825
|
-
headers
|
|
43826
|
-
},
|
|
43827
|
-
_task.logger,
|
|
43828
|
-
params.proxyLoc,
|
|
43829
|
-
params.localIP,
|
|
43830
|
-
params.accountId
|
|
43831
|
-
];
|
|
43832
|
-
const http = new Http(...args);
|
|
43833
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
43834
|
-
if (!a1Cookie) return {
|
|
43835
|
-
code: 414,
|
|
43836
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
43837
|
-
data: {}
|
|
43838
|
-
};
|
|
43839
|
-
if (!params.source_note_id && !params.xsec_token) return {
|
|
43840
|
-
code: 414,
|
|
43841
|
-
message: "参数缺失,请检查后重试!",
|
|
43842
|
-
data: {}
|
|
43843
|
-
};
|
|
43844
|
-
const feedParams = {
|
|
43845
|
-
source_note_id: params.source_note_id,
|
|
43846
|
-
image_formats: [
|
|
43847
|
-
"jpg",
|
|
43848
|
-
"webp",
|
|
43849
|
-
"avif"
|
|
43850
|
-
],
|
|
43851
|
-
extra: {
|
|
43852
|
-
need_body_topic: "1"
|
|
43853
|
-
},
|
|
43854
|
-
xsec_source: "pc_feed",
|
|
43855
|
-
xsec_token: params.xsec_token
|
|
43856
|
-
};
|
|
43857
|
-
const fatchFeed = "/api/sns/web/v1/feed";
|
|
43858
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
43859
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
43860
|
-
return acc;
|
|
43861
|
-
}, {});
|
|
43862
|
-
const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
|
|
43863
|
-
const xT = Date.now().toString();
|
|
43864
|
-
const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
|
|
43865
|
-
_task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
|
|
43866
|
-
_task.logger.info(`X-S: ${xsHeader["X-S"]}`);
|
|
43867
|
-
_task.logger.info(`x-s-common: ${xsCommon}`);
|
|
43868
|
-
const res = await http.api({
|
|
43869
|
-
method: "post",
|
|
43870
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
|
|
43871
|
-
data: feedParams,
|
|
43872
|
-
headers: {
|
|
43873
|
-
"X-S": xsHeader["X-S"],
|
|
43874
|
-
"X-S-Common": xsCommon,
|
|
43875
|
-
"X-T": xT
|
|
43876
|
-
}
|
|
43877
|
-
}, {
|
|
43878
|
-
retries: 3,
|
|
43879
|
-
retryDelay: 20,
|
|
43880
|
-
timeout: 3000
|
|
43881
|
-
});
|
|
43882
|
-
_task.logger.info(`API 响应: ${JSON.stringify(res)}`);
|
|
43883
|
-
const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
|
|
43884
|
-
const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43885
|
-
const data = isSuccess ? res.data?.items[0].note_card || {} : {};
|
|
43886
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43887
|
-
};
|
|
43888
|
-
const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
|
|
43889
|
-
const xiaohongshuWebRelationAction = async (_task, params)=>{
|
|
43890
|
-
if (DisabledReq) return utils_response(414, "用户关系操作失败", {});
|
|
43891
|
-
const headers = {
|
|
43892
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43893
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43894
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43895
|
-
};
|
|
43896
|
-
const args = [
|
|
43897
|
-
{
|
|
43898
|
-
headers
|
|
43899
|
-
},
|
|
43900
|
-
_task.logger,
|
|
43901
|
-
params.proxyLoc,
|
|
43902
|
-
params.localIP,
|
|
43903
|
-
params.accountId
|
|
43904
|
-
];
|
|
43905
|
-
const http = new Http(...args);
|
|
43906
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
43907
|
-
if (!a1Cookie) return {
|
|
43908
|
-
code: 414,
|
|
43909
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
43910
|
-
data: {}
|
|
43911
|
-
};
|
|
43912
|
-
if (!params.action || !params.target_user_id) return {
|
|
43913
|
-
code: 414,
|
|
43914
|
-
message: "参数缺失,请检查后重试!",
|
|
43915
|
-
data: {}
|
|
43916
|
-
};
|
|
43917
|
-
const relationParams = {
|
|
43918
|
-
target_user_id: params.target_user_id
|
|
43919
|
-
};
|
|
43920
|
-
let relationActionRes;
|
|
43921
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
43922
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
43923
|
-
return acc;
|
|
43924
|
-
}, {});
|
|
43925
|
-
switch(params.action){
|
|
43926
|
-
case "follow":
|
|
43927
|
-
{
|
|
43928
|
-
const followMentions = "/api/sns/web/v1/user/follow";
|
|
43929
|
-
const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
|
|
43930
|
-
relationActionRes = await http.api({
|
|
43931
|
-
method: "post",
|
|
43932
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
|
|
43933
|
-
data: relationParams,
|
|
43934
|
-
headers: followXsHeader
|
|
43935
|
-
}, {
|
|
43936
|
-
retries: 3,
|
|
43937
|
-
retryDelay: 500,
|
|
43938
|
-
timeout: 3000
|
|
43939
|
-
});
|
|
43940
|
-
break;
|
|
43941
|
-
}
|
|
43942
|
-
case "unfollow":
|
|
43943
|
-
{
|
|
43944
|
-
const unfllowMentions = "/api/sns/web/v1/user/unfollow";
|
|
43945
|
-
const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
|
|
43946
|
-
relationActionRes = await http.api({
|
|
43947
|
-
method: "post",
|
|
43948
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
|
|
43949
|
-
data: relationParams,
|
|
43950
|
-
headers: unfllowXsHeader
|
|
43951
|
-
}, {
|
|
43952
|
-
retries: 3,
|
|
43953
|
-
retryDelay: 20,
|
|
43954
|
-
timeout: 3000
|
|
43955
|
-
});
|
|
43956
|
-
break;
|
|
43957
|
-
}
|
|
43958
|
-
default:
|
|
43959
|
-
return {
|
|
43960
|
-
code: 414,
|
|
43961
|
-
message: "参数action错误,请重试!",
|
|
43962
|
-
data: {}
|
|
43963
|
-
};
|
|
43964
|
-
}
|
|
43965
|
-
const isSuccess = 0 === relationActionRes.code;
|
|
43966
|
-
const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
43967
|
-
const data = isSuccess ? relationActionRes.data : {
|
|
43968
|
-
fstatus: null
|
|
43969
|
-
};
|
|
43970
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43971
|
-
};
|
|
43972
|
-
const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
|
|
43973
|
-
const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
|
|
43974
|
-
keyword: classic_schemas_string(),
|
|
43975
|
-
page: classic_schemas_number(),
|
|
43976
|
-
page_size: classic_schemas_number(),
|
|
43977
|
-
sort_type: classic_schemas_enum([
|
|
43978
|
-
"general",
|
|
43979
|
-
"time_descending",
|
|
43980
|
-
"popular_descending"
|
|
43981
|
-
]),
|
|
43982
|
-
time_filter: classic_schemas_enum([
|
|
43983
|
-
"不限",
|
|
43984
|
-
"一周内"
|
|
43985
|
-
])
|
|
43986
|
-
});
|
|
43987
|
-
const createSearchId = ()=>{
|
|
43988
|
-
let r = BigInt(Date.now());
|
|
43989
|
-
const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
|
|
43990
|
-
r <<= BigInt(64);
|
|
43991
|
-
r += o;
|
|
43992
|
-
return r.toString(36);
|
|
43993
|
-
};
|
|
43994
|
-
const xiaohongshuWebSearch = async (_task, params)=>{
|
|
43995
|
-
const headers = {
|
|
43996
|
-
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
43997
|
-
referer: "https://www.xiaohongshu.com/",
|
|
43998
|
-
origin: "https://www.xiaohongshu.com/"
|
|
43999
|
-
};
|
|
44000
|
-
const args = [
|
|
44001
|
-
{
|
|
44002
|
-
headers
|
|
44003
|
-
},
|
|
44004
|
-
_task.logger,
|
|
44005
|
-
params.proxyLoc,
|
|
44006
|
-
params.localIP,
|
|
44007
|
-
params.accountId
|
|
44008
|
-
];
|
|
44009
|
-
const http = new Http(...args);
|
|
44010
|
-
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
44011
|
-
if (!a1Cookie) return {
|
|
44012
|
-
code: 414,
|
|
44013
|
-
message: "账号数据异常,请重新绑定账号后重试。",
|
|
44014
|
-
data: {}
|
|
44015
|
-
};
|
|
44016
|
-
if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
|
|
44017
|
-
if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
|
|
44018
|
-
code: 414,
|
|
44019
|
-
message: "排序类型参数错误,请检查后重试!",
|
|
44020
|
-
data: {}
|
|
44021
|
-
};
|
|
44022
|
-
if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
|
|
44023
|
-
code: 414,
|
|
44024
|
-
message: "时间过滤参数错误,请检查后重试!",
|
|
44025
|
-
data: {}
|
|
44026
|
-
};
|
|
44027
|
-
return {
|
|
44028
|
-
code: 414,
|
|
44029
|
-
message: "参数缺失,请检查后重试!",
|
|
44030
|
-
data: {}
|
|
44031
|
-
};
|
|
44032
|
-
}
|
|
44033
|
-
const filterPath = "/api/sns/web/v1/search/notes";
|
|
44034
|
-
const filterParams = {
|
|
44035
|
-
ext_flags: [],
|
|
44036
|
-
geo: "",
|
|
44037
|
-
image_formats: [
|
|
44038
|
-
"jpg",
|
|
44039
|
-
"webp",
|
|
44040
|
-
"avif"
|
|
44041
|
-
],
|
|
44042
|
-
filters: [
|
|
44043
|
-
{
|
|
44044
|
-
tags: [
|
|
44045
|
-
params.sort_type
|
|
44046
|
-
],
|
|
44047
|
-
type: "sort_type"
|
|
44048
|
-
},
|
|
44049
|
-
{
|
|
44050
|
-
tags: [
|
|
44051
|
-
"不限"
|
|
44052
|
-
],
|
|
44053
|
-
type: "filter_note_type"
|
|
44054
|
-
},
|
|
44055
|
-
{
|
|
44056
|
-
tags: [
|
|
44057
|
-
params.time_filter
|
|
44058
|
-
],
|
|
44059
|
-
type: "filter_note_time"
|
|
44060
|
-
},
|
|
44061
|
-
{
|
|
44062
|
-
tags: [
|
|
44063
|
-
"不限"
|
|
44064
|
-
],
|
|
44065
|
-
type: "filter_note_range"
|
|
44066
|
-
},
|
|
44067
|
-
{
|
|
44068
|
-
tags: [
|
|
44069
|
-
"不限"
|
|
44070
|
-
],
|
|
44071
|
-
type: "filter_pos_distance"
|
|
44072
|
-
}
|
|
44073
|
-
],
|
|
44074
|
-
keyword: params.keyword,
|
|
44075
|
-
note_type: 0,
|
|
44076
|
-
page: params.page,
|
|
44077
|
-
page_size: params.page_size,
|
|
44078
|
-
search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
|
|
44079
|
-
sort: "general"
|
|
44080
|
-
};
|
|
44081
|
-
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
44082
|
-
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
44083
|
-
return acc;
|
|
44084
|
-
}, {});
|
|
44085
|
-
const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
|
|
44086
|
-
const res = await http.api({
|
|
44087
|
-
method: "post",
|
|
44088
|
-
url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
|
|
44089
|
-
data: filterParams,
|
|
44090
|
-
headers: searchXsHeader
|
|
44091
|
-
}, {
|
|
44092
|
-
retries: 3,
|
|
44093
|
-
retryDelay: 20,
|
|
44094
|
-
timeout: 3000
|
|
44095
|
-
});
|
|
44096
|
-
const isSuccess = 0 === res.code;
|
|
44097
|
-
const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
44098
|
-
const data = isSuccess ? res.data : {};
|
|
44099
|
-
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
44100
|
-
};
|
|
44101
|
-
const ttConfigDataSchema = classic_schemas_object({
|
|
44102
|
-
fansNum: classic_schemas_number(),
|
|
44103
|
-
fansNumYesterday: classic_schemas_number().nullable(),
|
|
44104
|
-
readNum: classic_schemas_number(),
|
|
44105
|
-
incomeNum: classic_schemas_number(),
|
|
44106
|
-
incomeNumYesterday: classic_schemas_number().nullable(),
|
|
44107
|
-
showNumYesterday: classic_schemas_number().nullable(),
|
|
44108
|
-
readNumYesterday: classic_schemas_number().nullable(),
|
|
44109
|
-
likeNumYesterday: classic_schemas_number().nullable(),
|
|
44110
|
-
commentNumYesterday: classic_schemas_number().nullable()
|
|
44111
|
-
});
|
|
44112
|
-
const xhsConfigDataSchema = classic_schemas_object({
|
|
44113
|
-
fansNum: classic_schemas_number(),
|
|
44114
|
-
favedNum: classic_schemas_number(),
|
|
44115
|
-
watchNumLastWeek: classic_schemas_number(),
|
|
44116
|
-
likeNumLastWeek: classic_schemas_number(),
|
|
44117
|
-
collectNumLastWeek: classic_schemas_number(),
|
|
44118
|
-
commentNumLastWeek: classic_schemas_number(),
|
|
44119
|
-
fansNumLastWeek: classic_schemas_number(),
|
|
44120
|
-
fansNumYesterday: classic_schemas_number()
|
|
44121
|
-
});
|
|
44122
|
-
const wxConfigDataSchema = classic_schemas_object({
|
|
44123
|
-
fansNum: classic_schemas_number(),
|
|
44124
|
-
fansNumYesterday: classic_schemas_number(),
|
|
44125
|
-
readNumYesterday: classic_schemas_number(),
|
|
44126
|
-
shareNumYesterday: classic_schemas_number()
|
|
44127
|
-
});
|
|
44128
|
-
const bjhConfigDataSchema = classic_schemas_object({
|
|
44129
|
-
fansNum: classic_schemas_number(),
|
|
44130
|
-
fansNumYesterday: classic_schemas_number().nullable(),
|
|
44131
|
-
readNum: classic_schemas_number(),
|
|
44132
|
-
incomeNum: classic_schemas_number(),
|
|
44133
|
-
incomeNumYesterday: classic_schemas_number().nullable(),
|
|
44134
|
-
recommendNumYesterday: classic_schemas_number().nullable(),
|
|
44135
|
-
readNumYesterday: classic_schemas_number().nullable(),
|
|
44136
|
-
likeNumYesterday: classic_schemas_number().nullable(),
|
|
44137
|
-
commentNumYesterday: classic_schemas_number().nullable()
|
|
44138
|
-
});
|
|
44139
|
-
const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
|
|
44140
|
-
function Md5(input) {
|
|
44141
|
-
return external_node_crypto_default().createHash("md5").update(input).digest("hex");
|
|
44142
|
-
}
|
|
44143
|
-
const rpa_server_mock_errnoMap = {
|
|
43554
|
+
const xiaohongshuPublish_mock_errnoMap = {
|
|
44144
43555
|
"-1": "未知拦截器错误,请稍后重试。",
|
|
44145
43556
|
915: "所属C端账号手机号被修改,请重新登录",
|
|
44146
43557
|
914: "所属C端账号密码被修改,请重新登录",
|
|
@@ -44149,9 +43560,8 @@ var __webpack_exports__ = {};
|
|
|
44149
43560
|
906: "账号存在风险,请重新登录!",
|
|
44150
43561
|
"-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
|
|
44151
43562
|
};
|
|
44152
|
-
const
|
|
44153
|
-
const
|
|
44154
|
-
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
43563
|
+
const mock_xsEncrypt = new xhs_ob_feed_Xhshow();
|
|
43564
|
+
const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
|
|
44155
43565
|
const tmpCachePath = task.getTmpPath();
|
|
44156
43566
|
if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
|
|
44157
43567
|
code: 414,
|
|
@@ -44164,49 +43574,6 @@ var __webpack_exports__ = {};
|
|
|
44164
43574
|
message: "账号数据异常,请重新绑定账号后重试。",
|
|
44165
43575
|
data: ""
|
|
44166
43576
|
};
|
|
44167
|
-
const defaultPage = task.steelBrowserContext?.pages()[0];
|
|
44168
|
-
if (defaultPage) {
|
|
44169
|
-
if (!defaultPage._routeRegistered) {
|
|
44170
|
-
defaultPage._routeRegistered = true;
|
|
44171
|
-
const blockedPatterns = [
|
|
44172
|
-
"**/ffmpeg-core.wasm*",
|
|
44173
|
-
"**/apm-fe.xiaohongshu.com*",
|
|
44174
|
-
"**/t2.xiaohongshu.com*",
|
|
44175
|
-
"**/fe-video-qc.xhscdn.com*"
|
|
44176
|
-
].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
|
|
44177
|
-
await defaultPage.route("**/*", async (route)=>{
|
|
44178
|
-
const req = route.request();
|
|
44179
|
-
const url = req.url();
|
|
44180
|
-
const blocked = blockedPatterns.some((regex)=>regex.test(url));
|
|
44181
|
-
if (!blocked) return route.continue();
|
|
44182
|
-
if ("OPTIONS" === req.method()) {
|
|
44183
|
-
console.log("处理 OPTIONS 预检:", url);
|
|
44184
|
-
await route.fulfill({
|
|
44185
|
-
status: 204,
|
|
44186
|
-
headers: {
|
|
44187
|
-
"access-control-allow-origin": "*",
|
|
44188
|
-
"access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
|
|
44189
|
-
"access-control-allow-headers": "*"
|
|
44190
|
-
},
|
|
44191
|
-
body: ""
|
|
44192
|
-
});
|
|
44193
|
-
return;
|
|
44194
|
-
}
|
|
44195
|
-
await route.fulfill({
|
|
44196
|
-
status: 204,
|
|
44197
|
-
body: ""
|
|
44198
|
-
});
|
|
44199
|
-
});
|
|
44200
|
-
}
|
|
44201
|
-
}
|
|
44202
|
-
const pagePromise = task.createPage({
|
|
44203
|
-
show: task.debug,
|
|
44204
|
-
cookies: params.cookies,
|
|
44205
|
-
url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
|
|
44206
|
-
});
|
|
44207
|
-
await updateTaskState?.({
|
|
44208
|
-
state: types_TaskState.ACTION
|
|
44209
|
-
});
|
|
44210
43577
|
const headers = {
|
|
44211
43578
|
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
44212
43579
|
origin: "https://creator.xiaohongshu.com",
|
|
@@ -44233,9 +43600,9 @@ var __webpack_exports__ = {};
|
|
|
44233
43600
|
proxyHttp.addResponseInterceptor((response)=>{
|
|
44234
43601
|
const responseData = response.data;
|
|
44235
43602
|
if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
|
|
44236
|
-
const errmsg =
|
|
43603
|
+
const errmsg = xiaohongshuPublish_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
|
|
44237
43604
|
return {
|
|
44238
|
-
code:
|
|
43605
|
+
code: xiaohongshuPublish_mock_errnoMap[responseData.code] ? 414 : 500,
|
|
44239
43606
|
message: errmsg,
|
|
44240
43607
|
data: responseData
|
|
44241
43608
|
};
|
|
@@ -44249,10 +43616,10 @@ var __webpack_exports__ = {};
|
|
|
44249
43616
|
version: 1,
|
|
44250
43617
|
source: "web"
|
|
44251
43618
|
};
|
|
44252
|
-
const fetchCoverXsHeader =
|
|
43619
|
+
const fetchCoverXsHeader = mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
|
|
44253
43620
|
const uploadInfos = [];
|
|
44254
43621
|
if (params.banners.length > 18) {
|
|
44255
|
-
|
|
43622
|
+
const num = Math.ceil(params.banners.length / 14);
|
|
44256
43623
|
for(let i = 0; i < num; i++){
|
|
44257
43624
|
const start = 14 * i;
|
|
44258
43625
|
params.banners.length;
|
|
@@ -44316,7 +43683,6 @@ var __webpack_exports__ = {};
|
|
|
44316
43683
|
const localUrl = await downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
|
|
44317
43684
|
const fileBuffer = external_node_fs_default().readFileSync(localUrl);
|
|
44318
43685
|
const MAX_RETRIES = uploadInfos.length;
|
|
44319
|
-
task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
|
|
44320
43686
|
let attempt = 0;
|
|
44321
43687
|
while(attempt < MAX_RETRIES){
|
|
44322
43688
|
const ossBucketIndex = availableBuckets.shift();
|
|
@@ -44340,7 +43706,6 @@ var __webpack_exports__ = {};
|
|
|
44340
43706
|
ossToken
|
|
44341
43707
|
};
|
|
44342
43708
|
} catch (error) {
|
|
44343
|
-
task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
|
|
44344
43709
|
attempt++;
|
|
44345
43710
|
}
|
|
44346
43711
|
}
|
|
@@ -44361,7 +43726,7 @@ var __webpack_exports__ = {};
|
|
|
44361
43726
|
const topicData = {
|
|
44362
43727
|
topic_names: topic.name
|
|
44363
43728
|
};
|
|
44364
|
-
const topicXsHeader =
|
|
43729
|
+
const topicXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
|
|
44365
43730
|
const createTopic = await proxyHttp.api({
|
|
44366
43731
|
method: "POST",
|
|
44367
43732
|
url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
|
|
@@ -44373,7 +43738,8 @@ var __webpack_exports__ = {};
|
|
|
44373
43738
|
retryDelay: 20,
|
|
44374
43739
|
timeout: 3000
|
|
44375
43740
|
});
|
|
44376
|
-
|
|
43741
|
+
if (!createTopic?.data) throw types_errorResponse("话题创建失败,请检查话题字段!", 414);
|
|
43742
|
+
Object.assign(topic, createTopic?.data?.topic_infos[0]);
|
|
44377
43743
|
}
|
|
44378
43744
|
}));
|
|
44379
43745
|
const visibleRangeMap = {
|
|
@@ -44504,28 +43870,9 @@ var __webpack_exports__ = {};
|
|
|
44504
43870
|
} : {}
|
|
44505
43871
|
};
|
|
44506
43872
|
publishData.common.business_binds = JSON.stringify(business_binds);
|
|
43873
|
+
const publishXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/v2/note", recordCookie, "ugc", publishData);
|
|
44507
43874
|
task._timerRecord.PrePublish = Date.now();
|
|
44508
|
-
const
|
|
44509
|
-
await updateTaskState?.({
|
|
44510
|
-
sessionId: task.sessionId
|
|
44511
|
-
});
|
|
44512
|
-
const publishXsHeader = {
|
|
44513
|
-
"x-s": "",
|
|
44514
|
-
"x-t": Date.now().toString()
|
|
44515
|
-
};
|
|
44516
|
-
await page.waitForFunction(()=>"function" == typeof window.mnsv2, {
|
|
44517
|
-
timeout: 10000
|
|
44518
|
-
});
|
|
44519
|
-
const encodeData = `/web_api/sns/v2/note${JSON.stringify(publishData)}`;
|
|
44520
|
-
const ticket_mnsv2 = await page.evaluate(({ c, d })=>{
|
|
44521
|
-
if ("function" == typeof window.mnsv2) return window.mnsv2(c, d);
|
|
44522
|
-
return "mnsv2 未定义";
|
|
44523
|
-
}, {
|
|
44524
|
-
c: encodeData,
|
|
44525
|
-
d: Md5(encodeData)
|
|
44526
|
-
});
|
|
44527
|
-
publishXsHeader["x-s"] = rpa_server_mock_encode_mnsv2(ticket_mnsv2, "Windows", "object");
|
|
44528
|
-
publishXsHeader["x-t"] = Date.now().toString();
|
|
43875
|
+
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
44529
43876
|
if (MockPublish) {
|
|
44530
43877
|
const message = `文章模拟发布成功 ${http.proxyInfo}`;
|
|
44531
43878
|
const data = "123456789";
|
|
@@ -44548,6 +43895,17 @@ var __webpack_exports__ = {};
|
|
|
44548
43895
|
retryDelay: 500,
|
|
44549
43896
|
timeout: 12000
|
|
44550
43897
|
});
|
|
43898
|
+
reportLogger({
|
|
43899
|
+
token: params.huiwenToken || "",
|
|
43900
|
+
enverionment: task.enverionment || "development",
|
|
43901
|
+
postId: params.articleId,
|
|
43902
|
+
eip: proxyHttp.proxyInfo,
|
|
43903
|
+
proxyIp: params.localIP,
|
|
43904
|
+
accountId: params.accountId,
|
|
43905
|
+
uid: params.uid,
|
|
43906
|
+
platform: "xiaohongshu",
|
|
43907
|
+
publishParams: publishData
|
|
43908
|
+
});
|
|
44551
43909
|
const isSuccess = publishResult.success;
|
|
44552
43910
|
const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
44553
43911
|
const data = isSuccess ? publishResult.data?.id || "" : "";
|
|
@@ -44568,8 +43926,1642 @@ var __webpack_exports__ = {};
|
|
|
44568
43926
|
response: data
|
|
44569
43927
|
}
|
|
44570
43928
|
});
|
|
44571
|
-
return
|
|
43929
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
43930
|
+
};
|
|
43931
|
+
const xiaohongshuPublish_rpa_rpaAction = async (task, params)=>{
|
|
43932
|
+
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
43933
|
+
const commonCookies = {
|
|
43934
|
+
path: "/",
|
|
43935
|
+
sameSite: "lax",
|
|
43936
|
+
secure: false,
|
|
43937
|
+
domain: ".xiaohongshu.com",
|
|
43938
|
+
url: "https://creator.xiaohongshu.com",
|
|
43939
|
+
httpOnly: true
|
|
43940
|
+
};
|
|
43941
|
+
const page = await task.createPage({
|
|
43942
|
+
show: task.debug,
|
|
43943
|
+
url: params.url || "https://creator.xiaohongshu.com/publish/publish",
|
|
43944
|
+
cookies: params.cookies?.map((it)=>({
|
|
43945
|
+
...it,
|
|
43946
|
+
...commonCookies
|
|
43947
|
+
}))
|
|
43948
|
+
});
|
|
43949
|
+
await updateTaskState?.({
|
|
43950
|
+
state: types_TaskState.ACTION,
|
|
43951
|
+
connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
|
|
43952
|
+
sessionId: task.sessionId
|
|
43953
|
+
});
|
|
43954
|
+
const tmpCachePath = task.getTmpPath();
|
|
43955
|
+
const selectAddress = async (selector, address)=>{
|
|
43956
|
+
const instance = "string" == typeof selector ? page.locator(selector) : selector;
|
|
43957
|
+
await instance.click();
|
|
43958
|
+
await instance.locator("input").fill(address);
|
|
43959
|
+
const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
|
|
43960
|
+
await poperInstance.first().waitFor();
|
|
43961
|
+
await poperInstance.first().click();
|
|
43962
|
+
};
|
|
43963
|
+
const selectDate = async (selector, date)=>{
|
|
43964
|
+
const instance = "string" == typeof selector ? page.locator(selector) : selector;
|
|
43965
|
+
await instance.click();
|
|
43966
|
+
await instance.fill(date);
|
|
43967
|
+
await instance.blur();
|
|
43968
|
+
};
|
|
43969
|
+
const getPoperInstance = async ()=>{
|
|
43970
|
+
await page.waitForTimeout(500);
|
|
43971
|
+
const elements = page.locator(".d-popover");
|
|
43972
|
+
const count = await elements.count();
|
|
43973
|
+
const visibleElements = [];
|
|
43974
|
+
for(let i = 0; i < count; i++){
|
|
43975
|
+
const element = elements.nth(i);
|
|
43976
|
+
const style = await element.getAttribute("style");
|
|
43977
|
+
if (style && !style.includes("display: none")) visibleElements.push(element);
|
|
43978
|
+
}
|
|
43979
|
+
if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
|
|
43980
|
+
throw new Error("未找到 popover 弹窗");
|
|
43981
|
+
};
|
|
43982
|
+
const getDialogInstance = async ()=>{
|
|
43983
|
+
await page.waitForTimeout(1000);
|
|
43984
|
+
const elements = page.locator(".el-dialog");
|
|
43985
|
+
return elements.last();
|
|
43986
|
+
};
|
|
43987
|
+
try {
|
|
43988
|
+
await page.waitForSelector("#CreatorPlatform", {
|
|
43989
|
+
state: "visible"
|
|
43990
|
+
});
|
|
43991
|
+
} catch (error) {
|
|
43992
|
+
return {
|
|
43993
|
+
code: 414,
|
|
43994
|
+
message: "登录失效",
|
|
43995
|
+
data: page.url()
|
|
43996
|
+
};
|
|
43997
|
+
}
|
|
43998
|
+
await page.locator("#content-area .menu-container .publish-video .btn-wrapper .btn-inner").click();
|
|
43999
|
+
await page.locator('.header-tabs .creator-tab:not([style*="-9999px"])').filter({
|
|
44000
|
+
hasText: /^上传图文$/
|
|
44001
|
+
}).click();
|
|
44002
|
+
const images = await Promise.all(params.banners.map((url)=>{
|
|
44003
|
+
const fileName = getFilenameFromUrl(url);
|
|
44004
|
+
return downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
|
|
44005
|
+
}));
|
|
44006
|
+
const fileChooser = await page.$("input.upload-input");
|
|
44007
|
+
if (fileChooser) await fileChooser.setInputFiles(images);
|
|
44008
|
+
const titleInstance = page.locator(".input input");
|
|
44009
|
+
await titleInstance.waitFor({
|
|
44010
|
+
state: "visible",
|
|
44011
|
+
timeout: 50000
|
|
44012
|
+
});
|
|
44013
|
+
await titleInstance.click();
|
|
44014
|
+
await titleInstance.fill(params.title);
|
|
44015
|
+
const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
|
|
44016
|
+
await descInstance.click();
|
|
44017
|
+
await descInstance.pressSequentially(params.content.replace(/#.*?\[.*?]#/g, ""));
|
|
44018
|
+
if (params.topic && params.topic.length > 0) for (const it of params.topic){
|
|
44019
|
+
await descInstance.pressSequentially(`#${it.name}`);
|
|
44020
|
+
await page.locator("#creator-editor-topic-container").waitFor({
|
|
44021
|
+
state: "visible"
|
|
44022
|
+
});
|
|
44023
|
+
await page.waitForTimeout(500);
|
|
44024
|
+
await page.locator("#creator-editor-topic-container .item").first().click();
|
|
44025
|
+
}
|
|
44026
|
+
if (params.address) await selectAddress(page.locator(".address-card-wrapper .d-select-wrapper"), params.address.name);
|
|
44027
|
+
if (params.selfDeclaration) {
|
|
44028
|
+
await page.locator(".declaration-wrapper .d-select-wrapper").click();
|
|
44029
|
+
const poperInstance = await getPoperInstance();
|
|
44030
|
+
const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
|
|
44031
|
+
if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
|
|
44032
|
+
hasText: "虚构演绎,仅供娱乐"
|
|
44033
|
+
}).click();
|
|
44034
|
+
else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
|
|
44035
|
+
hasText: "笔记含AI合成内容"
|
|
44036
|
+
}).click();
|
|
44037
|
+
else if ("source-statement" === params.selfDeclaration.type) {
|
|
44038
|
+
await selfDeclarationInstance.filter({
|
|
44039
|
+
hasText: /内容来源声明/
|
|
44040
|
+
}).click();
|
|
44041
|
+
const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
|
|
44042
|
+
await selfDeclarationSecondaryMenuInstance.first().waitFor();
|
|
44043
|
+
if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
|
|
44044
|
+
hasText: "已在正文中自主标注"
|
|
44045
|
+
}).click();
|
|
44046
|
+
else if ("self-shooting" === params.selfDeclaration.childType) {
|
|
44047
|
+
const { shootingDate, shootingLocation } = params.selfDeclaration;
|
|
44048
|
+
await selfDeclarationSecondaryMenuInstance.filter({
|
|
44049
|
+
hasText: "自主拍摄"
|
|
44050
|
+
}).click();
|
|
44051
|
+
const selfShootingPopup = await getDialogInstance();
|
|
44052
|
+
const hasCustomContent = shootingDate || shootingLocation;
|
|
44053
|
+
if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
|
|
44054
|
+
if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
|
|
44055
|
+
await selfShootingPopup.locator("footer button").filter({
|
|
44056
|
+
hasText: hasCustomContent ? "确认" : "取消"
|
|
44057
|
+
}).click();
|
|
44058
|
+
} else if ("transshipment" === params.selfDeclaration.childType) {
|
|
44059
|
+
await selfDeclarationSecondaryMenuInstance.filter({
|
|
44060
|
+
hasText: "来源转载"
|
|
44061
|
+
}).click();
|
|
44062
|
+
const selfShootingPopup = await getDialogInstance();
|
|
44063
|
+
const sourceMedia = params.selfDeclaration.sourceMedia;
|
|
44064
|
+
if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
|
|
44065
|
+
await selfShootingPopup.locator("footer button").filter({
|
|
44066
|
+
hasText: sourceMedia ? "确认" : "取消"
|
|
44067
|
+
}).click();
|
|
44068
|
+
}
|
|
44069
|
+
}
|
|
44070
|
+
}
|
|
44071
|
+
if ("private" === params.visibleRange) {
|
|
44072
|
+
await page.locator(".publish-page-content-setting-content .d-select-wrapper").last().click();
|
|
44073
|
+
const poperInstance = await getPoperInstance();
|
|
44074
|
+
await poperInstance.locator(".d-options .d-option").filter({
|
|
44075
|
+
hasText: "仅自己可见"
|
|
44076
|
+
}).click();
|
|
44077
|
+
}
|
|
44078
|
+
task._timerRecord.PrePublish = Date.now();
|
|
44079
|
+
const releaseTimeInstance = page.locator("label").filter({
|
|
44080
|
+
hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
|
|
44081
|
+
});
|
|
44082
|
+
await releaseTimeInstance.click();
|
|
44083
|
+
if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
|
|
44084
|
+
await page.waitForFunction(()=>{
|
|
44085
|
+
const publishBtn = Array.from(document.querySelectorAll("button")).find((b)=>b.textContent?.trim() === "发布");
|
|
44086
|
+
const uploading = document.querySelector(".progress-container");
|
|
44087
|
+
return !!publishBtn && !uploading;
|
|
44088
|
+
}, {
|
|
44089
|
+
timeout: 180000,
|
|
44090
|
+
polling: 2000
|
|
44091
|
+
});
|
|
44092
|
+
const response = await new Promise((resolve, reject)=>{
|
|
44093
|
+
const handleResponse = async (response)=>{
|
|
44094
|
+
if (response.url().includes("/web_api/sns/v2/note")) {
|
|
44095
|
+
const jsonResponse = await response.json();
|
|
44096
|
+
page.off("response", handleResponse);
|
|
44097
|
+
if (jsonResponse?.success) resolve(jsonResponse?.data?.id);
|
|
44098
|
+
else reject(new Error(jsonResponse?.msg || "发布失败"));
|
|
44099
|
+
}
|
|
44100
|
+
};
|
|
44101
|
+
page.on("response", handleResponse);
|
|
44102
|
+
page.locator(".publish-page-publish-btn button").filter({
|
|
44103
|
+
hasText: "发布"
|
|
44104
|
+
}).click();
|
|
44105
|
+
});
|
|
44106
|
+
await updateTaskState?.({
|
|
44107
|
+
state: types_TaskState.SUCCESS,
|
|
44108
|
+
result: {
|
|
44109
|
+
response
|
|
44110
|
+
}
|
|
44111
|
+
});
|
|
44112
|
+
await page.close();
|
|
44113
|
+
return success(response);
|
|
44572
44114
|
};
|
|
44115
|
+
const xiaohongshuPublish_rpa_server_rpaAction_Server = async (task, params)=>{
|
|
44116
|
+
if (params.originalBind && params?.selfDeclaration?.type === "source-statement") return {
|
|
44117
|
+
code: 414,
|
|
44118
|
+
message: "已声明原创不可选择“来源转载”",
|
|
44119
|
+
data: ""
|
|
44120
|
+
};
|
|
44121
|
+
const defaultPage = task.steelBrowserContext?.pages()[0];
|
|
44122
|
+
if (defaultPage) {
|
|
44123
|
+
if (!defaultPage._routeRegistered) {
|
|
44124
|
+
defaultPage._routeRegistered = true;
|
|
44125
|
+
const blockedPatterns = [
|
|
44126
|
+
"**/ffmpeg-core.wasm*",
|
|
44127
|
+
"**/apm-fe.xiaohongshu.com*",
|
|
44128
|
+
"**/t2.xiaohongshu.com*",
|
|
44129
|
+
"**/fe-video-qc.xhscdn.com*"
|
|
44130
|
+
].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
|
|
44131
|
+
await defaultPage.route("**/*", async (route)=>{
|
|
44132
|
+
const req = route.request();
|
|
44133
|
+
const url = req.url();
|
|
44134
|
+
const blocked = blockedPatterns.some((regex)=>regex.test(url));
|
|
44135
|
+
if (!blocked) return route.continue();
|
|
44136
|
+
if ("OPTIONS" === req.method()) {
|
|
44137
|
+
console.log("处理 OPTIONS 预检:", url);
|
|
44138
|
+
await route.fulfill({
|
|
44139
|
+
status: 204,
|
|
44140
|
+
headers: {
|
|
44141
|
+
"access-control-allow-origin": "*",
|
|
44142
|
+
"access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
|
|
44143
|
+
"access-control-allow-headers": "*"
|
|
44144
|
+
},
|
|
44145
|
+
body: ""
|
|
44146
|
+
});
|
|
44147
|
+
return;
|
|
44148
|
+
}
|
|
44149
|
+
await route.fulfill({
|
|
44150
|
+
status: 204,
|
|
44151
|
+
body: ""
|
|
44152
|
+
});
|
|
44153
|
+
});
|
|
44154
|
+
}
|
|
44155
|
+
}
|
|
44156
|
+
const tmpCachePath = task.getTmpPath();
|
|
44157
|
+
task.logger?.info("==>进入RPA操作:任务开始,下载图片开始...");
|
|
44158
|
+
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
44159
|
+
const imagePromise = Promise.all(params.banners.map((url)=>{
|
|
44160
|
+
const fileName = getFilenameFromUrl(url);
|
|
44161
|
+
return downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
|
|
44162
|
+
}));
|
|
44163
|
+
let proxyUrl;
|
|
44164
|
+
if (params.localIP) {
|
|
44165
|
+
const args = [
|
|
44166
|
+
params.localIP,
|
|
44167
|
+
params.proxyLoc,
|
|
44168
|
+
params.accountId
|
|
44169
|
+
];
|
|
44170
|
+
task.logger?.info(`==> 开始获取代理信息:${args}`);
|
|
44171
|
+
const ProxyAgentResult = await ProxyAgent({
|
|
44172
|
+
logger: task.logger
|
|
44173
|
+
}, ...args);
|
|
44174
|
+
task.logger?.info("==> 代理信息获取成功!");
|
|
44175
|
+
proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
|
|
44176
|
+
}
|
|
44177
|
+
task.logger?.info("==>开始打开小红书页面...");
|
|
44178
|
+
const page = await task.createPage({
|
|
44179
|
+
show: task.debug,
|
|
44180
|
+
cookies: params.cookies,
|
|
44181
|
+
proxyUrl,
|
|
44182
|
+
url: params.url || "https://creator.xiaohongshu.com/publish/publish?source=official&from=menu&target=image",
|
|
44183
|
+
...params.viewport ? {
|
|
44184
|
+
viewport: params.viewport
|
|
44185
|
+
} : {}
|
|
44186
|
+
});
|
|
44187
|
+
task.logger?.info("==>小红书页面打开成功");
|
|
44188
|
+
await updateTaskState?.({
|
|
44189
|
+
state: types_TaskState.ACTION,
|
|
44190
|
+
connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
|
|
44191
|
+
sessionId: task.sessionId
|
|
44192
|
+
});
|
|
44193
|
+
const clickTimeout = 10000;
|
|
44194
|
+
const selectAddress = async (selector, address)=>{
|
|
44195
|
+
const instance = "string" == typeof selector ? page.locator(selector) : selector;
|
|
44196
|
+
await instance.click({
|
|
44197
|
+
timeout: clickTimeout
|
|
44198
|
+
});
|
|
44199
|
+
await instance.locator("input").fill(address);
|
|
44200
|
+
const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
|
|
44201
|
+
await poperInstance.first().waitFor();
|
|
44202
|
+
await poperInstance.first().click({
|
|
44203
|
+
timeout: clickTimeout
|
|
44204
|
+
});
|
|
44205
|
+
};
|
|
44206
|
+
const selectDate = async (selector, date)=>{
|
|
44207
|
+
const instance = "string" == typeof selector ? page.locator(selector) : selector;
|
|
44208
|
+
await instance.click({
|
|
44209
|
+
timeout: clickTimeout
|
|
44210
|
+
});
|
|
44211
|
+
await instance.fill(date);
|
|
44212
|
+
await instance.blur();
|
|
44213
|
+
};
|
|
44214
|
+
const getPoperInstance = async ()=>{
|
|
44215
|
+
await page.waitForTimeout(500);
|
|
44216
|
+
const elements = page.locator(".d-popover");
|
|
44217
|
+
const count = await elements.count();
|
|
44218
|
+
const visibleElements = [];
|
|
44219
|
+
for(let i = 0; i < count; i++){
|
|
44220
|
+
const element = elements.nth(i);
|
|
44221
|
+
const style = await element.getAttribute("style");
|
|
44222
|
+
if (style && !style.includes("display: none")) visibleElements.push(element);
|
|
44223
|
+
}
|
|
44224
|
+
if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
|
|
44225
|
+
throw new Error("未找到 popover 弹窗");
|
|
44226
|
+
};
|
|
44227
|
+
const getDialogInstance = async ()=>{
|
|
44228
|
+
await page.waitForTimeout(1000);
|
|
44229
|
+
const elements = page.locator(".el-dialog");
|
|
44230
|
+
return elements.last();
|
|
44231
|
+
};
|
|
44232
|
+
try {
|
|
44233
|
+
await page.waitForSelector("#CreatorPlatform", {
|
|
44234
|
+
state: "attached"
|
|
44235
|
+
});
|
|
44236
|
+
} catch (error) {
|
|
44237
|
+
return {
|
|
44238
|
+
code: 414,
|
|
44239
|
+
message: "登录失效",
|
|
44240
|
+
data: page.url()
|
|
44241
|
+
};
|
|
44242
|
+
}
|
|
44243
|
+
const images = await imagePromise;
|
|
44244
|
+
task.logger?.info(`==>图片下载完成,共 ${images.length} 张,开始上传图片...`);
|
|
44245
|
+
const fileChooser = await page.waitForSelector("input.upload-input", {
|
|
44246
|
+
timeout: 10000
|
|
44247
|
+
});
|
|
44248
|
+
if (fileChooser) await fileChooser.setInputFiles(images, {
|
|
44249
|
+
timeout: 60000
|
|
44250
|
+
}).catch((err)=>{
|
|
44251
|
+
task.logger?.error(`设置上传文件失败:${err.message}`);
|
|
44252
|
+
});
|
|
44253
|
+
else task.logger?.error("文件上传输入框未找到");
|
|
44254
|
+
task.logger?.info("==>图片上传完成,开始渲染预览图...");
|
|
44255
|
+
const titleInstance = page.locator(".input input");
|
|
44256
|
+
await titleInstance.waitFor({
|
|
44257
|
+
state: "attached",
|
|
44258
|
+
timeout: 60000
|
|
44259
|
+
});
|
|
44260
|
+
await titleInstance.click({
|
|
44261
|
+
timeout: 24 * clickTimeout
|
|
44262
|
+
});
|
|
44263
|
+
task.logger?.info("==> 预览图渲染成功,开始RPA操作!");
|
|
44264
|
+
await titleInstance.fill(params.title);
|
|
44265
|
+
const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
|
|
44266
|
+
await descInstance.click({
|
|
44267
|
+
timeout: clickTimeout
|
|
44268
|
+
});
|
|
44269
|
+
await descInstance.fill(`${params.content.replace(/#.*?\[.*?]#/g, "")}\n`);
|
|
44270
|
+
await page.keyboard.press("Control+End");
|
|
44271
|
+
if (params.topic && params.topic.length > 0) for (const it of params.topic){
|
|
44272
|
+
await page.keyboard.insertText(`#${it.name}`);
|
|
44273
|
+
await page.locator(".ql-mention-loading").waitFor({
|
|
44274
|
+
state: "detached"
|
|
44275
|
+
});
|
|
44276
|
+
await page.waitForTimeout(1000);
|
|
44277
|
+
await page.locator("#creator-editor-topic-container .item.is-selected").click({
|
|
44278
|
+
timeout: clickTimeout
|
|
44279
|
+
});
|
|
44280
|
+
await page.keyboard.press("Control+End");
|
|
44281
|
+
}
|
|
44282
|
+
const container = page.locator(".plugin.editor-container");
|
|
44283
|
+
await container.focus();
|
|
44284
|
+
await page.mouse.wheel(0, 500);
|
|
44285
|
+
if (params.address) await selectAddress(page.locator(".media-extension .address-input").filter({
|
|
44286
|
+
hasText: "添加地点"
|
|
44287
|
+
}), params.address.name);
|
|
44288
|
+
if (params.collectionBind) {
|
|
44289
|
+
await page.locator(".media-extension .collection-container").filter({
|
|
44290
|
+
hasText: "添加合集"
|
|
44291
|
+
}).click({
|
|
44292
|
+
timeout: clickTimeout
|
|
44293
|
+
});
|
|
44294
|
+
const collectionName = params.collectionBind.name;
|
|
44295
|
+
const collectionBindInstance = await getPoperInstance();
|
|
44296
|
+
const collectionItemInstance = collectionBindInstance.locator(".d-grid-item .item-label", {
|
|
44297
|
+
hasText: collectionName
|
|
44298
|
+
});
|
|
44299
|
+
await collectionBindInstance.locator(".loading").waitFor({
|
|
44300
|
+
state: "detached"
|
|
44301
|
+
});
|
|
44302
|
+
await collectionItemInstance.click({
|
|
44303
|
+
timeout: clickTimeout
|
|
44304
|
+
});
|
|
44305
|
+
}
|
|
44306
|
+
if (params.groupBind) {
|
|
44307
|
+
await page.locator(".media-extension .address-input").filter({
|
|
44308
|
+
hasText: "选择群聊"
|
|
44309
|
+
}).click({
|
|
44310
|
+
timeout: clickTimeout
|
|
44311
|
+
});
|
|
44312
|
+
const groupBindName = params.groupBind.group_name;
|
|
44313
|
+
const groupBindInstance = await getPoperInstance();
|
|
44314
|
+
const groupItemInstance = groupBindInstance.locator(".d-grid-item .name", {
|
|
44315
|
+
hasText: groupBindName
|
|
44316
|
+
});
|
|
44317
|
+
await groupBindInstance.locator(".loading").waitFor({
|
|
44318
|
+
state: "detached"
|
|
44319
|
+
});
|
|
44320
|
+
await groupItemInstance.click({
|
|
44321
|
+
timeout: clickTimeout
|
|
44322
|
+
});
|
|
44323
|
+
}
|
|
44324
|
+
const OriginalBindBtn = page.locator(".btn-text.red", {
|
|
44325
|
+
hasText: "去声明"
|
|
44326
|
+
});
|
|
44327
|
+
const isOriginalBindBtnVisible = await OriginalBindBtn.isVisible();
|
|
44328
|
+
if (isOriginalBindBtnVisible && params.originalBind) {
|
|
44329
|
+
await OriginalBindBtn.click({
|
|
44330
|
+
timeout: clickTimeout
|
|
44331
|
+
});
|
|
44332
|
+
const poperInstance = await getPoperInstance();
|
|
44333
|
+
await poperInstance.locator(".d-checkbox-simulator").click({
|
|
44334
|
+
timeout: clickTimeout
|
|
44335
|
+
});
|
|
44336
|
+
await poperInstance.locator(".footer .custom-button.bg-red").click({
|
|
44337
|
+
timeout: clickTimeout
|
|
44338
|
+
});
|
|
44339
|
+
}
|
|
44340
|
+
if (params.selfDeclaration) {
|
|
44341
|
+
await page.locator(".media-settings .flexbox").filter({
|
|
44342
|
+
hasText: "内容类型声明"
|
|
44343
|
+
}).locator(".d-select-placeholder").click({
|
|
44344
|
+
timeout: clickTimeout
|
|
44345
|
+
});
|
|
44346
|
+
const poperInstance = await getPoperInstance();
|
|
44347
|
+
const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
|
|
44348
|
+
if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
|
|
44349
|
+
hasText: "虚构演绎,仅供娱乐"
|
|
44350
|
+
}).click({
|
|
44351
|
+
timeout: clickTimeout
|
|
44352
|
+
});
|
|
44353
|
+
else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
|
|
44354
|
+
hasText: "笔记含AI合成内容"
|
|
44355
|
+
}).click({
|
|
44356
|
+
timeout: clickTimeout
|
|
44357
|
+
});
|
|
44358
|
+
else if ("source-statement" === params.selfDeclaration.type) {
|
|
44359
|
+
await selfDeclarationInstance.filter({
|
|
44360
|
+
hasText: /内容来源声明/
|
|
44361
|
+
}).click({
|
|
44362
|
+
timeout: clickTimeout
|
|
44363
|
+
});
|
|
44364
|
+
const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
|
|
44365
|
+
await selfDeclarationSecondaryMenuInstance.first().waitFor();
|
|
44366
|
+
if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
|
|
44367
|
+
hasText: "已在正文中自主标注"
|
|
44368
|
+
}).click({
|
|
44369
|
+
timeout: clickTimeout
|
|
44370
|
+
});
|
|
44371
|
+
else if ("self-shooting" === params.selfDeclaration.childType) {
|
|
44372
|
+
const { shootingDate, shootingLocation } = params.selfDeclaration;
|
|
44373
|
+
await selfDeclarationSecondaryMenuInstance.filter({
|
|
44374
|
+
hasText: "自主拍摄"
|
|
44375
|
+
}).click({
|
|
44376
|
+
timeout: clickTimeout
|
|
44377
|
+
});
|
|
44378
|
+
const selfShootingPopup = await getDialogInstance();
|
|
44379
|
+
const hasCustomContent = shootingDate || shootingLocation;
|
|
44380
|
+
if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
|
|
44381
|
+
if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
|
|
44382
|
+
await selfShootingPopup.locator("footer button").filter({
|
|
44383
|
+
hasText: hasCustomContent ? "确认" : "取消"
|
|
44384
|
+
}).click({
|
|
44385
|
+
timeout: clickTimeout
|
|
44386
|
+
});
|
|
44387
|
+
} else if ("transshipment" === params.selfDeclaration.childType) {
|
|
44388
|
+
await selfDeclarationSecondaryMenuInstance.filter({
|
|
44389
|
+
hasText: "来源转载"
|
|
44390
|
+
}).click({
|
|
44391
|
+
timeout: clickTimeout
|
|
44392
|
+
});
|
|
44393
|
+
const selfShootingPopup = await getDialogInstance();
|
|
44394
|
+
const sourceMedia = params.selfDeclaration.sourceMedia;
|
|
44395
|
+
if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
|
|
44396
|
+
await selfShootingPopup.locator("footer button").filter({
|
|
44397
|
+
hasText: sourceMedia ? "确认" : "取消"
|
|
44398
|
+
}).click({
|
|
44399
|
+
timeout: clickTimeout
|
|
44400
|
+
});
|
|
44401
|
+
}
|
|
44402
|
+
}
|
|
44403
|
+
}
|
|
44404
|
+
if ("public" !== params.visibleRange) {
|
|
44405
|
+
await page.locator(".media-settings .flexbox").filter({
|
|
44406
|
+
hasText: "可见范围"
|
|
44407
|
+
}).locator(".d-select-wrapper").click({
|
|
44408
|
+
timeout: clickTimeout
|
|
44409
|
+
});
|
|
44410
|
+
const poperInstance = await getPoperInstance();
|
|
44411
|
+
const visibleText = "friends" === params.visibleRange ? "好友可见" : "仅自己可见";
|
|
44412
|
+
await poperInstance.locator(".d-options .custom-option").filter({
|
|
44413
|
+
hasText: visibleText
|
|
44414
|
+
}).click({
|
|
44415
|
+
timeout: clickTimeout
|
|
44416
|
+
});
|
|
44417
|
+
}
|
|
44418
|
+
async function setSwitch(page, label, target) {
|
|
44419
|
+
const item = page.locator(".d-new-form-item", {
|
|
44420
|
+
has: page.locator(".d-form-item__label", {
|
|
44421
|
+
hasText: label
|
|
44422
|
+
})
|
|
44423
|
+
});
|
|
44424
|
+
const switchUI = item.locator(".d-switch-simulator");
|
|
44425
|
+
const cls = await switchUI.getAttribute("class");
|
|
44426
|
+
const isChecked = cls?.includes("checked") || true;
|
|
44427
|
+
if (isChecked !== target) await switchUI.click({
|
|
44428
|
+
timeout: clickTimeout
|
|
44429
|
+
});
|
|
44430
|
+
}
|
|
44431
|
+
if (!params.coProduceBind) await setSwitch(page, "允许合拍", false);
|
|
44432
|
+
if (!params.noteCopyBind) await setSwitch(page, "允许正文复制", false);
|
|
44433
|
+
const releaseTimeInstance = page.locator("label").filter({
|
|
44434
|
+
hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
|
|
44435
|
+
});
|
|
44436
|
+
await releaseTimeInstance.click({
|
|
44437
|
+
timeout: clickTimeout
|
|
44438
|
+
});
|
|
44439
|
+
if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
|
|
44440
|
+
const imgPreviewArea = page.locator(".img-preview-area");
|
|
44441
|
+
try {
|
|
44442
|
+
await imgPreviewArea.locator(".mask.uploading").waitFor({
|
|
44443
|
+
state: "hidden",
|
|
44444
|
+
timeout: 50000
|
|
44445
|
+
});
|
|
44446
|
+
} catch (error) {
|
|
44447
|
+
throw new Error("上传图片超时,请重试!");
|
|
44448
|
+
}
|
|
44449
|
+
if (MockPublish) {
|
|
44450
|
+
const message = "文章模拟发布成功";
|
|
44451
|
+
const data = "123456789";
|
|
44452
|
+
await updateTaskState?.({
|
|
44453
|
+
state: types_TaskState.SUCCESS,
|
|
44454
|
+
result: {
|
|
44455
|
+
response: data
|
|
44456
|
+
}
|
|
44457
|
+
});
|
|
44458
|
+
return success(data, message);
|
|
44459
|
+
}
|
|
44460
|
+
const response = await new Promise((resolve)=>{
|
|
44461
|
+
const handleResponse = async (response)=>{
|
|
44462
|
+
if (response.url().includes("/web_api/sns/v2/note")) {
|
|
44463
|
+
const jsonResponse = await response.json();
|
|
44464
|
+
page.off("response", handleResponse);
|
|
44465
|
+
resolve(jsonResponse);
|
|
44466
|
+
}
|
|
44467
|
+
};
|
|
44468
|
+
page.on("response", handleResponse);
|
|
44469
|
+
page.locator(".submit .publishBtn").click({
|
|
44470
|
+
timeout: clickTimeout
|
|
44471
|
+
});
|
|
44472
|
+
page.waitForSelector(".d-toast-icon-danger", {
|
|
44473
|
+
state: "visible",
|
|
44474
|
+
timeout: 2000
|
|
44475
|
+
}).then(async ()=>{
|
|
44476
|
+
await page.waitForTimeout(300);
|
|
44477
|
+
const toastDesc = await page.locator(".d-toast-description").textContent();
|
|
44478
|
+
const desc = toastDesc?.trim();
|
|
44479
|
+
page.off("response", handleResponse);
|
|
44480
|
+
resolve({
|
|
44481
|
+
success: false,
|
|
44482
|
+
msg: desc || "未知错误"
|
|
44483
|
+
});
|
|
44484
|
+
}).catch(()=>{});
|
|
44485
|
+
setTimeout(()=>{
|
|
44486
|
+
page.off("response", handleResponse);
|
|
44487
|
+
resolve({
|
|
44488
|
+
success: false,
|
|
44489
|
+
msg: "发布超时"
|
|
44490
|
+
});
|
|
44491
|
+
}, 7000);
|
|
44492
|
+
});
|
|
44493
|
+
if (!response?.success) {
|
|
44494
|
+
const msg = `发布失败:${response?.msg || "未知错误"}`;
|
|
44495
|
+
await updateTaskState?.({
|
|
44496
|
+
state: types_TaskState.FAILED,
|
|
44497
|
+
error: msg
|
|
44498
|
+
});
|
|
44499
|
+
await page.close();
|
|
44500
|
+
return {
|
|
44501
|
+
code: 414,
|
|
44502
|
+
message: msg,
|
|
44503
|
+
data: ""
|
|
44504
|
+
};
|
|
44505
|
+
}
|
|
44506
|
+
await updateTaskState?.({
|
|
44507
|
+
state: types_TaskState.SUCCESS,
|
|
44508
|
+
result: {
|
|
44509
|
+
response: response?.data?.id || ""
|
|
44510
|
+
}
|
|
44511
|
+
});
|
|
44512
|
+
await page.close();
|
|
44513
|
+
return success(response?.data?.id || "");
|
|
44514
|
+
};
|
|
44515
|
+
const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
|
|
44516
|
+
function Md5(input) {
|
|
44517
|
+
return external_node_crypto_default().createHash("md5").update(input).digest("hex");
|
|
44518
|
+
}
|
|
44519
|
+
const rpa_server_mock_errnoMap = {
|
|
44520
|
+
"-1": "未知拦截器错误,请稍后重试。",
|
|
44521
|
+
915: "所属C端账号手机号被修改,请重新登录",
|
|
44522
|
+
914: "所属C端账号密码被修改,请重新登录",
|
|
44523
|
+
903: "账户已登出,需重新登陆重试!",
|
|
44524
|
+
902: "登录已过期,请重新登录!",
|
|
44525
|
+
906: "账号存在风险,请重新登录!",
|
|
44526
|
+
"-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
|
|
44527
|
+
};
|
|
44528
|
+
const rpa_server_mock_xsEncrypt = new Xhshow();
|
|
44529
|
+
const rpaAction_Server_Mock = async (task, params)=>{
|
|
44530
|
+
const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
|
|
44531
|
+
const tmpCachePath = task.getTmpPath();
|
|
44532
|
+
if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
|
|
44533
|
+
code: 414,
|
|
44534
|
+
message: "原创声明与转载声明互斥,请重新选择后发布!",
|
|
44535
|
+
data: ""
|
|
44536
|
+
};
|
|
44537
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
44538
|
+
if (!a1Cookie) return {
|
|
44539
|
+
code: 414,
|
|
44540
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
44541
|
+
data: ""
|
|
44542
|
+
};
|
|
44543
|
+
const defaultPage = task.steelBrowserContext?.pages()[0];
|
|
44544
|
+
if (defaultPage) {
|
|
44545
|
+
if (!defaultPage._routeRegistered) {
|
|
44546
|
+
defaultPage._routeRegistered = true;
|
|
44547
|
+
const blockedPatterns = [
|
|
44548
|
+
"**/ffmpeg-core.wasm*",
|
|
44549
|
+
"**/apm-fe.xiaohongshu.com*",
|
|
44550
|
+
"**/t2.xiaohongshu.com*",
|
|
44551
|
+
"**/fe-video-qc.xhscdn.com*"
|
|
44552
|
+
].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
|
|
44553
|
+
await defaultPage.route("**/*", async (route)=>{
|
|
44554
|
+
const req = route.request();
|
|
44555
|
+
const url = req.url();
|
|
44556
|
+
const blocked = blockedPatterns.some((regex)=>regex.test(url));
|
|
44557
|
+
if (!blocked) return route.continue();
|
|
44558
|
+
if ("OPTIONS" === req.method()) {
|
|
44559
|
+
console.log("处理 OPTIONS 预检:", url);
|
|
44560
|
+
await route.fulfill({
|
|
44561
|
+
status: 204,
|
|
44562
|
+
headers: {
|
|
44563
|
+
"access-control-allow-origin": "*",
|
|
44564
|
+
"access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
|
|
44565
|
+
"access-control-allow-headers": "*"
|
|
44566
|
+
},
|
|
44567
|
+
body: ""
|
|
44568
|
+
});
|
|
44569
|
+
return;
|
|
44570
|
+
}
|
|
44571
|
+
await route.fulfill({
|
|
44572
|
+
status: 204,
|
|
44573
|
+
body: ""
|
|
44574
|
+
});
|
|
44575
|
+
});
|
|
44576
|
+
}
|
|
44577
|
+
}
|
|
44578
|
+
const pagePromise = task.createPage({
|
|
44579
|
+
show: task.debug,
|
|
44580
|
+
cookies: params.cookies,
|
|
44581
|
+
url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
|
|
44582
|
+
});
|
|
44583
|
+
await updateTaskState?.({
|
|
44584
|
+
state: types_TaskState.ACTION
|
|
44585
|
+
});
|
|
44586
|
+
const headers = {
|
|
44587
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
44588
|
+
origin: "https://creator.xiaohongshu.com",
|
|
44589
|
+
referer: "https://creator.xiaohongshu.com/",
|
|
44590
|
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
|
|
44591
|
+
};
|
|
44592
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
44593
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
44594
|
+
return acc;
|
|
44595
|
+
}, {});
|
|
44596
|
+
const args = [
|
|
44597
|
+
{
|
|
44598
|
+
headers
|
|
44599
|
+
},
|
|
44600
|
+
task.logger,
|
|
44601
|
+
params.proxyLoc,
|
|
44602
|
+
params.localIP,
|
|
44603
|
+
params.accountId
|
|
44604
|
+
];
|
|
44605
|
+
const http = new Http({
|
|
44606
|
+
headers
|
|
44607
|
+
});
|
|
44608
|
+
const proxyHttp = new Http(...args);
|
|
44609
|
+
proxyHttp.addResponseInterceptor((response)=>{
|
|
44610
|
+
const responseData = response.data;
|
|
44611
|
+
if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
|
|
44612
|
+
const errmsg = rpa_server_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
|
|
44613
|
+
return {
|
|
44614
|
+
code: rpa_server_mock_errnoMap[responseData.code] ? 414 : 500,
|
|
44615
|
+
message: errmsg,
|
|
44616
|
+
data: responseData
|
|
44617
|
+
};
|
|
44618
|
+
}
|
|
44619
|
+
});
|
|
44620
|
+
const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
|
|
44621
|
+
const fetchCoverParams = {
|
|
44622
|
+
biz_name: "spectrum",
|
|
44623
|
+
scene: "image",
|
|
44624
|
+
file_count: params.banners.length,
|
|
44625
|
+
version: 1,
|
|
44626
|
+
source: "web"
|
|
44627
|
+
};
|
|
44628
|
+
const fetchCoverXsHeader = rpa_server_mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
|
|
44629
|
+
const uploadInfos = [];
|
|
44630
|
+
if (params.banners.length > 18) {
|
|
44631
|
+
let num = Math.ceil(params.banners.length / 14);
|
|
44632
|
+
for(let i = 0; i < num; i++){
|
|
44633
|
+
const start = 14 * i;
|
|
44634
|
+
params.banners.length;
|
|
44635
|
+
({
|
|
44636
|
+
...fetchCoverParams
|
|
44637
|
+
});
|
|
44638
|
+
const batchCoverIdInfo = await proxyHttp.api({
|
|
44639
|
+
method: "get",
|
|
44640
|
+
baseURL: "https://creator.xiaohongshu.com",
|
|
44641
|
+
url: fetchCoverUrl,
|
|
44642
|
+
defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
|
|
44643
|
+
headers: fetchCoverXsHeader,
|
|
44644
|
+
params: fetchCoverParams
|
|
44645
|
+
}, {
|
|
44646
|
+
retries: 3,
|
|
44647
|
+
retryDelay: 20,
|
|
44648
|
+
timeout: 3000
|
|
44649
|
+
});
|
|
44650
|
+
for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
|
|
44651
|
+
bucket: item.bucket || "",
|
|
44652
|
+
uploadAddr: item.uploadAddr || "",
|
|
44653
|
+
fileIds: fileId,
|
|
44654
|
+
token: item.token || ""
|
|
44655
|
+
});
|
|
44656
|
+
}
|
|
44657
|
+
} else {
|
|
44658
|
+
const coverIdInfo = await proxyHttp.api({
|
|
44659
|
+
method: "get",
|
|
44660
|
+
baseURL: "https://creator.xiaohongshu.com",
|
|
44661
|
+
url: fetchCoverUrl,
|
|
44662
|
+
defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
|
|
44663
|
+
headers: fetchCoverXsHeader,
|
|
44664
|
+
params: fetchCoverParams
|
|
44665
|
+
}, {
|
|
44666
|
+
retries: 3,
|
|
44667
|
+
retryDelay: 20,
|
|
44668
|
+
timeout: 3000
|
|
44669
|
+
});
|
|
44670
|
+
for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
|
|
44671
|
+
bucket: item.bucket || "",
|
|
44672
|
+
uploadAddr: item.uploadAddr || "",
|
|
44673
|
+
fileIds: fileId,
|
|
44674
|
+
token: item.token || ""
|
|
44675
|
+
});
|
|
44676
|
+
}
|
|
44677
|
+
if (uploadInfos.length < params.banners.length) return {
|
|
44678
|
+
code: 414,
|
|
44679
|
+
message: "可用 OSS bucket 数量不足,无法上传所有图片!",
|
|
44680
|
+
data: ""
|
|
44681
|
+
};
|
|
44682
|
+
if (0 === uploadInfos.length) return {
|
|
44683
|
+
code: 414,
|
|
44684
|
+
message: "图片上传失败,请稍后重试!",
|
|
44685
|
+
data: ""
|
|
44686
|
+
};
|
|
44687
|
+
const availableBuckets = Array.from({
|
|
44688
|
+
length: uploadInfos.length
|
|
44689
|
+
}, (_, i)=>i);
|
|
44690
|
+
const uploadFile = async (url, index)=>{
|
|
44691
|
+
const fileName = getFilenameFromUrl(url);
|
|
44692
|
+
const localUrl = await downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
|
|
44693
|
+
const fileBuffer = external_node_fs_default().readFileSync(localUrl);
|
|
44694
|
+
const MAX_RETRIES = uploadInfos.length;
|
|
44695
|
+
task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
|
|
44696
|
+
let attempt = 0;
|
|
44697
|
+
while(attempt < MAX_RETRIES){
|
|
44698
|
+
const ossBucketIndex = availableBuckets.shift();
|
|
44699
|
+
if (void 0 === ossBucketIndex) break;
|
|
44700
|
+
const currentInfo = uploadInfos[ossBucketIndex];
|
|
44701
|
+
const ossFileId = currentInfo.fileIds;
|
|
44702
|
+
const ossToken = currentInfo.token;
|
|
44703
|
+
const ossDomain = currentInfo.uploadAddr;
|
|
44704
|
+
try {
|
|
44705
|
+
await http.api({
|
|
44706
|
+
method: "put",
|
|
44707
|
+
url: `https://${ossDomain}/${ossFileId}`,
|
|
44708
|
+
data: fileBuffer,
|
|
44709
|
+
headers: {
|
|
44710
|
+
"x-cos-security-token": ossToken
|
|
44711
|
+
},
|
|
44712
|
+
defaultErrorMsg: "图片上传异常,请稍后重试发布。"
|
|
44713
|
+
});
|
|
44714
|
+
return {
|
|
44715
|
+
ossFileId,
|
|
44716
|
+
ossToken
|
|
44717
|
+
};
|
|
44718
|
+
} catch (error) {
|
|
44719
|
+
task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
|
|
44720
|
+
attempt++;
|
|
44721
|
+
}
|
|
44722
|
+
}
|
|
44723
|
+
return {
|
|
44724
|
+
ossFileId: "",
|
|
44725
|
+
ossToken: ""
|
|
44726
|
+
};
|
|
44727
|
+
};
|
|
44728
|
+
const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
|
|
44729
|
+
const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
|
|
44730
|
+
if (invalidUpload) return {
|
|
44731
|
+
code: 414,
|
|
44732
|
+
message: "图片上传异常,请稍后重试发布。",
|
|
44733
|
+
data: ""
|
|
44734
|
+
};
|
|
44735
|
+
if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
|
|
44736
|
+
if (!topic.id) {
|
|
44737
|
+
const topicData = {
|
|
44738
|
+
topic_names: topic.name
|
|
44739
|
+
};
|
|
44740
|
+
const topicXsHeader = rpa_server_mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
|
|
44741
|
+
const createTopic = await proxyHttp.api({
|
|
44742
|
+
method: "POST",
|
|
44743
|
+
url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
|
|
44744
|
+
headers: topicXsHeader,
|
|
44745
|
+
data: topicData,
|
|
44746
|
+
defaultErrorMsg: "话题创建异常,请稍后重试。"
|
|
44747
|
+
}, {
|
|
44748
|
+
retries: 3,
|
|
44749
|
+
retryDelay: 20,
|
|
44750
|
+
timeout: 3000
|
|
44751
|
+
});
|
|
44752
|
+
Object.assign(topic, createTopic.data.topic_infos[0]);
|
|
44753
|
+
}
|
|
44754
|
+
}));
|
|
44755
|
+
const visibleRangeMap = {
|
|
44756
|
+
public: 0,
|
|
44757
|
+
private: 1,
|
|
44758
|
+
friends: 4
|
|
44759
|
+
};
|
|
44760
|
+
const publishData = {
|
|
44761
|
+
common: {
|
|
44762
|
+
ats: [],
|
|
44763
|
+
biz_relations: [],
|
|
44764
|
+
desc: params?.content,
|
|
44765
|
+
goods_info: {},
|
|
44766
|
+
hash_tag: params.topic || [],
|
|
44767
|
+
note_id: "",
|
|
44768
|
+
source: JSON.stringify({
|
|
44769
|
+
type: "web",
|
|
44770
|
+
ids: "",
|
|
44771
|
+
extraInfo: '{"systemId":"web"}'
|
|
44772
|
+
}),
|
|
44773
|
+
title: params?.title,
|
|
44774
|
+
type: "normal",
|
|
44775
|
+
privacy_info: {
|
|
44776
|
+
op_type: 1,
|
|
44777
|
+
type: visibleRangeMap[params.visibleRange]
|
|
44778
|
+
},
|
|
44779
|
+
post_loc: params.address ? {
|
|
44780
|
+
name: params.address?.name,
|
|
44781
|
+
poi_id: params.address?.poi_id,
|
|
44782
|
+
poi_type: params.address?.poi_type,
|
|
44783
|
+
subname: params.address?.full_address
|
|
44784
|
+
} : null,
|
|
44785
|
+
business_binds: ""
|
|
44786
|
+
},
|
|
44787
|
+
image_info: {
|
|
44788
|
+
images: coverInfos.map((it)=>({
|
|
44789
|
+
extra_info_json: '{"mimeType":"image/png"}',
|
|
44790
|
+
file_id: it.ossFileId,
|
|
44791
|
+
metadata: {
|
|
44792
|
+
source: -1
|
|
44793
|
+
},
|
|
44794
|
+
stickers: {
|
|
44795
|
+
floating: [],
|
|
44796
|
+
version: 2
|
|
44797
|
+
}
|
|
44798
|
+
}))
|
|
44799
|
+
},
|
|
44800
|
+
video_info: null
|
|
44801
|
+
};
|
|
44802
|
+
const userDeclarationBind = {
|
|
44803
|
+
origin: 2,
|
|
44804
|
+
photoInfo: {},
|
|
44805
|
+
repostInfo: {}
|
|
44806
|
+
};
|
|
44807
|
+
if (params.selfDeclaration?.type === "fictional-rendition") userDeclarationBind.origin = 1;
|
|
44808
|
+
else if (params.selfDeclaration?.type === "ai-generated") userDeclarationBind.origin = 2;
|
|
44809
|
+
else if (params.selfDeclaration?.type === "source-statement") {
|
|
44810
|
+
if ("self-labeling" === params.selfDeclaration.childType) userDeclarationBind.origin = 3;
|
|
44811
|
+
else if ("self-shooting" === params.selfDeclaration.childType) {
|
|
44812
|
+
userDeclarationBind.origin = 4;
|
|
44813
|
+
const photoInfo = {};
|
|
44814
|
+
if (params.selfDeclaration.shootingLocation) photoInfo.photoPlace = {
|
|
44815
|
+
name: params.selfDeclaration.shootingLocation.name,
|
|
44816
|
+
poiId: params.selfDeclaration.shootingLocation.poi_id,
|
|
44817
|
+
poiType: params.selfDeclaration.shootingLocation.poi_type,
|
|
44818
|
+
subname: params.selfDeclaration.shootingLocation.full_address
|
|
44819
|
+
};
|
|
44820
|
+
if (params.selfDeclaration.shootingDate) photoInfo.photoTime = params.selfDeclaration.shootingDate;
|
|
44821
|
+
userDeclarationBind.photoInfo = photoInfo;
|
|
44822
|
+
} else if ("transshipment" === params.selfDeclaration.childType) {
|
|
44823
|
+
userDeclarationBind.origin = 5;
|
|
44824
|
+
if (params.selfDeclaration.sourceMedia) userDeclarationBind.repostInfo = {
|
|
44825
|
+
source: params.selfDeclaration.sourceMedia
|
|
44826
|
+
};
|
|
44827
|
+
}
|
|
44828
|
+
}
|
|
44829
|
+
const bizId = params?.originalBind && (params.cookies.find((it)=>"x-user-id-creator.xiaohongshu.com" === it.name)?.value || await proxyHttp.api({
|
|
44830
|
+
method: "get",
|
|
44831
|
+
url: "https://creator.xiaohongshu.com/api/galaxy/user/my-info"
|
|
44832
|
+
}, {
|
|
44833
|
+
retries: 3,
|
|
44834
|
+
retryDelay: 20,
|
|
44835
|
+
timeout: 3000
|
|
44836
|
+
}).then((userData)=>userData.data?.userDetail?.id));
|
|
44837
|
+
const business_binds = {
|
|
44838
|
+
version: 1,
|
|
44839
|
+
bizType: "",
|
|
44840
|
+
noteId: "",
|
|
44841
|
+
noteOrderBind: {},
|
|
44842
|
+
notePostTiming: params.isImmediatelyPublish ? {} : {
|
|
44843
|
+
postTime: params.scheduledPublish
|
|
44844
|
+
},
|
|
44845
|
+
coProduceBind: {
|
|
44846
|
+
enable: !!params?.coProduceBind
|
|
44847
|
+
},
|
|
44848
|
+
noteCopyBind: {
|
|
44849
|
+
copyable: !!params?.noteCopyBind
|
|
44850
|
+
},
|
|
44851
|
+
optionRelationList: params.originalBind ? [
|
|
44852
|
+
{
|
|
44853
|
+
type: "ORIGINAL_STATEMENT",
|
|
44854
|
+
relationList: [
|
|
44855
|
+
{
|
|
44856
|
+
bizId,
|
|
44857
|
+
bizType: "ORIGINAL_STATEMENT",
|
|
44858
|
+
extraInfo: "{}"
|
|
44859
|
+
}
|
|
44860
|
+
]
|
|
44861
|
+
}
|
|
44862
|
+
] : [],
|
|
44863
|
+
...params?.groupBind ? {
|
|
44864
|
+
groupBind: {
|
|
44865
|
+
groupId: params?.groupBind?.group_id,
|
|
44866
|
+
groupName: params.groupBind?.group_name,
|
|
44867
|
+
desc: params.groupBind?.desc,
|
|
44868
|
+
avatar: params.groupBind?.avatar
|
|
44869
|
+
}
|
|
44870
|
+
} : {
|
|
44871
|
+
groupBind: {}
|
|
44872
|
+
},
|
|
44873
|
+
...params.selfDeclaration ? {
|
|
44874
|
+
userDeclarationBind
|
|
44875
|
+
} : {},
|
|
44876
|
+
...params?.collectionBind?.id ? {
|
|
44877
|
+
noteCollectionBind: {
|
|
44878
|
+
id: params.collectionBind.id
|
|
44879
|
+
}
|
|
44880
|
+
} : {}
|
|
44881
|
+
};
|
|
44882
|
+
publishData.common.business_binds = JSON.stringify(business_binds);
|
|
44883
|
+
task._timerRecord.PrePublish = Date.now();
|
|
44884
|
+
const page = await pagePromise;
|
|
44885
|
+
await updateTaskState?.({
|
|
44886
|
+
sessionId: task.sessionId
|
|
44887
|
+
});
|
|
44888
|
+
const publishXsHeader = {
|
|
44889
|
+
"x-s": "",
|
|
44890
|
+
"x-t": Date.now().toString()
|
|
44891
|
+
};
|
|
44892
|
+
await page.waitForFunction(()=>"function" == typeof window.mnsv2, {
|
|
44893
|
+
timeout: 10000
|
|
44894
|
+
});
|
|
44895
|
+
const encodeData = `/web_api/sns/v2/note${JSON.stringify(publishData)}`;
|
|
44896
|
+
const ticket_mnsv2 = await page.evaluate(({ c, d })=>{
|
|
44897
|
+
if ("function" == typeof window.mnsv2) return window.mnsv2(c, d);
|
|
44898
|
+
return "mnsv2 未定义";
|
|
44899
|
+
}, {
|
|
44900
|
+
c: encodeData,
|
|
44901
|
+
d: Md5(encodeData)
|
|
44902
|
+
});
|
|
44903
|
+
publishXsHeader["x-s"] = rpa_server_mock_encode_mnsv2(ticket_mnsv2, "Windows", "object");
|
|
44904
|
+
publishXsHeader["x-t"] = Date.now().toString();
|
|
44905
|
+
if (MockPublish) {
|
|
44906
|
+
const message = `文章模拟发布成功 ${http.proxyInfo}`;
|
|
44907
|
+
const data = "123456789";
|
|
44908
|
+
await updateTaskState?.({
|
|
44909
|
+
state: types_TaskState.SUCCESS,
|
|
44910
|
+
result: {
|
|
44911
|
+
response: data
|
|
44912
|
+
}
|
|
44913
|
+
});
|
|
44914
|
+
return success(data, message);
|
|
44915
|
+
}
|
|
44916
|
+
const publishResult = await proxyHttp.api({
|
|
44917
|
+
method: "post",
|
|
44918
|
+
url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
|
|
44919
|
+
data: publishData,
|
|
44920
|
+
headers: publishXsHeader,
|
|
44921
|
+
defaultErrorMsg: "文章发布异常,请稍后重试。"
|
|
44922
|
+
}, {
|
|
44923
|
+
retries: 2,
|
|
44924
|
+
retryDelay: 500,
|
|
44925
|
+
timeout: 12000
|
|
44926
|
+
});
|
|
44927
|
+
const isSuccess = publishResult.success;
|
|
44928
|
+
const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
44929
|
+
const data = isSuccess ? publishResult.data?.id || "" : "";
|
|
44930
|
+
if (!isSuccess) {
|
|
44931
|
+
await updateTaskState?.({
|
|
44932
|
+
state: types_TaskState.FAILED,
|
|
44933
|
+
error: message
|
|
44934
|
+
});
|
|
44935
|
+
return {
|
|
44936
|
+
code: 414,
|
|
44937
|
+
data,
|
|
44938
|
+
message
|
|
44939
|
+
};
|
|
44940
|
+
}
|
|
44941
|
+
await updateTaskState?.({
|
|
44942
|
+
state: types_TaskState.SUCCESS,
|
|
44943
|
+
result: {
|
|
44944
|
+
response: data
|
|
44945
|
+
}
|
|
44946
|
+
});
|
|
44947
|
+
return success(data, message);
|
|
44948
|
+
};
|
|
44949
|
+
const FictionalRendition = classic_schemas_object({
|
|
44950
|
+
type: literal("fictional-rendition")
|
|
44951
|
+
});
|
|
44952
|
+
const AIGenerated = classic_schemas_object({
|
|
44953
|
+
type: literal("ai-generated")
|
|
44954
|
+
});
|
|
44955
|
+
const SourceStatement = classic_schemas_object({
|
|
44956
|
+
type: literal("source-statement"),
|
|
44957
|
+
childType: classic_schemas_enum([
|
|
44958
|
+
"self-labeling",
|
|
44959
|
+
"self-shooting",
|
|
44960
|
+
"transshipment"
|
|
44961
|
+
]),
|
|
44962
|
+
shootingLocation: custom().optional(),
|
|
44963
|
+
shootingDate: classic_schemas_string().optional(),
|
|
44964
|
+
sourceMedia: classic_schemas_string().optional()
|
|
44965
|
+
});
|
|
44966
|
+
schemas_union([
|
|
44967
|
+
FictionalRendition,
|
|
44968
|
+
AIGenerated,
|
|
44969
|
+
SourceStatement
|
|
44970
|
+
]);
|
|
44971
|
+
const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
|
|
44972
|
+
banners: classic_schemas_array(classic_schemas_string()),
|
|
44973
|
+
title: classic_schemas_string(),
|
|
44974
|
+
content: classic_schemas_string(),
|
|
44975
|
+
address: custom().optional(),
|
|
44976
|
+
selfDeclaration: custom().optional(),
|
|
44977
|
+
topic: classic_schemas_array(custom()).optional(),
|
|
44978
|
+
proxyLoc: classic_schemas_string().optional(),
|
|
44979
|
+
localIP: classic_schemas_string().optional(),
|
|
44980
|
+
huiwenToken: classic_schemas_string().optional(),
|
|
44981
|
+
visibleRange: classic_schemas_enum([
|
|
44982
|
+
"public",
|
|
44983
|
+
"private",
|
|
44984
|
+
"friends"
|
|
44985
|
+
]),
|
|
44986
|
+
isImmediatelyPublish: classic_schemas_boolean().optional(),
|
|
44987
|
+
scheduledPublish: classic_schemas_string().optional(),
|
|
44988
|
+
collectionId: classic_schemas_string().optional(),
|
|
44989
|
+
collectionBind: custom().optional(),
|
|
44990
|
+
groupBind: custom().optional(),
|
|
44991
|
+
noteCopyBind: classic_schemas_boolean().optional(),
|
|
44992
|
+
coProduceBind: classic_schemas_boolean().optional(),
|
|
44993
|
+
originalBind: classic_schemas_boolean().optional()
|
|
44994
|
+
});
|
|
44995
|
+
const xiaohongshuPublish = async (task, params)=>{
|
|
44996
|
+
if (DisabledReq) return {
|
|
44997
|
+
code: 414,
|
|
44998
|
+
data: "",
|
|
44999
|
+
message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
|
|
45000
|
+
};
|
|
45001
|
+
if ("rpa" === params.actionType) return xiaohongshuPublish_rpa_rpaAction(task, params);
|
|
45002
|
+
if ("mockApi" === params.actionType) return xiaohongshuPublish_mock_mockAction(task, params);
|
|
45003
|
+
if ("server" === params.actionType) return xiaohongshuPublish_rpa_server_rpaAction_Server(task, params);
|
|
45004
|
+
return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, xiaohongshuPublish_rpa_server_rpaAction_Server)(task, params);
|
|
45005
|
+
};
|
|
45006
|
+
const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
|
|
45007
|
+
const xiaohongshuWebCommentAction = async (_task, params)=>{
|
|
45008
|
+
if (DisabledReq) return utils_response(414, "点赞相关操作失败", {});
|
|
45009
|
+
const headers = {
|
|
45010
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45011
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45012
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45013
|
+
};
|
|
45014
|
+
const args = [
|
|
45015
|
+
{
|
|
45016
|
+
headers
|
|
45017
|
+
},
|
|
45018
|
+
_task.logger,
|
|
45019
|
+
params.proxyLoc,
|
|
45020
|
+
params.localIP,
|
|
45021
|
+
params.accountId
|
|
45022
|
+
];
|
|
45023
|
+
const http = new Http(...args);
|
|
45024
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45025
|
+
if (!a1Cookie) return {
|
|
45026
|
+
code: 414,
|
|
45027
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45028
|
+
data: []
|
|
45029
|
+
};
|
|
45030
|
+
if (!params.note_id && !params.comment_id && !params.action) return {
|
|
45031
|
+
code: 414,
|
|
45032
|
+
message: "参数缺失,请检查后重试!",
|
|
45033
|
+
data: {}
|
|
45034
|
+
};
|
|
45035
|
+
const actionParams = {
|
|
45036
|
+
note_id: params.note_id,
|
|
45037
|
+
comment_id: params.comment_id
|
|
45038
|
+
};
|
|
45039
|
+
let likeActionRes = {
|
|
45040
|
+
code: 500,
|
|
45041
|
+
success: false,
|
|
45042
|
+
msg: ""
|
|
45043
|
+
};
|
|
45044
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45045
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45046
|
+
return acc;
|
|
45047
|
+
}, {});
|
|
45048
|
+
switch(params.action){
|
|
45049
|
+
case "like":
|
|
45050
|
+
{
|
|
45051
|
+
const likeAction = "/api/sns/web/v1/comment/like";
|
|
45052
|
+
const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
|
|
45053
|
+
likeActionRes = await http.api({
|
|
45054
|
+
method: "post",
|
|
45055
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
|
|
45056
|
+
data: actionParams,
|
|
45057
|
+
headers: likeActionXsHeader
|
|
45058
|
+
}, {
|
|
45059
|
+
retries: 3,
|
|
45060
|
+
retryDelay: 20,
|
|
45061
|
+
timeout: 3000
|
|
45062
|
+
});
|
|
45063
|
+
break;
|
|
45064
|
+
}
|
|
45065
|
+
case "dislike":
|
|
45066
|
+
{
|
|
45067
|
+
const dislikeMentions = "/api/sns/web/v1/comment/dislike";
|
|
45068
|
+
const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
|
|
45069
|
+
likeActionRes = await http.api({
|
|
45070
|
+
method: "post",
|
|
45071
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
|
|
45072
|
+
data: actionParams,
|
|
45073
|
+
headers: dislikeXsHeader
|
|
45074
|
+
}, {
|
|
45075
|
+
retries: 3,
|
|
45076
|
+
retryDelay: 20,
|
|
45077
|
+
timeout: 3000
|
|
45078
|
+
});
|
|
45079
|
+
break;
|
|
45080
|
+
}
|
|
45081
|
+
default:
|
|
45082
|
+
return {
|
|
45083
|
+
code: 414,
|
|
45084
|
+
message: "参数action错误,请重试!",
|
|
45085
|
+
data: {}
|
|
45086
|
+
};
|
|
45087
|
+
}
|
|
45088
|
+
const isSuccess = 0 === likeActionRes.code;
|
|
45089
|
+
const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45090
|
+
const data = isSuccess ? likeActionRes.success : {};
|
|
45091
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45092
|
+
};
|
|
45093
|
+
const xiaohongshuWebIntimacySearch = async (_task, params)=>{
|
|
45094
|
+
if (DisabledReq) return utils_response(0, "搜索@列表数据成功", []);
|
|
45095
|
+
const headers = {
|
|
45096
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45097
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45098
|
+
origin: "https://www.xiaohongshu.com"
|
|
45099
|
+
};
|
|
45100
|
+
const args = [
|
|
45101
|
+
{
|
|
45102
|
+
headers
|
|
45103
|
+
},
|
|
45104
|
+
_task.logger,
|
|
45105
|
+
params.proxyLoc,
|
|
45106
|
+
params.localIP,
|
|
45107
|
+
params.accountId
|
|
45108
|
+
];
|
|
45109
|
+
const http = new Http(...args);
|
|
45110
|
+
let intimacyDetail = [];
|
|
45111
|
+
const res = await http.api({
|
|
45112
|
+
method: "get",
|
|
45113
|
+
url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
|
|
45114
|
+
...params.searchValue ? {
|
|
45115
|
+
params: {
|
|
45116
|
+
keyword: params.searchValue,
|
|
45117
|
+
page: 1,
|
|
45118
|
+
rows: 30
|
|
45119
|
+
}
|
|
45120
|
+
} : {}
|
|
45121
|
+
}, {
|
|
45122
|
+
retries: 3,
|
|
45123
|
+
retryDelay: 20,
|
|
45124
|
+
timeout: 3000
|
|
45125
|
+
});
|
|
45126
|
+
const isSuccess = 0 === res.code;
|
|
45127
|
+
if (isSuccess) intimacyDetail = res.data.items;
|
|
45128
|
+
const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45129
|
+
return utils_response(isSuccess ? 0 : 414, message, intimacyDetail);
|
|
45130
|
+
};
|
|
45131
|
+
const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
|
|
45132
|
+
const xiaohongshuWebMsgRead = async (_task, params)=>{
|
|
45133
|
+
if (DisabledReq) return utils_response(414, "Read指定Tab失败", {});
|
|
45134
|
+
const headers = {
|
|
45135
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45136
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45137
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45138
|
+
};
|
|
45139
|
+
const args = [
|
|
45140
|
+
{
|
|
45141
|
+
headers
|
|
45142
|
+
},
|
|
45143
|
+
_task.logger,
|
|
45144
|
+
params.proxyLoc,
|
|
45145
|
+
params.localIP,
|
|
45146
|
+
params.accountId
|
|
45147
|
+
];
|
|
45148
|
+
const http = new Http(...args);
|
|
45149
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45150
|
+
if (!a1Cookie) return {
|
|
45151
|
+
code: 414,
|
|
45152
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45153
|
+
data: []
|
|
45154
|
+
};
|
|
45155
|
+
if (!params.type) return {
|
|
45156
|
+
code: 414,
|
|
45157
|
+
message: "参数缺失,请检查后重试!",
|
|
45158
|
+
data: {}
|
|
45159
|
+
};
|
|
45160
|
+
const replyParams = {
|
|
45161
|
+
type: params.type
|
|
45162
|
+
};
|
|
45163
|
+
const fatchMentions = "/api/sns/web/v1/message/read";
|
|
45164
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45165
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45166
|
+
return acc;
|
|
45167
|
+
}, {});
|
|
45168
|
+
const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
|
|
45169
|
+
const res = await http.api({
|
|
45170
|
+
method: "post",
|
|
45171
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
|
|
45172
|
+
data: replyParams,
|
|
45173
|
+
headers: fatchMentionsXsHeader
|
|
45174
|
+
}, {
|
|
45175
|
+
retries: 3,
|
|
45176
|
+
retryDelay: 20,
|
|
45177
|
+
timeout: 3000
|
|
45178
|
+
});
|
|
45179
|
+
const isSuccess = 0 === res.code;
|
|
45180
|
+
const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45181
|
+
const data = isSuccess ? res.success : {};
|
|
45182
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45183
|
+
};
|
|
45184
|
+
const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
|
|
45185
|
+
const xiaohongshuWebMsgReply = async (_task, params)=>{
|
|
45186
|
+
if (DisabledReq) return utils_response(414, "评论回复失败", {});
|
|
45187
|
+
const headers = {
|
|
45188
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45189
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45190
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45191
|
+
};
|
|
45192
|
+
const args = [
|
|
45193
|
+
{
|
|
45194
|
+
headers
|
|
45195
|
+
},
|
|
45196
|
+
_task.logger,
|
|
45197
|
+
params.proxyLoc,
|
|
45198
|
+
params.localIP,
|
|
45199
|
+
params.accountId
|
|
45200
|
+
];
|
|
45201
|
+
const http = new Http(...args);
|
|
45202
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45203
|
+
if (!a1Cookie) return {
|
|
45204
|
+
code: 414,
|
|
45205
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45206
|
+
data: []
|
|
45207
|
+
};
|
|
45208
|
+
if (!params.note_id || !params.target_comment_id || !params.content) return {
|
|
45209
|
+
code: 414,
|
|
45210
|
+
message: "参数缺失,请检查后重试!",
|
|
45211
|
+
data: {}
|
|
45212
|
+
};
|
|
45213
|
+
const replyParams = {
|
|
45214
|
+
at_users: params.at_users ?? [],
|
|
45215
|
+
content: params.content,
|
|
45216
|
+
note_id: params.note_id,
|
|
45217
|
+
target_comment_id: params.target_comment_id
|
|
45218
|
+
};
|
|
45219
|
+
const replyPath = "/api/sns/web/v1/comment/post";
|
|
45220
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45221
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45222
|
+
return acc;
|
|
45223
|
+
}, {});
|
|
45224
|
+
const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
|
|
45225
|
+
const res = await http.api({
|
|
45226
|
+
method: "post",
|
|
45227
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
|
|
45228
|
+
data: replyParams,
|
|
45229
|
+
headers: replyXsHeader
|
|
45230
|
+
}, {
|
|
45231
|
+
retries: 3,
|
|
45232
|
+
retryDelay: 20,
|
|
45233
|
+
timeout: 3000
|
|
45234
|
+
});
|
|
45235
|
+
const isSuccess = 0 === res.code;
|
|
45236
|
+
const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45237
|
+
const data = isSuccess ? res.data : {};
|
|
45238
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45239
|
+
};
|
|
45240
|
+
const xiaohongshuWebNoteFeed_xsEncrypt = new xhs_ob_feed_Xhshow();
|
|
45241
|
+
const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
|
|
45242
|
+
const xiaohongshuWebNoteFeed = async (_task, params)=>{
|
|
45243
|
+
if (DisabledReq) return utils_response(414, "获取指定文章详情失败", {});
|
|
45244
|
+
const headers = {
|
|
45245
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45246
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45247
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45248
|
+
};
|
|
45249
|
+
const args = [
|
|
45250
|
+
{
|
|
45251
|
+
headers
|
|
45252
|
+
},
|
|
45253
|
+
_task.logger,
|
|
45254
|
+
params.proxyLoc,
|
|
45255
|
+
params.localIP,
|
|
45256
|
+
params.accountId
|
|
45257
|
+
];
|
|
45258
|
+
const http = new Http(...args);
|
|
45259
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45260
|
+
if (!a1Cookie) return {
|
|
45261
|
+
code: 414,
|
|
45262
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45263
|
+
data: {}
|
|
45264
|
+
};
|
|
45265
|
+
if (!params.source_note_id && !params.xsec_token) return {
|
|
45266
|
+
code: 414,
|
|
45267
|
+
message: "参数缺失,请检查后重试!",
|
|
45268
|
+
data: {}
|
|
45269
|
+
};
|
|
45270
|
+
const feedParams = {
|
|
45271
|
+
source_note_id: params.source_note_id,
|
|
45272
|
+
image_formats: [
|
|
45273
|
+
"jpg",
|
|
45274
|
+
"webp",
|
|
45275
|
+
"avif"
|
|
45276
|
+
],
|
|
45277
|
+
extra: {
|
|
45278
|
+
need_body_topic: "1"
|
|
45279
|
+
},
|
|
45280
|
+
xsec_source: "pc_feed",
|
|
45281
|
+
xsec_token: params.xsec_token
|
|
45282
|
+
};
|
|
45283
|
+
const fatchFeed = "/api/sns/web/v1/feed";
|
|
45284
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45285
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45286
|
+
return acc;
|
|
45287
|
+
}, {});
|
|
45288
|
+
const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
|
|
45289
|
+
const xT = Date.now().toString();
|
|
45290
|
+
const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
|
|
45291
|
+
_task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
|
|
45292
|
+
_task.logger.info(`X-S: ${xsHeader["X-S"]}`);
|
|
45293
|
+
_task.logger.info(`x-s-common: ${xsCommon}`);
|
|
45294
|
+
const res = await http.api({
|
|
45295
|
+
method: "post",
|
|
45296
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
|
|
45297
|
+
data: feedParams,
|
|
45298
|
+
headers: {
|
|
45299
|
+
"X-S": xsHeader["X-S"],
|
|
45300
|
+
"X-S-Common": xsCommon,
|
|
45301
|
+
"X-T": xT
|
|
45302
|
+
}
|
|
45303
|
+
}, {
|
|
45304
|
+
retries: 3,
|
|
45305
|
+
retryDelay: 20,
|
|
45306
|
+
timeout: 3000
|
|
45307
|
+
});
|
|
45308
|
+
_task.logger.info(`API 响应: ${JSON.stringify(res)}`);
|
|
45309
|
+
const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
|
|
45310
|
+
const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45311
|
+
const data = isSuccess ? res.data?.items[0].note_card || {} : {};
|
|
45312
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45313
|
+
};
|
|
45314
|
+
const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
|
|
45315
|
+
const xiaohongshuWebRelationAction = async (_task, params)=>{
|
|
45316
|
+
if (DisabledReq) return utils_response(414, "用户关系操作失败", {});
|
|
45317
|
+
const headers = {
|
|
45318
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45319
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45320
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45321
|
+
};
|
|
45322
|
+
const args = [
|
|
45323
|
+
{
|
|
45324
|
+
headers
|
|
45325
|
+
},
|
|
45326
|
+
_task.logger,
|
|
45327
|
+
params.proxyLoc,
|
|
45328
|
+
params.localIP,
|
|
45329
|
+
params.accountId
|
|
45330
|
+
];
|
|
45331
|
+
const http = new Http(...args);
|
|
45332
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45333
|
+
if (!a1Cookie) return {
|
|
45334
|
+
code: 414,
|
|
45335
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45336
|
+
data: {}
|
|
45337
|
+
};
|
|
45338
|
+
if (!params.action || !params.target_user_id) return {
|
|
45339
|
+
code: 414,
|
|
45340
|
+
message: "参数缺失,请检查后重试!",
|
|
45341
|
+
data: {}
|
|
45342
|
+
};
|
|
45343
|
+
const relationParams = {
|
|
45344
|
+
target_user_id: params.target_user_id
|
|
45345
|
+
};
|
|
45346
|
+
let relationActionRes;
|
|
45347
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45348
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45349
|
+
return acc;
|
|
45350
|
+
}, {});
|
|
45351
|
+
switch(params.action){
|
|
45352
|
+
case "follow":
|
|
45353
|
+
{
|
|
45354
|
+
const followMentions = "/api/sns/web/v1/user/follow";
|
|
45355
|
+
const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
|
|
45356
|
+
relationActionRes = await http.api({
|
|
45357
|
+
method: "post",
|
|
45358
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
|
|
45359
|
+
data: relationParams,
|
|
45360
|
+
headers: followXsHeader
|
|
45361
|
+
}, {
|
|
45362
|
+
retries: 3,
|
|
45363
|
+
retryDelay: 500,
|
|
45364
|
+
timeout: 3000
|
|
45365
|
+
});
|
|
45366
|
+
break;
|
|
45367
|
+
}
|
|
45368
|
+
case "unfollow":
|
|
45369
|
+
{
|
|
45370
|
+
const unfllowMentions = "/api/sns/web/v1/user/unfollow";
|
|
45371
|
+
const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
|
|
45372
|
+
relationActionRes = await http.api({
|
|
45373
|
+
method: "post",
|
|
45374
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
|
|
45375
|
+
data: relationParams,
|
|
45376
|
+
headers: unfllowXsHeader
|
|
45377
|
+
}, {
|
|
45378
|
+
retries: 3,
|
|
45379
|
+
retryDelay: 20,
|
|
45380
|
+
timeout: 3000
|
|
45381
|
+
});
|
|
45382
|
+
break;
|
|
45383
|
+
}
|
|
45384
|
+
default:
|
|
45385
|
+
return {
|
|
45386
|
+
code: 414,
|
|
45387
|
+
message: "参数action错误,请重试!",
|
|
45388
|
+
data: {}
|
|
45389
|
+
};
|
|
45390
|
+
}
|
|
45391
|
+
const isSuccess = 0 === relationActionRes.code;
|
|
45392
|
+
const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45393
|
+
const data = isSuccess ? relationActionRes.data : {
|
|
45394
|
+
fstatus: null
|
|
45395
|
+
};
|
|
45396
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45397
|
+
};
|
|
45398
|
+
const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
|
|
45399
|
+
const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
|
|
45400
|
+
keyword: classic_schemas_string(),
|
|
45401
|
+
page: classic_schemas_number(),
|
|
45402
|
+
page_size: classic_schemas_number(),
|
|
45403
|
+
sort_type: classic_schemas_enum([
|
|
45404
|
+
"general",
|
|
45405
|
+
"time_descending",
|
|
45406
|
+
"popular_descending"
|
|
45407
|
+
]),
|
|
45408
|
+
time_filter: classic_schemas_enum([
|
|
45409
|
+
"不限",
|
|
45410
|
+
"一周内"
|
|
45411
|
+
])
|
|
45412
|
+
});
|
|
45413
|
+
const createSearchId = ()=>{
|
|
45414
|
+
let r = BigInt(Date.now());
|
|
45415
|
+
const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
|
|
45416
|
+
r <<= BigInt(64);
|
|
45417
|
+
r += o;
|
|
45418
|
+
return r.toString(36);
|
|
45419
|
+
};
|
|
45420
|
+
const xiaohongshuWebSearch = async (_task, params)=>{
|
|
45421
|
+
const headers = {
|
|
45422
|
+
cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
|
|
45423
|
+
referer: "https://www.xiaohongshu.com/",
|
|
45424
|
+
origin: "https://www.xiaohongshu.com/"
|
|
45425
|
+
};
|
|
45426
|
+
const args = [
|
|
45427
|
+
{
|
|
45428
|
+
headers
|
|
45429
|
+
},
|
|
45430
|
+
_task.logger,
|
|
45431
|
+
params.proxyLoc,
|
|
45432
|
+
params.localIP,
|
|
45433
|
+
params.accountId
|
|
45434
|
+
];
|
|
45435
|
+
const http = new Http(...args);
|
|
45436
|
+
const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
|
|
45437
|
+
if (!a1Cookie) return {
|
|
45438
|
+
code: 414,
|
|
45439
|
+
message: "账号数据异常,请重新绑定账号后重试。",
|
|
45440
|
+
data: {}
|
|
45441
|
+
};
|
|
45442
|
+
if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
|
|
45443
|
+
if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
|
|
45444
|
+
code: 414,
|
|
45445
|
+
message: "排序类型参数错误,请检查后重试!",
|
|
45446
|
+
data: {}
|
|
45447
|
+
};
|
|
45448
|
+
if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
|
|
45449
|
+
code: 414,
|
|
45450
|
+
message: "时间过滤参数错误,请检查后重试!",
|
|
45451
|
+
data: {}
|
|
45452
|
+
};
|
|
45453
|
+
return {
|
|
45454
|
+
code: 414,
|
|
45455
|
+
message: "参数缺失,请检查后重试!",
|
|
45456
|
+
data: {}
|
|
45457
|
+
};
|
|
45458
|
+
}
|
|
45459
|
+
const filterPath = "/api/sns/web/v1/search/notes";
|
|
45460
|
+
const filterParams = {
|
|
45461
|
+
ext_flags: [],
|
|
45462
|
+
geo: "",
|
|
45463
|
+
image_formats: [
|
|
45464
|
+
"jpg",
|
|
45465
|
+
"webp",
|
|
45466
|
+
"avif"
|
|
45467
|
+
],
|
|
45468
|
+
filters: [
|
|
45469
|
+
{
|
|
45470
|
+
tags: [
|
|
45471
|
+
params.sort_type
|
|
45472
|
+
],
|
|
45473
|
+
type: "sort_type"
|
|
45474
|
+
},
|
|
45475
|
+
{
|
|
45476
|
+
tags: [
|
|
45477
|
+
"不限"
|
|
45478
|
+
],
|
|
45479
|
+
type: "filter_note_type"
|
|
45480
|
+
},
|
|
45481
|
+
{
|
|
45482
|
+
tags: [
|
|
45483
|
+
params.time_filter
|
|
45484
|
+
],
|
|
45485
|
+
type: "filter_note_time"
|
|
45486
|
+
},
|
|
45487
|
+
{
|
|
45488
|
+
tags: [
|
|
45489
|
+
"不限"
|
|
45490
|
+
],
|
|
45491
|
+
type: "filter_note_range"
|
|
45492
|
+
},
|
|
45493
|
+
{
|
|
45494
|
+
tags: [
|
|
45495
|
+
"不限"
|
|
45496
|
+
],
|
|
45497
|
+
type: "filter_pos_distance"
|
|
45498
|
+
}
|
|
45499
|
+
],
|
|
45500
|
+
keyword: params.keyword,
|
|
45501
|
+
note_type: 0,
|
|
45502
|
+
page: params.page,
|
|
45503
|
+
page_size: params.page_size,
|
|
45504
|
+
search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
|
|
45505
|
+
sort: "general"
|
|
45506
|
+
};
|
|
45507
|
+
const recordCookie = params.cookies.reduce((acc, cookie)=>{
|
|
45508
|
+
if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
|
|
45509
|
+
return acc;
|
|
45510
|
+
}, {});
|
|
45511
|
+
const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
|
|
45512
|
+
const res = await http.api({
|
|
45513
|
+
method: "post",
|
|
45514
|
+
url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
|
|
45515
|
+
data: filterParams,
|
|
45516
|
+
headers: searchXsHeader
|
|
45517
|
+
}, {
|
|
45518
|
+
retries: 3,
|
|
45519
|
+
retryDelay: 20,
|
|
45520
|
+
timeout: 3000
|
|
45521
|
+
});
|
|
45522
|
+
const isSuccess = 0 === res.code;
|
|
45523
|
+
const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
|
|
45524
|
+
const data = isSuccess ? res.data : {};
|
|
45525
|
+
return utils_response(isSuccess ? 0 : 414, message, data);
|
|
45526
|
+
};
|
|
45527
|
+
const ttConfigDataSchema = classic_schemas_object({
|
|
45528
|
+
fansNum: classic_schemas_number(),
|
|
45529
|
+
fansNumYesterday: classic_schemas_number().nullable(),
|
|
45530
|
+
readNum: classic_schemas_number(),
|
|
45531
|
+
incomeNum: classic_schemas_number(),
|
|
45532
|
+
incomeNumYesterday: classic_schemas_number().nullable(),
|
|
45533
|
+
showNumYesterday: classic_schemas_number().nullable(),
|
|
45534
|
+
readNumYesterday: classic_schemas_number().nullable(),
|
|
45535
|
+
likeNumYesterday: classic_schemas_number().nullable(),
|
|
45536
|
+
commentNumYesterday: classic_schemas_number().nullable()
|
|
45537
|
+
});
|
|
45538
|
+
const xhsConfigDataSchema = classic_schemas_object({
|
|
45539
|
+
fansNum: classic_schemas_number(),
|
|
45540
|
+
favedNum: classic_schemas_number(),
|
|
45541
|
+
watchNumLastWeek: classic_schemas_number(),
|
|
45542
|
+
likeNumLastWeek: classic_schemas_number(),
|
|
45543
|
+
collectNumLastWeek: classic_schemas_number(),
|
|
45544
|
+
commentNumLastWeek: classic_schemas_number(),
|
|
45545
|
+
fansNumLastWeek: classic_schemas_number(),
|
|
45546
|
+
fansNumYesterday: classic_schemas_number()
|
|
45547
|
+
});
|
|
45548
|
+
const wxConfigDataSchema = classic_schemas_object({
|
|
45549
|
+
fansNum: classic_schemas_number(),
|
|
45550
|
+
fansNumYesterday: classic_schemas_number(),
|
|
45551
|
+
readNumYesterday: classic_schemas_number(),
|
|
45552
|
+
shareNumYesterday: classic_schemas_number()
|
|
45553
|
+
});
|
|
45554
|
+
const bjhConfigDataSchema = classic_schemas_object({
|
|
45555
|
+
fansNum: classic_schemas_number(),
|
|
45556
|
+
fansNumYesterday: classic_schemas_number().nullable(),
|
|
45557
|
+
readNum: classic_schemas_number(),
|
|
45558
|
+
incomeNum: classic_schemas_number(),
|
|
45559
|
+
incomeNumYesterday: classic_schemas_number().nullable(),
|
|
45560
|
+
recommendNumYesterday: classic_schemas_number().nullable(),
|
|
45561
|
+
readNumYesterday: classic_schemas_number().nullable(),
|
|
45562
|
+
likeNumYesterday: classic_schemas_number().nullable(),
|
|
45563
|
+
commentNumYesterday: classic_schemas_number().nullable()
|
|
45564
|
+
});
|
|
44573
45565
|
const BetaFlag = "HuiwenCanary";
|
|
44574
45566
|
class Action {
|
|
44575
45567
|
constructor(task){
|