@iflyrpa/actions 3.0.2 → 3.0.4

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/index.js CHANGED
@@ -5490,7 +5490,7 @@ var __webpack_exports__ = {};
5490
5490
  const package_json_namespaceObject = require("@iflyrpa/share/package.json");
5491
5491
  var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
5492
5492
  var package_namespaceObject = {
5493
- i8: "3.0.1"
5493
+ i8: "3.0.3"
5494
5494
  };
5495
5495
  const share_namespaceObject = require("@iflyrpa/share");
5496
5496
  const external_node_fs_namespaceObject = require("node:fs");
@@ -5521,7 +5521,7 @@ var __webpack_exports__ = {};
5521
5521
  };
5522
5522
  const ProxyInfo = await http.api({
5523
5523
  method: "POST",
5524
- url: "http://172.29.194.32:9998/pool/eip/proxy",
5524
+ url: "https://fetdev.iflysec.com/ip-pool/pool/eip/proxy",
5525
5525
  data: params
5526
5526
  }).catch((err)=>{
5527
5527
  throw {
@@ -9696,7 +9696,7 @@ var __webpack_exports__ = {};
9696
9696
  data: null
9697
9697
  });
9698
9698
  const MockPublish = false;
9699
- const DisabledReq = true;
9699
+ const DisabledReq = false;
9700
9700
  const scanRetryMaxCount = 60;
9701
9701
  const waitQrcodeResultMaxTime = 2000 * scanRetryMaxCount;
9702
9702
  const rpaServer = async (task, params)=>{
@@ -14564,29 +14564,54 @@ var __webpack_exports__ = {};
14564
14564
  })}`);
14565
14565
  task.logger.info(`publishData: ${JSON.stringify(publishData)}`);
14566
14566
  task.logger.info(`url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
14567
- const publishResult = await proxyHttp.api({
14568
- method: "post",
14569
- url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
14570
- data: publishData,
14571
- defaultErrorMsg: "发布异常,请稍后重试。",
14572
- headers: {
14573
- ...headers,
14574
- Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
14575
- "Content-Type": "application/json",
14576
- Accept: "application/json, text/plain, */*",
14577
- "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
14578
- "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
14579
- "bd-ticket-guard-version": "2",
14580
- "bd-ticket-guard-web-sign-type": "1",
14581
- "bd-ticket-guard-web-version": "2",
14582
- "x-secsdk-csrf-token": csrfToken,
14583
- "x-tt-session-dtrait": sessionDtrait || ""
14584
- }
14585
- }, {
14586
- timeout: 60000,
14587
- retries: 3,
14588
- retryDelay: 2000
14589
- });
14567
+ let publishResult;
14568
+ try {
14569
+ publishResult = await proxyHttp.api({
14570
+ method: "post",
14571
+ url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
14572
+ data: publishData,
14573
+ defaultErrorMsg: "发布异常,请稍后重试。",
14574
+ headers: {
14575
+ ...headers,
14576
+ Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
14577
+ "Content-Type": "application/json",
14578
+ Accept: "application/json, text/plain, */*",
14579
+ "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
14580
+ "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
14581
+ "bd-ticket-guard-version": "2",
14582
+ "bd-ticket-guard-web-sign-type": "1",
14583
+ "bd-ticket-guard-web-version": "2",
14584
+ "x-secsdk-csrf-token": csrfToken,
14585
+ "x-tt-session-dtrait": sessionDtrait || ""
14586
+ }
14587
+ }, {
14588
+ timeout: 60000,
14589
+ retries: 3,
14590
+ retryDelay: 2000
14591
+ });
14592
+ } catch (error) {
14593
+ const upstreamMessage = error?.message || String(error);
14594
+ const upstreamCode = error?.code;
14595
+ task.logger.error(`TaskId:${task.taskId},create_v2 请求异常,上游错误已屏蔽。上游 code=${upstreamCode},message=${upstreamMessage}`, {
14596
+ error,
14597
+ upstreamData: error?.data,
14598
+ extra: error?.extra
14599
+ });
14600
+ const message = "发布失败,请重试";
14601
+ await updateTaskState?.({
14602
+ state: share_namespaceObject.TaskState.FAILED,
14603
+ error: message,
14604
+ result: {
14605
+ data: decision,
14606
+ uploadedImgList: JSON.stringify(publishData.item.common.images)
14607
+ }
14608
+ });
14609
+ return {
14610
+ code: 414,
14611
+ data: "",
14612
+ message
14613
+ };
14614
+ }
14590
14615
  reportLogger({
14591
14616
  token: params.huiwenToken || "",
14592
14617
  enverionment: task.enverionment || "development",
@@ -23291,697 +23316,626 @@ var __webpack_exports__ = {};
23291
23316
  if ("server" === params.actionType) return xiaohongshuLogin_rpa_server_rpaServer(task, params);
23292
23317
  return executeAction(xiaohongshuLogin_rpa_rpaAction)(task, params);
23293
23318
  };
23294
- const FictionalRendition = schemas_object({
23295
- type: literal("fictional-rendition")
23296
- });
23297
- const AIGenerated = schemas_object({
23298
- type: literal("ai-generated")
23299
- });
23300
- const SourceStatement = schemas_object({
23301
- type: literal("source-statement"),
23302
- childType: schemas_enum([
23303
- "self-labeling",
23304
- "self-shooting",
23305
- "transshipment"
23306
- ]),
23307
- shootingLocation: custom().optional(),
23308
- shootingDate: schemas_string().optional(),
23309
- sourceMedia: schemas_string().optional()
23310
- });
23311
- union([
23312
- FictionalRendition,
23313
- AIGenerated,
23314
- SourceStatement
23315
- ]);
23316
- const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
23317
- banners: schemas_array(schemas_string()),
23318
- title: schemas_string(),
23319
- content: schemas_string(),
23320
- address: custom().optional(),
23321
- selfDeclaration: custom().optional(),
23322
- topic: schemas_array(custom()).optional(),
23323
- proxyLoc: schemas_string().optional(),
23324
- localIP: schemas_string().optional(),
23325
- huiwenToken: schemas_string().optional(),
23326
- visibleRange: schemas_enum([
23327
- "public",
23328
- "private",
23329
- "friends"
23330
- ]),
23331
- isImmediatelyPublish: schemas_boolean().optional(),
23332
- scheduledPublish: schemas_string().optional(),
23333
- collectionId: schemas_string().optional(),
23334
- collectionBind: custom().optional(),
23335
- groupBind: custom().optional(),
23336
- noteCopyBind: schemas_boolean().optional(),
23337
- coProduceBind: schemas_boolean().optional(),
23338
- originalBind: schemas_boolean().optional()
23339
- });
23340
- const xiaohongshuPublish = async (_task, _params)=>({
23319
+ let _windowCache = null;
23320
+ const getWindow = ()=>{
23321
+ if (_windowCache) return _windowCache;
23322
+ _windowCache = "undefined" != typeof window ? window : globalThis;
23323
+ return _windowCache;
23324
+ };
23325
+ if ("undefined" != typeof process) {
23326
+ process.on("uncaughtException", ()=>{});
23327
+ process.on("unhandledRejection", ()=>{});
23328
+ }
23329
+ const mnsv2_enc = (arg1, arg2, cookieString)=>{
23330
+ const win = getWindow();
23331
+ win.ck = cookieString;
23332
+ __webpack_require__("./src/utils/xhs_ob_feed/ob.env.js");
23333
+ try {
23334
+ __webpack_require__("./src/utils/xhs_ob_feed/ob.enc.js");
23335
+ } catch {}
23336
+ let result = "";
23337
+ try {
23338
+ result = win.mnsv2(arg1, arg2);
23339
+ } catch {}
23340
+ return result;
23341
+ };
23342
+ const mnsvc2 = mnsv2_enc;
23343
+ const xhs_ob_feed_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob_feed/x_s.encoder.js");
23344
+ class xhs_ob_feed_Xhshow {
23345
+ stringifyCookies(cookies) {
23346
+ return Object.entries(cookies).map(([key, value])=>`${key}=${value}`).join("; ");
23347
+ }
23348
+ signHeadersGet(uri, cookieString, xsecAppid = "ugc", params) {
23349
+ let para1 = "";
23350
+ if (params && 0 !== Object.keys(params).length) {
23351
+ const _queryPara = Object.entries(params).map(([key, value])=>{
23352
+ let valueStr = "";
23353
+ if (Array.isArray(value)) valueStr = value.map((v)=>String(v)).join(",");
23354
+ else if (null != value) valueStr = String(value);
23355
+ return `${key}=${valueStr}`;
23356
+ });
23357
+ para1 = `${uri}?${_queryPara.join("&")}`;
23358
+ } else para1 = uri;
23359
+ const md5Para1 = external_node_crypto_default().createHash("md5").update(para1).digest("hex");
23360
+ const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23361
+ return {
23362
+ "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23363
+ };
23364
+ }
23365
+ signHeadersPost(uri, cookieString, xsecAppid = "ugc", payload) {
23366
+ const para1 = uri + JSON.stringify(payload || {});
23367
+ const md5Para1 = external_node_crypto_default().createHash("md5").update(para1).digest("hex");
23368
+ const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23369
+ return {
23370
+ "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23371
+ };
23372
+ }
23373
+ }
23374
+ const xiaohongshuPublish_mock_errnoMap = {
23375
+ "-1": "未知拦截器错误,请稍后重试。",
23376
+ 915: "所属C端账号手机号被修改,请重新登录",
23377
+ 914: "所属C端账号密码被修改,请重新登录",
23378
+ 903: "账户已登出,需重新登陆重试!",
23379
+ 902: "登录已过期,请重新登录!",
23380
+ 906: "账号存在风险,请重新登录!",
23381
+ "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
23382
+ };
23383
+ const mock_xsEncrypt = new xhs_ob_feed_Xhshow();
23384
+ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23385
+ const tmpCachePath = task.getTmpPath();
23386
+ if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
23341
23387
  code: 414,
23342
- data: "",
23343
- message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
23344
- });
23345
- const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
23346
- const xiaohongshuWebCommentAction = async (_task, params)=>{
23347
- if (DisabledReq) return (0, share_namespaceObject.response)(414, "点赞相关操作失败", {});
23348
- const headers = {
23349
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23350
- referer: "https://www.xiaohongshu.com/",
23351
- origin: "https://www.xiaohongshu.com/"
23388
+ message: "原创声明与转载声明互斥,请重新选择后发布!",
23389
+ data: ""
23352
23390
  };
23353
- const args = [
23354
- {
23355
- headers
23356
- },
23357
- _task.logger,
23358
- params.proxyLoc,
23359
- params.localIP,
23360
- params.accountId
23361
- ];
23362
- const http = new Http(...args);
23363
23391
  const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23364
23392
  if (!a1Cookie) return {
23365
23393
  code: 414,
23366
23394
  message: "账号数据异常,请重新绑定账号后重试。",
23367
- data: []
23368
- };
23369
- if (!params.note_id && !params.comment_id && !params.action) return {
23370
- code: 414,
23371
- message: "参数缺失,请检查后重试!",
23372
- data: {}
23373
- };
23374
- const actionParams = {
23375
- note_id: params.note_id,
23376
- comment_id: params.comment_id
23395
+ data: ""
23377
23396
  };
23378
- let likeActionRes = {
23379
- code: 500,
23380
- success: false,
23381
- msg: ""
23397
+ const headers = {
23398
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23399
+ origin: "https://creator.xiaohongshu.com",
23400
+ referer: "https://creator.xiaohongshu.com/",
23401
+ "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"
23382
23402
  };
23383
23403
  const recordCookie = params.cookies.reduce((acc, cookie)=>{
23384
23404
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23385
23405
  return acc;
23386
23406
  }, {});
23387
- switch(params.action){
23388
- case "like":
23389
- {
23390
- const likeAction = "/api/sns/web/v1/comment/like";
23391
- const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
23392
- likeActionRes = await http.api({
23393
- method: "post",
23394
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
23395
- data: actionParams,
23396
- headers: likeActionXsHeader
23397
- }, {
23398
- retries: 3,
23399
- retryDelay: 20,
23400
- timeout: 3000
23401
- });
23402
- break;
23403
- }
23404
- case "dislike":
23405
- {
23406
- const dislikeMentions = "/api/sns/web/v1/comment/dislike";
23407
- const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
23408
- likeActionRes = await http.api({
23409
- method: "post",
23410
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
23411
- data: actionParams,
23412
- headers: dislikeXsHeader
23413
- }, {
23414
- retries: 3,
23415
- retryDelay: 20,
23416
- timeout: 3000
23417
- });
23418
- break;
23419
- }
23420
- default:
23421
- return {
23422
- code: 414,
23423
- message: "参数action错误,请重试!",
23424
- data: {}
23425
- };
23426
- }
23427
- const isSuccess = 0 === likeActionRes.code;
23428
- const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23429
- const data = isSuccess ? likeActionRes.success : {};
23430
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23431
- };
23432
- const xiaohongshuWebIntimacySearch = async (_task, params)=>{
23433
- if (DisabledReq) return (0, share_namespaceObject.response)(0, "搜索@列表数据成功", []);
23434
- const headers = {
23435
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23436
- referer: "https://www.xiaohongshu.com/",
23437
- origin: "https://www.xiaohongshu.com"
23438
- };
23439
23407
  const args = [
23440
23408
  {
23441
23409
  headers
23442
23410
  },
23443
- _task.logger,
23411
+ task.logger,
23444
23412
  params.proxyLoc,
23445
23413
  params.localIP,
23446
23414
  params.accountId
23447
23415
  ];
23448
- const http = new Http(...args);
23449
- let intimacyDetail = [];
23450
- const res = await http.api({
23451
- method: "get",
23452
- url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
23453
- ...params.searchValue ? {
23454
- params: {
23455
- keyword: params.searchValue,
23456
- page: 1,
23457
- rows: 30
23458
- }
23459
- } : {}
23460
- }, {
23461
- retries: 3,
23462
- retryDelay: 20,
23463
- timeout: 3000
23416
+ const http = new Http({
23417
+ headers
23464
23418
  });
23465
- const isSuccess = 0 === res.code;
23466
- if (isSuccess) intimacyDetail = res.data.items;
23467
- const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23468
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, intimacyDetail);
23469
- };
23470
- const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
23471
- const xiaohongshuWebMsgRead = async (_task, params)=>{
23472
- if (DisabledReq) return (0, share_namespaceObject.response)(414, "Read指定Tab失败", {});
23473
- const headers = {
23474
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23475
- referer: "https://www.xiaohongshu.com/",
23476
- origin: "https://www.xiaohongshu.com/"
23419
+ const proxyHttp = new Http(...args);
23420
+ proxyHttp.addResponseInterceptor((response)=>{
23421
+ const responseData = response.data;
23422
+ if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
23423
+ const errmsg = xiaohongshuPublish_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
23424
+ return {
23425
+ code: xiaohongshuPublish_mock_errnoMap[responseData.code] ? 414 : 500,
23426
+ message: errmsg,
23427
+ data: responseData
23428
+ };
23429
+ }
23430
+ });
23431
+ const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
23432
+ const fetchCoverParams = {
23433
+ biz_name: "spectrum",
23434
+ scene: "image",
23435
+ file_count: params.banners.length,
23436
+ version: 1,
23437
+ source: "web"
23477
23438
  };
23478
- const args = [
23479
- {
23480
- headers
23481
- },
23482
- _task.logger,
23483
- params.proxyLoc,
23484
- params.localIP,
23485
- params.accountId
23486
- ];
23487
- const http = new Http(...args);
23488
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23489
- if (!a1Cookie) return {
23439
+ const fetchCoverXsHeader = mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
23440
+ const uploadInfos = [];
23441
+ if (params.banners.length > 18) {
23442
+ const num = Math.ceil(params.banners.length / 14);
23443
+ for(let i = 0; i < num; i++){
23444
+ const start = 14 * i;
23445
+ params.banners.length;
23446
+ ({
23447
+ ...fetchCoverParams
23448
+ });
23449
+ const batchCoverIdInfo = await proxyHttp.api({
23450
+ method: "get",
23451
+ baseURL: "https://creator.xiaohongshu.com",
23452
+ url: fetchCoverUrl,
23453
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23454
+ headers: fetchCoverXsHeader,
23455
+ params: fetchCoverParams
23456
+ }, {
23457
+ retries: 3,
23458
+ retryDelay: 20,
23459
+ timeout: 3000
23460
+ });
23461
+ for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
23462
+ bucket: item.bucket || "",
23463
+ uploadAddr: item.uploadAddr || "",
23464
+ fileIds: fileId,
23465
+ token: item.token || ""
23466
+ });
23467
+ }
23468
+ } else {
23469
+ const coverIdInfo = await proxyHttp.api({
23470
+ method: "get",
23471
+ baseURL: "https://creator.xiaohongshu.com",
23472
+ url: fetchCoverUrl,
23473
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23474
+ headers: fetchCoverXsHeader,
23475
+ params: fetchCoverParams
23476
+ }, {
23477
+ retries: 3,
23478
+ retryDelay: 20,
23479
+ timeout: 3000
23480
+ });
23481
+ for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
23482
+ bucket: item.bucket || "",
23483
+ uploadAddr: item.uploadAddr || "",
23484
+ fileIds: fileId,
23485
+ token: item.token || ""
23486
+ });
23487
+ }
23488
+ if (uploadInfos.length < params.banners.length) return {
23490
23489
  code: 414,
23491
- message: "账号数据异常,请重新绑定账号后重试。",
23492
- data: []
23490
+ message: "可用 OSS bucket 数量不足,无法上传所有图片!",
23491
+ data: ""
23493
23492
  };
23494
- if (!params.type) return {
23493
+ if (0 === uploadInfos.length) return {
23495
23494
  code: 414,
23496
- message: "参数缺失,请检查后重试!",
23497
- data: {}
23498
- };
23499
- const replyParams = {
23500
- type: params.type
23501
- };
23502
- const fatchMentions = "/api/sns/web/v1/message/read";
23503
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23504
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23505
- return acc;
23506
- }, {});
23507
- const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
23508
- const res = await http.api({
23509
- method: "post",
23510
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
23511
- data: replyParams,
23512
- headers: fatchMentionsXsHeader
23513
- }, {
23514
- retries: 3,
23515
- retryDelay: 20,
23516
- timeout: 3000
23517
- });
23518
- const isSuccess = 0 === res.code;
23519
- const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23520
- const data = isSuccess ? res.success : {};
23521
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23522
- };
23523
- const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
23524
- const xiaohongshuWebMsgReply = async (_task, params)=>{
23525
- if (DisabledReq) return (0, share_namespaceObject.response)(414, "评论回复失败", {});
23526
- const headers = {
23527
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23528
- referer: "https://www.xiaohongshu.com/",
23529
- origin: "https://www.xiaohongshu.com/"
23495
+ message: "图片上传失败,请稍后重试!",
23496
+ data: ""
23530
23497
  };
23531
- const args = [
23532
- {
23533
- headers
23534
- },
23535
- _task.logger,
23536
- params.proxyLoc,
23537
- params.localIP,
23538
- params.accountId
23539
- ];
23540
- const http = new Http(...args);
23541
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23542
- if (!a1Cookie) return {
23543
- code: 414,
23544
- message: "账号数据异常,请重新绑定账号后重试。",
23545
- data: []
23498
+ const availableBuckets = Array.from({
23499
+ length: uploadInfos.length
23500
+ }, (_, i)=>i);
23501
+ const uploadFile = async (url, index)=>{
23502
+ const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
23503
+ const localUrl = await (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
23504
+ const fileBuffer = external_node_fs_default().readFileSync(localUrl);
23505
+ const MAX_RETRIES = uploadInfos.length;
23506
+ let attempt = 0;
23507
+ while(attempt < MAX_RETRIES){
23508
+ const ossBucketIndex = availableBuckets.shift();
23509
+ if (void 0 === ossBucketIndex) break;
23510
+ const currentInfo = uploadInfos[ossBucketIndex];
23511
+ const ossFileId = currentInfo.fileIds;
23512
+ const ossToken = currentInfo.token;
23513
+ const ossDomain = currentInfo.uploadAddr;
23514
+ try {
23515
+ await http.api({
23516
+ method: "put",
23517
+ url: `https://${ossDomain}/${ossFileId}`,
23518
+ data: fileBuffer,
23519
+ headers: {
23520
+ "x-cos-security-token": ossToken
23521
+ },
23522
+ defaultErrorMsg: "图片上传异常,请稍后重试发布。"
23523
+ });
23524
+ return {
23525
+ ossFileId,
23526
+ ossToken
23527
+ };
23528
+ } catch (error) {
23529
+ attempt++;
23530
+ }
23531
+ }
23532
+ return {
23533
+ ossFileId: "",
23534
+ ossToken: ""
23535
+ };
23546
23536
  };
23547
- if (!params.note_id || !params.target_comment_id || !params.content) return {
23537
+ const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
23538
+ const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
23539
+ if (invalidUpload) return {
23548
23540
  code: 414,
23549
- message: "参数缺失,请检查后重试!",
23550
- data: {}
23541
+ message: "图片上传异常,请稍后重试发布。",
23542
+ data: ""
23551
23543
  };
23552
- const replyParams = {
23553
- at_users: params.at_users ?? [],
23554
- content: params.content,
23555
- note_id: params.note_id,
23556
- target_comment_id: params.target_comment_id
23544
+ if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
23545
+ if (!topic.id) {
23546
+ const topicData = {
23547
+ topic_names: topic.name
23548
+ };
23549
+ const topicXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
23550
+ const createTopic = await proxyHttp.api({
23551
+ method: "POST",
23552
+ url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
23553
+ headers: topicXsHeader,
23554
+ data: topicData,
23555
+ defaultErrorMsg: "话题创建异常,请稍后重试。"
23556
+ }, {
23557
+ retries: 3,
23558
+ retryDelay: 20,
23559
+ timeout: 3000
23560
+ });
23561
+ if (!createTopic?.data) throw types_errorResponse("话题创建失败,请检查话题字段!", 414);
23562
+ Object.assign(topic, createTopic?.data?.topic_infos[0]);
23563
+ }
23564
+ }));
23565
+ const visibleRangeMap = {
23566
+ public: 0,
23567
+ private: 1,
23568
+ friends: 4
23557
23569
  };
23558
- const replyPath = "/api/sns/web/v1/comment/post";
23559
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23560
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23561
- return acc;
23562
- }, {});
23563
- const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
23564
- const res = await http.api({
23565
- method: "post",
23566
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
23567
- data: replyParams,
23568
- headers: replyXsHeader
23569
- }, {
23570
- retries: 3,
23571
- retryDelay: 20,
23572
- timeout: 3000
23573
- });
23574
- const isSuccess = 0 === res.code;
23575
- const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23576
- const data = isSuccess ? res.data : {};
23577
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23578
- };
23579
- let _windowCache = null;
23580
- const getWindow = ()=>{
23581
- if (_windowCache) return _windowCache;
23582
- _windowCache = "undefined" != typeof window ? window : globalThis;
23583
- return _windowCache;
23584
- };
23585
- if ("undefined" != typeof process) {
23586
- process.on("uncaughtException", ()=>{});
23587
- process.on("unhandledRejection", ()=>{});
23588
- }
23589
- const mnsv2_enc = (arg1, arg2, cookieString)=>{
23590
- const win = getWindow();
23591
- win.ck = cookieString;
23592
- __webpack_require__("./src/utils/xhs_ob_feed/ob.env.js");
23593
- try {
23594
- __webpack_require__("./src/utils/xhs_ob_feed/ob.enc.js");
23595
- } catch {}
23596
- let result = "";
23597
- try {
23598
- result = win.mnsv2(arg1, arg2);
23599
- } catch {}
23600
- return result;
23601
- };
23602
- const mnsvc2 = mnsv2_enc;
23603
- const xhs_ob_feed_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob_feed/x_s.encoder.js");
23604
- class xhs_ob_feed_Xhshow {
23605
- stringifyCookies(cookies) {
23606
- return Object.entries(cookies).map(([key, value])=>`${key}=${value}`).join("; ");
23607
- }
23608
- signHeadersGet(uri, cookieString, xsecAppid = "ugc", params) {
23609
- let para1 = "";
23610
- if (params && 0 !== Object.keys(params).length) {
23611
- const _queryPara = Object.entries(params).map(([key, value])=>{
23612
- let valueStr = "";
23613
- if (Array.isArray(value)) valueStr = value.map((v)=>String(v)).join(",");
23614
- else if (null != value) valueStr = String(value);
23615
- return `${key}=${valueStr}`;
23616
- });
23617
- para1 = `${uri}?${_queryPara.join("&")}`;
23618
- } else para1 = uri;
23619
- const md5Para1 = external_node_crypto_default().createHash("md5").update(para1).digest("hex");
23620
- const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23621
- return {
23622
- "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23623
- };
23624
- }
23625
- signHeadersPost(uri, cookieString, xsecAppid = "ugc", payload) {
23626
- const para1 = uri + JSON.stringify(payload || {});
23627
- const md5Para1 = external_node_crypto_default().createHash("md5").update(para1).digest("hex");
23628
- const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23629
- return {
23630
- "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23631
- };
23632
- }
23633
- }
23634
- const xiaohongshuWebNoteFeed_xsEncrypt = new xhs_ob_feed_Xhshow();
23635
- const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
23636
- const xiaohongshuWebNoteFeed = async (_task, params)=>{
23637
- if (DisabledReq) return (0, share_namespaceObject.response)(414, "获取指定文章详情失败", {});
23638
- const headers = {
23639
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23640
- referer: "https://www.xiaohongshu.com/",
23641
- origin: "https://www.xiaohongshu.com/"
23642
- };
23643
- const args = [
23644
- {
23645
- headers
23570
+ const publishData = {
23571
+ common: {
23572
+ ats: [],
23573
+ biz_relations: [],
23574
+ desc: params?.content,
23575
+ goods_info: {},
23576
+ hash_tag: params.topic || [],
23577
+ note_id: "",
23578
+ source: JSON.stringify({
23579
+ type: "web",
23580
+ ids: "",
23581
+ extraInfo: '{"systemId":"web"}'
23582
+ }),
23583
+ title: params?.title,
23584
+ type: "normal",
23585
+ privacy_info: {
23586
+ op_type: 1,
23587
+ type: visibleRangeMap[params.visibleRange]
23588
+ },
23589
+ post_loc: params.address ? {
23590
+ name: params.address?.name,
23591
+ poi_id: params.address?.poi_id,
23592
+ poi_type: params.address?.poi_type,
23593
+ subname: params.address?.full_address
23594
+ } : null,
23595
+ business_binds: ""
23646
23596
  },
23647
- _task.logger,
23648
- params.proxyLoc,
23649
- params.localIP,
23650
- params.accountId
23651
- ];
23652
- const http = new Http(...args);
23653
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23654
- if (!a1Cookie) return {
23655
- code: 414,
23656
- message: "账号数据异常,请重新绑定账号后重试。",
23657
- data: {}
23658
- };
23659
- if (!params.source_note_id && !params.xsec_token) return {
23660
- code: 414,
23661
- message: "参数缺失,请检查后重试!",
23662
- data: {}
23663
- };
23664
- const feedParams = {
23665
- source_note_id: params.source_note_id,
23666
- image_formats: [
23667
- "jpg",
23668
- "webp",
23669
- "avif"
23670
- ],
23671
- extra: {
23672
- need_body_topic: "1"
23597
+ image_info: {
23598
+ images: coverInfos.map((it)=>({
23599
+ extra_info_json: '{"mimeType":"image/png"}',
23600
+ file_id: it.ossFileId,
23601
+ metadata: {
23602
+ source: -1
23603
+ },
23604
+ stickers: {
23605
+ floating: [],
23606
+ version: 2
23607
+ }
23608
+ }))
23673
23609
  },
23674
- xsec_source: "pc_feed",
23675
- xsec_token: params.xsec_token
23610
+ video_info: null
23676
23611
  };
23677
- const fatchFeed = "/api/sns/web/v1/feed";
23678
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23679
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23680
- return acc;
23681
- }, {});
23682
- const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
23683
- const xT = Date.now().toString();
23684
- const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
23685
- _task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
23686
- _task.logger.info(`X-S: ${xsHeader["X-S"]}`);
23687
- _task.logger.info(`x-s-common: ${xsCommon}`);
23688
- const res = await http.api({
23689
- method: "post",
23690
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
23691
- data: feedParams,
23692
- headers: {
23693
- "X-S": xsHeader["X-S"],
23694
- "X-S-Common": xsCommon,
23695
- "X-T": xT
23612
+ const userDeclarationBind = {
23613
+ origin: 2,
23614
+ photoInfo: {},
23615
+ repostInfo: {}
23616
+ };
23617
+ if (params.selfDeclaration?.type === "fictional-rendition") userDeclarationBind.origin = 1;
23618
+ else if (params.selfDeclaration?.type === "ai-generated") userDeclarationBind.origin = 2;
23619
+ else if (params.selfDeclaration?.type === "source-statement") {
23620
+ if ("self-labeling" === params.selfDeclaration.childType) userDeclarationBind.origin = 3;
23621
+ else if ("self-shooting" === params.selfDeclaration.childType) {
23622
+ userDeclarationBind.origin = 4;
23623
+ const photoInfo = {};
23624
+ if (params.selfDeclaration.shootingLocation) photoInfo.photoPlace = {
23625
+ name: params.selfDeclaration.shootingLocation.name,
23626
+ poiId: params.selfDeclaration.shootingLocation.poi_id,
23627
+ poiType: params.selfDeclaration.shootingLocation.poi_type,
23628
+ subname: params.selfDeclaration.shootingLocation.full_address
23629
+ };
23630
+ if (params.selfDeclaration.shootingDate) photoInfo.photoTime = params.selfDeclaration.shootingDate;
23631
+ userDeclarationBind.photoInfo = photoInfo;
23632
+ } else if ("transshipment" === params.selfDeclaration.childType) {
23633
+ userDeclarationBind.origin = 5;
23634
+ if (params.selfDeclaration.sourceMedia) userDeclarationBind.repostInfo = {
23635
+ source: params.selfDeclaration.sourceMedia
23636
+ };
23696
23637
  }
23638
+ }
23639
+ const bizId = params?.originalBind && (params.cookies.find((it)=>"x-user-id-creator.xiaohongshu.com" === it.name)?.value || await proxyHttp.api({
23640
+ method: "get",
23641
+ url: "https://creator.xiaohongshu.com/api/galaxy/user/my-info"
23697
23642
  }, {
23698
23643
  retries: 3,
23699
23644
  retryDelay: 20,
23700
23645
  timeout: 3000
23701
- });
23702
- _task.logger.info(`API 响应: ${JSON.stringify(res)}`);
23703
- const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
23704
- const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23705
- const data = isSuccess ? res.data?.items[0].note_card || {} : {};
23706
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23707
- };
23708
- const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
23709
- const xiaohongshuWebRelationAction = async (_task, params)=>{
23710
- if (DisabledReq) return (0, share_namespaceObject.response)(414, "用户关系操作失败", {});
23711
- const headers = {
23712
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23713
- referer: "https://www.xiaohongshu.com/",
23714
- origin: "https://www.xiaohongshu.com/"
23715
- };
23716
- const args = [
23717
- {
23718
- headers
23646
+ }).then((userData)=>userData.data?.userDetail?.id));
23647
+ const business_binds = {
23648
+ version: 1,
23649
+ bizType: "",
23650
+ noteId: "",
23651
+ noteOrderBind: {},
23652
+ notePostTiming: params.isImmediatelyPublish ? {} : {
23653
+ postTime: params.scheduledPublish
23719
23654
  },
23720
- _task.logger,
23721
- params.proxyLoc,
23722
- params.localIP,
23723
- params.accountId
23724
- ];
23725
- const http = new Http(...args);
23726
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23727
- if (!a1Cookie) return {
23728
- code: 414,
23729
- message: "账号数据异常,请重新绑定账号后重试。",
23730
- data: {}
23731
- };
23732
- if (!params.action || !params.target_user_id) return {
23733
- code: 414,
23734
- message: "参数缺失,请检查后重试!",
23735
- data: {}
23736
- };
23737
- const relationParams = {
23738
- target_user_id: params.target_user_id
23739
- };
23740
- let relationActionRes;
23741
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23742
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23743
- return acc;
23744
- }, {});
23745
- switch(params.action){
23746
- case "follow":
23655
+ coProduceBind: {
23656
+ enable: !!params?.coProduceBind
23657
+ },
23658
+ noteCopyBind: {
23659
+ copyable: !!params?.noteCopyBind
23660
+ },
23661
+ optionRelationList: params.originalBind ? [
23747
23662
  {
23748
- const followMentions = "/api/sns/web/v1/user/follow";
23749
- const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
23750
- relationActionRes = await http.api({
23751
- method: "post",
23752
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
23753
- data: relationParams,
23754
- headers: followXsHeader
23755
- }, {
23756
- retries: 3,
23757
- retryDelay: 500,
23758
- timeout: 3000
23759
- });
23760
- break;
23663
+ type: "ORIGINAL_STATEMENT",
23664
+ relationList: [
23665
+ {
23666
+ bizId,
23667
+ bizType: "ORIGINAL_STATEMENT",
23668
+ extraInfo: "{}"
23669
+ }
23670
+ ]
23761
23671
  }
23762
- case "unfollow":
23763
- {
23764
- const unfllowMentions = "/api/sns/web/v1/user/unfollow";
23765
- const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
23766
- relationActionRes = await http.api({
23767
- method: "post",
23768
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
23769
- data: relationParams,
23770
- headers: unfllowXsHeader
23771
- }, {
23772
- retries: 3,
23773
- retryDelay: 20,
23774
- timeout: 3000
23775
- });
23776
- break;
23672
+ ] : [],
23673
+ ...params?.groupBind ? {
23674
+ groupBind: {
23675
+ groupId: params?.groupBind?.group_id,
23676
+ groupName: params.groupBind?.group_name,
23677
+ desc: params.groupBind?.desc,
23678
+ avatar: params.groupBind?.avatar
23777
23679
  }
23778
- default:
23779
- return {
23780
- code: 414,
23781
- message: "参数action错误,请重试!",
23782
- data: {}
23783
- };
23784
- }
23785
- const isSuccess = 0 === relationActionRes.code;
23786
- const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23787
- const data = isSuccess ? relationActionRes.data : {
23788
- fstatus: null
23680
+ } : {
23681
+ groupBind: {}
23682
+ },
23683
+ ...params.selfDeclaration ? {
23684
+ userDeclarationBind
23685
+ } : {},
23686
+ ...params?.collectionBind?.id ? {
23687
+ noteCollectionBind: {
23688
+ id: params.collectionBind.id
23689
+ }
23690
+ } : {}
23789
23691
  };
23692
+ publishData.common.business_binds = JSON.stringify(business_binds);
23693
+ const publishXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/v2/note", recordCookie, "ugc", publishData);
23694
+ task._timerRecord.PrePublish = Date.now();
23695
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23696
+ if (MockPublish) {
23697
+ const message = `文章模拟发布成功 ${http.proxyInfo}`;
23698
+ const data = "123456789";
23699
+ await updateTaskState?.({
23700
+ state: share_namespaceObject.TaskState.SUCCESS,
23701
+ result: {
23702
+ response: data
23703
+ }
23704
+ });
23705
+ return (0, share_namespaceObject.success)(data, message);
23706
+ }
23707
+ const publishResult = await proxyHttp.api({
23708
+ method: "post",
23709
+ url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
23710
+ data: publishData,
23711
+ headers: publishXsHeader,
23712
+ defaultErrorMsg: "文章发布异常,请稍后重试。"
23713
+ }, {
23714
+ retries: 2,
23715
+ retryDelay: 500,
23716
+ timeout: 12000
23717
+ });
23718
+ reportLogger({
23719
+ token: params.huiwenToken || "",
23720
+ enverionment: task.enverionment || "development",
23721
+ postId: params.articleId,
23722
+ eip: proxyHttp.proxyInfo,
23723
+ proxyIp: params.localIP,
23724
+ accountId: params.accountId,
23725
+ uid: params.uid,
23726
+ platform: "xiaohongshu",
23727
+ publishParams: publishData
23728
+ });
23729
+ const isSuccess = publishResult.success;
23730
+ const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
23731
+ const data = isSuccess ? publishResult.data?.id || "" : "";
23732
+ if (!isSuccess) {
23733
+ await updateTaskState?.({
23734
+ state: share_namespaceObject.TaskState.FAILED,
23735
+ error: message
23736
+ });
23737
+ return {
23738
+ code: 414,
23739
+ data,
23740
+ message
23741
+ };
23742
+ }
23743
+ await updateTaskState?.({
23744
+ state: share_namespaceObject.TaskState.SUCCESS,
23745
+ result: {
23746
+ response: data
23747
+ }
23748
+ });
23790
23749
  return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23791
23750
  };
23792
- const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
23793
- const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
23794
- keyword: schemas_string(),
23795
- page: schemas_number(),
23796
- page_size: schemas_number(),
23797
- sort_type: schemas_enum([
23798
- "general",
23799
- "time_descending",
23800
- "popular_descending"
23801
- ]),
23802
- time_filter: schemas_enum([
23803
- "不限",
23804
- "一周内"
23805
- ])
23806
- });
23807
- const createSearchId = ()=>{
23808
- let r = BigInt(Date.now());
23809
- const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
23810
- r <<= BigInt(64);
23811
- r += o;
23812
- return r.toString(36);
23813
- };
23814
- const xiaohongshuWebSearch = async (_task, params)=>{
23815
- const headers = {
23816
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23817
- referer: "https://www.xiaohongshu.com/",
23818
- origin: "https://www.xiaohongshu.com/"
23751
+ const xiaohongshuPublish_rpa_rpaAction = async (task, params)=>{
23752
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23753
+ const commonCookies = {
23754
+ path: "/",
23755
+ sameSite: "lax",
23756
+ secure: false,
23757
+ domain: ".xiaohongshu.com",
23758
+ url: "https://creator.xiaohongshu.com",
23759
+ httpOnly: true
23819
23760
  };
23820
- const args = [
23821
- {
23822
- headers
23823
- },
23824
- _task.logger,
23825
- params.proxyLoc,
23826
- params.localIP,
23827
- params.accountId
23828
- ];
23829
- const http = new Http(...args);
23830
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23831
- if (!a1Cookie) return {
23832
- code: 414,
23833
- message: "账号数据异常,请重新绑定账号后重试。",
23834
- data: {}
23761
+ const page = await task.createPage({
23762
+ show: task.debug,
23763
+ url: params.url || "https://creator.xiaohongshu.com/publish/publish",
23764
+ cookies: params.cookies?.map((it)=>({
23765
+ ...it,
23766
+ ...commonCookies
23767
+ }))
23768
+ });
23769
+ await updateTaskState?.({
23770
+ state: share_namespaceObject.TaskState.ACTION,
23771
+ connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
23772
+ sessionId: task.sessionId
23773
+ });
23774
+ const tmpCachePath = task.getTmpPath();
23775
+ const selectAddress = async (selector, address)=>{
23776
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23777
+ await instance.click();
23778
+ await instance.locator("input").fill(address);
23779
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
23780
+ await poperInstance.first().waitFor();
23781
+ await poperInstance.first().click();
23835
23782
  };
23836
- if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
23837
- if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
23838
- code: 414,
23839
- message: "排序类型参数错误,请检查后重试!",
23840
- data: {}
23841
- };
23842
- if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
23843
- code: 414,
23844
- message: "时间过滤参数错误,请检查后重试!",
23845
- data: {}
23846
- };
23783
+ const selectDate = async (selector, date)=>{
23784
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23785
+ await instance.click();
23786
+ await instance.fill(date);
23787
+ await instance.blur();
23788
+ };
23789
+ const getPoperInstance = async ()=>{
23790
+ await page.waitForTimeout(500);
23791
+ const elements = page.locator(".d-popover");
23792
+ const count = await elements.count();
23793
+ const visibleElements = [];
23794
+ for(let i = 0; i < count; i++){
23795
+ const element = elements.nth(i);
23796
+ const style = await element.getAttribute("style");
23797
+ if (style && !style.includes("display: none")) visibleElements.push(element);
23798
+ }
23799
+ if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
23800
+ throw new Error("未找到 popover 弹窗");
23801
+ };
23802
+ const getDialogInstance = async ()=>{
23803
+ await page.waitForTimeout(1000);
23804
+ const elements = page.locator(".el-dialog");
23805
+ return elements.last();
23806
+ };
23807
+ try {
23808
+ await page.waitForSelector("#CreatorPlatform", {
23809
+ state: "visible"
23810
+ });
23811
+ } catch (error) {
23847
23812
  return {
23848
23813
  code: 414,
23849
- message: "参数缺失,请检查后重试!",
23850
- data: {}
23814
+ message: "登录失效",
23815
+ data: page.url()
23851
23816
  };
23852
23817
  }
23853
- const filterPath = "/api/sns/web/v1/search/notes";
23854
- const filterParams = {
23855
- ext_flags: [],
23856
- geo: "",
23857
- image_formats: [
23858
- "jpg",
23859
- "webp",
23860
- "avif"
23861
- ],
23862
- filters: [
23863
- {
23864
- tags: [
23865
- params.sort_type
23866
- ],
23867
- type: "sort_type"
23868
- },
23869
- {
23870
- tags: [
23871
- "不限"
23872
- ],
23873
- type: "filter_note_type"
23874
- },
23875
- {
23876
- tags: [
23877
- params.time_filter
23878
- ],
23879
- type: "filter_note_time"
23880
- },
23881
- {
23882
- tags: [
23883
- "不限"
23884
- ],
23885
- type: "filter_note_range"
23886
- },
23887
- {
23888
- tags: [
23889
- "不限"
23890
- ],
23891
- type: "filter_pos_distance"
23892
- }
23893
- ],
23894
- keyword: params.keyword,
23895
- note_type: 0,
23896
- page: params.page,
23897
- page_size: params.page_size,
23898
- search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
23899
- sort: "general"
23900
- };
23901
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23902
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23903
- return acc;
23904
- }, {});
23905
- const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
23906
- const res = await http.api({
23907
- method: "post",
23908
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
23909
- data: filterParams,
23910
- headers: searchXsHeader
23911
- }, {
23912
- retries: 3,
23913
- retryDelay: 20,
23914
- timeout: 3000
23818
+ await page.locator("#content-area .menu-container .publish-video .btn-wrapper .btn-inner").click();
23819
+ await page.locator('.header-tabs .creator-tab:not([style*="-9999px"])').filter({
23820
+ hasText: /^上传图文$/
23821
+ }).click();
23822
+ const images = await Promise.all(params.banners.map((url)=>{
23823
+ const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
23824
+ return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
23825
+ }));
23826
+ const fileChooser = await page.$("input.upload-input");
23827
+ if (fileChooser) await fileChooser.setInputFiles(images);
23828
+ const titleInstance = page.locator(".input input");
23829
+ await titleInstance.waitFor({
23830
+ state: "visible",
23831
+ timeout: 50000
23915
23832
  });
23916
- const isSuccess = 0 === res.code;
23917
- const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23918
- const data = isSuccess ? res.data : {};
23919
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
23920
- };
23921
- const ttConfigDataSchema = schemas_object({
23922
- fansNum: schemas_number(),
23923
- fansNumYesterday: schemas_number().nullable(),
23924
- readNum: schemas_number(),
23925
- incomeNum: schemas_number(),
23926
- incomeNumYesterday: schemas_number().nullable(),
23927
- showNumYesterday: schemas_number().nullable(),
23928
- readNumYesterday: schemas_number().nullable(),
23929
- likeNumYesterday: schemas_number().nullable(),
23930
- commentNumYesterday: schemas_number().nullable()
23931
- });
23932
- const xhsConfigDataSchema = schemas_object({
23933
- fansNum: schemas_number(),
23934
- favedNum: schemas_number(),
23935
- watchNumLastWeek: schemas_number(),
23936
- likeNumLastWeek: schemas_number(),
23937
- collectNumLastWeek: schemas_number(),
23938
- commentNumLastWeek: schemas_number(),
23939
- fansNumLastWeek: schemas_number(),
23940
- fansNumYesterday: schemas_number()
23941
- });
23942
- const wxConfigDataSchema = schemas_object({
23943
- fansNum: schemas_number(),
23944
- fansNumYesterday: schemas_number(),
23945
- readNumYesterday: schemas_number(),
23946
- shareNumYesterday: schemas_number()
23947
- });
23948
- const bjhConfigDataSchema = schemas_object({
23949
- fansNum: schemas_number(),
23950
- fansNumYesterday: schemas_number().nullable(),
23951
- readNum: schemas_number(),
23952
- incomeNum: schemas_number(),
23953
- incomeNumYesterday: schemas_number().nullable(),
23954
- recommendNumYesterday: schemas_number().nullable(),
23955
- readNumYesterday: schemas_number().nullable(),
23956
- likeNumYesterday: schemas_number().nullable(),
23957
- commentNumYesterday: schemas_number().nullable()
23958
- });
23959
- const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
23960
- function Md5(input) {
23961
- return external_node_crypto_default().createHash("md5").update(input).digest("hex");
23962
- }
23963
- const rpa_server_mock_errnoMap = {
23964
- "-1": "未知拦截器错误,请稍后重试。",
23965
- 915: "所属C端账号手机号被修改,请重新登录",
23966
- 914: "所属C端账号密码被修改,请重新登录",
23967
- 903: "账户已登出,需重新登陆重试!",
23968
- 902: "登录已过期,请重新登录!",
23969
- 906: "账号存在风险,请重新登录!",
23970
- "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
23833
+ await titleInstance.click();
23834
+ await titleInstance.fill(params.title);
23835
+ const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
23836
+ await descInstance.click();
23837
+ await descInstance.pressSequentially(params.content.replace(/#.*?\[.*?]#/g, ""));
23838
+ if (params.topic && params.topic.length > 0) for (const it of params.topic){
23839
+ await descInstance.pressSequentially(`#${it.name}`);
23840
+ await page.locator("#creator-editor-topic-container").waitFor({
23841
+ state: "visible"
23842
+ });
23843
+ await page.waitForTimeout(500);
23844
+ await page.locator("#creator-editor-topic-container .item").first().click();
23845
+ }
23846
+ if (params.address) await selectAddress(page.locator(".address-card-wrapper .d-select-wrapper"), params.address.name);
23847
+ if (params.selfDeclaration) {
23848
+ await page.locator(".declaration-wrapper .d-select-wrapper").click();
23849
+ const poperInstance = await getPoperInstance();
23850
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
23851
+ if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
23852
+ hasText: "虚构演绎,仅供娱乐"
23853
+ }).click();
23854
+ else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
23855
+ hasText: "笔记含AI合成内容"
23856
+ }).click();
23857
+ else if ("source-statement" === params.selfDeclaration.type) {
23858
+ await selfDeclarationInstance.filter({
23859
+ hasText: /内容来源声明/
23860
+ }).click();
23861
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
23862
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
23863
+ if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
23864
+ hasText: "已在正文中自主标注"
23865
+ }).click();
23866
+ else if ("self-shooting" === params.selfDeclaration.childType) {
23867
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
23868
+ await selfDeclarationSecondaryMenuInstance.filter({
23869
+ hasText: "自主拍摄"
23870
+ }).click();
23871
+ const selfShootingPopup = await getDialogInstance();
23872
+ const hasCustomContent = shootingDate || shootingLocation;
23873
+ if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
23874
+ if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
23875
+ await selfShootingPopup.locator("footer button").filter({
23876
+ hasText: hasCustomContent ? "确认" : "取消"
23877
+ }).click();
23878
+ } else if ("transshipment" === params.selfDeclaration.childType) {
23879
+ await selfDeclarationSecondaryMenuInstance.filter({
23880
+ hasText: "来源转载"
23881
+ }).click();
23882
+ const selfShootingPopup = await getDialogInstance();
23883
+ const sourceMedia = params.selfDeclaration.sourceMedia;
23884
+ if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
23885
+ await selfShootingPopup.locator("footer button").filter({
23886
+ hasText: sourceMedia ? "确认" : "取消"
23887
+ }).click();
23888
+ }
23889
+ }
23890
+ }
23891
+ if ("private" === params.visibleRange) {
23892
+ await page.locator(".publish-page-content-setting-content .d-select-wrapper").last().click();
23893
+ const poperInstance = await getPoperInstance();
23894
+ await poperInstance.locator(".d-options .d-option").filter({
23895
+ hasText: "仅自己可见"
23896
+ }).click();
23897
+ }
23898
+ task._timerRecord.PrePublish = Date.now();
23899
+ const releaseTimeInstance = page.locator("label").filter({
23900
+ hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
23901
+ });
23902
+ await releaseTimeInstance.click();
23903
+ if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
23904
+ await page.waitForFunction(()=>{
23905
+ const publishBtn = Array.from(document.querySelectorAll("button")).find((b)=>b.textContent?.trim() === "发布");
23906
+ const uploading = document.querySelector(".progress-container");
23907
+ return !!publishBtn && !uploading;
23908
+ }, {
23909
+ timeout: 180000,
23910
+ polling: 2000
23911
+ });
23912
+ const response = await new Promise((resolve, reject)=>{
23913
+ const handleResponse = async (response)=>{
23914
+ if (response.url().includes("/web_api/sns/v2/note")) {
23915
+ const jsonResponse = await response.json();
23916
+ page.off("response", handleResponse);
23917
+ if (jsonResponse?.success) resolve(jsonResponse?.data?.id);
23918
+ else reject(new Error(jsonResponse?.msg || "发布失败"));
23919
+ }
23920
+ };
23921
+ page.on("response", handleResponse);
23922
+ page.locator(".publish-page-publish-btn button").filter({
23923
+ hasText: "发布"
23924
+ }).click();
23925
+ });
23926
+ await updateTaskState?.({
23927
+ state: share_namespaceObject.TaskState.SUCCESS,
23928
+ result: {
23929
+ response
23930
+ }
23931
+ });
23932
+ await page.close();
23933
+ return (0, share_namespaceObject.success)(response);
23971
23934
  };
23972
- const rpa_server_mock_xsEncrypt = new Xhshow();
23973
- const rpaAction_Server_Mock = async (task, params)=>{
23974
- const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23975
- const tmpCachePath = task.getTmpPath();
23976
- if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
23977
- code: 414,
23978
- message: "原创声明与转载声明互斥,请重新选择后发布!",
23979
- data: ""
23980
- };
23981
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23982
- if (!a1Cookie) return {
23935
+ const xiaohongshuPublish_rpa_server_rpaAction_Server = async (task, params)=>{
23936
+ if (params.originalBind && params?.selfDeclaration?.type === "source-statement") return {
23983
23937
  code: 414,
23984
- message: "账号数据异常,请重新绑定账号后重试。",
23938
+ message: "已声明原创不可选择“来源转载”",
23985
23939
  data: ""
23986
23940
  };
23987
23941
  const defaultPage = task.steelBrowserContext?.pages()[0];
@@ -24019,205 +23973,627 @@ var __webpack_exports__ = {};
24019
23973
  });
24020
23974
  }
24021
23975
  }
24022
- const pagePromise = task.createPage({
23976
+ const tmpCachePath = task.getTmpPath();
23977
+ task.logger?.info("==>进入RPA操作:任务开始,下载图片开始...");
23978
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23979
+ const imagePromise = Promise.all(params.banners.map((url)=>{
23980
+ const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
23981
+ return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
23982
+ }));
23983
+ let proxyUrl;
23984
+ if (params.localIP) {
23985
+ const args = [
23986
+ params.localIP,
23987
+ params.proxyLoc,
23988
+ params.accountId
23989
+ ];
23990
+ task.logger?.info(`==> 开始获取代理信息:${args}`);
23991
+ const ProxyAgentResult = await ProxyAgent({
23992
+ logger: task.logger
23993
+ }, ...args);
23994
+ task.logger?.info("==> 代理信息获取成功!");
23995
+ proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
23996
+ }
23997
+ task.logger?.info("==>开始打开小红书页面...");
23998
+ const page = await task.createPage({
24023
23999
  show: task.debug,
24024
24000
  cookies: params.cookies,
24025
- url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
24001
+ proxyUrl,
24002
+ url: params.url || "https://creator.xiaohongshu.com/publish/publish?source=official&from=menu&target=image",
24003
+ ...params.viewport ? {
24004
+ viewport: params.viewport
24005
+ } : {}
24026
24006
  });
24007
+ task.logger?.info("==>小红书页面打开成功");
24027
24008
  await updateTaskState?.({
24028
- state: share_namespaceObject.TaskState.ACTION
24009
+ state: share_namespaceObject.TaskState.ACTION,
24010
+ connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
24011
+ sessionId: task.sessionId
24029
24012
  });
24030
- const headers = {
24031
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24032
- origin: "https://creator.xiaohongshu.com",
24033
- referer: "https://creator.xiaohongshu.com/",
24034
- "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"
24013
+ const clickTimeout = 10000;
24014
+ const selectAddress = async (selector, address)=>{
24015
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
24016
+ await instance.click({
24017
+ timeout: clickTimeout
24018
+ });
24019
+ await instance.locator("input").fill(address);
24020
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
24021
+ await poperInstance.first().waitFor();
24022
+ await poperInstance.first().click({
24023
+ timeout: clickTimeout
24024
+ });
24035
24025
  };
24036
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
24037
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24038
- return acc;
24039
- }, {});
24040
- const args = [
24041
- {
24042
- headers
24043
- },
24044
- task.logger,
24045
- params.proxyLoc,
24046
- params.localIP,
24047
- params.accountId
24048
- ];
24049
- const http = new Http({
24050
- headers
24026
+ const selectDate = async (selector, date)=>{
24027
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
24028
+ await instance.click({
24029
+ timeout: clickTimeout
24030
+ });
24031
+ await instance.fill(date);
24032
+ await instance.blur();
24033
+ };
24034
+ const getPoperInstance = async ()=>{
24035
+ await page.waitForTimeout(500);
24036
+ const elements = page.locator(".d-popover");
24037
+ const count = await elements.count();
24038
+ const visibleElements = [];
24039
+ for(let i = 0; i < count; i++){
24040
+ const element = elements.nth(i);
24041
+ const style = await element.getAttribute("style");
24042
+ if (style && !style.includes("display: none")) visibleElements.push(element);
24043
+ }
24044
+ if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
24045
+ throw new Error("未找到 popover 弹窗");
24046
+ };
24047
+ const getDialogInstance = async ()=>{
24048
+ await page.waitForTimeout(1000);
24049
+ const elements = page.locator(".el-dialog");
24050
+ return elements.last();
24051
+ };
24052
+ try {
24053
+ await page.waitForSelector("#CreatorPlatform", {
24054
+ state: "attached"
24055
+ });
24056
+ } catch (error) {
24057
+ return {
24058
+ code: 414,
24059
+ message: "登录失效",
24060
+ data: page.url()
24061
+ };
24062
+ }
24063
+ const images = await imagePromise;
24064
+ task.logger?.info(`==>图片下载完成,共 ${images.length} 张,开始上传图片...`);
24065
+ const fileChooser = await page.waitForSelector("input.upload-input", {
24066
+ timeout: 10000
24051
24067
  });
24052
- const proxyHttp = new Http(...args);
24053
- proxyHttp.addResponseInterceptor((response)=>{
24054
- const responseData = response.data;
24055
- if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
24056
- const errmsg = rpa_server_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
24057
- return {
24058
- code: rpa_server_mock_errnoMap[responseData.code] ? 414 : 500,
24059
- message: errmsg,
24060
- data: responseData
24061
- };
24062
- }
24068
+ if (fileChooser) await fileChooser.setInputFiles(images, {
24069
+ timeout: 60000
24070
+ }).catch((err)=>{
24071
+ task.logger?.error(`设置上传文件失败:${err.message}`);
24063
24072
  });
24064
- const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
24065
- const fetchCoverParams = {
24066
- biz_name: "spectrum",
24067
- scene: "image",
24068
- file_count: params.banners.length,
24069
- version: 1,
24070
- source: "web"
24071
- };
24072
- const fetchCoverXsHeader = rpa_server_mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
24073
- const uploadInfos = [];
24074
- if (params.banners.length > 18) {
24075
- let num = Math.ceil(params.banners.length / 14);
24076
- for(let i = 0; i < num; i++){
24077
- const start = 14 * i;
24078
- params.banners.length;
24079
- ({
24080
- ...fetchCoverParams
24081
- });
24082
- const batchCoverIdInfo = await proxyHttp.api({
24083
- method: "get",
24084
- baseURL: "https://creator.xiaohongshu.com",
24085
- url: fetchCoverUrl,
24086
- defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24087
- headers: fetchCoverXsHeader,
24088
- params: fetchCoverParams
24089
- }, {
24090
- retries: 3,
24091
- retryDelay: 20,
24092
- timeout: 3000
24093
- });
24094
- for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24095
- bucket: item.bucket || "",
24096
- uploadAddr: item.uploadAddr || "",
24097
- fileIds: fileId,
24098
- token: item.token || ""
24099
- });
24100
- }
24101
- } else {
24102
- const coverIdInfo = await proxyHttp.api({
24103
- method: "get",
24104
- baseURL: "https://creator.xiaohongshu.com",
24105
- url: fetchCoverUrl,
24106
- defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24107
- headers: fetchCoverXsHeader,
24108
- params: fetchCoverParams
24109
- }, {
24110
- retries: 3,
24111
- retryDelay: 20,
24112
- timeout: 3000
24073
+ else task.logger?.error("文件上传输入框未找到");
24074
+ task.logger?.info("==>图片上传完成,开始渲染预览图...");
24075
+ const titleInstance = page.locator(".input input");
24076
+ await titleInstance.waitFor({
24077
+ state: "attached",
24078
+ timeout: 60000
24079
+ });
24080
+ await titleInstance.click({
24081
+ timeout: 24 * clickTimeout
24082
+ });
24083
+ task.logger?.info("==> 预览图渲染成功,开始RPA操作!");
24084
+ await titleInstance.fill(params.title);
24085
+ const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
24086
+ await descInstance.click({
24087
+ timeout: clickTimeout
24088
+ });
24089
+ await descInstance.fill(`${params.content.replace(/#.*?\[.*?]#/g, "")}\n`);
24090
+ await page.keyboard.press("Control+End");
24091
+ if (params.topic && params.topic.length > 0) for (const it of params.topic){
24092
+ await page.keyboard.insertText(`#${it.name}`);
24093
+ await page.locator(".ql-mention-loading").waitFor({
24094
+ state: "detached"
24113
24095
  });
24114
- for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24115
- bucket: item.bucket || "",
24116
- uploadAddr: item.uploadAddr || "",
24117
- fileIds: fileId,
24118
- token: item.token || ""
24096
+ await page.waitForTimeout(1000);
24097
+ await page.locator("#creator-editor-topic-container .item.is-selected").click({
24098
+ timeout: clickTimeout
24119
24099
  });
24100
+ await page.keyboard.press("Control+End");
24120
24101
  }
24121
- if (uploadInfos.length < params.banners.length) return {
24122
- code: 414,
24123
- message: "可用 OSS bucket 数量不足,无法上传所有图片!",
24124
- data: ""
24125
- };
24126
- if (0 === uploadInfos.length) return {
24127
- code: 414,
24128
- message: "图片上传失败,请稍后重试!",
24129
- data: ""
24130
- };
24131
- const availableBuckets = Array.from({
24132
- length: uploadInfos.length
24133
- }, (_, i)=>i);
24134
- const uploadFile = async (url, index)=>{
24135
- const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
24136
- const localUrl = await (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
24137
- const fileBuffer = external_node_fs_default().readFileSync(localUrl);
24138
- const MAX_RETRIES = uploadInfos.length;
24139
- task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
24140
- let attempt = 0;
24141
- while(attempt < MAX_RETRIES){
24142
- const ossBucketIndex = availableBuckets.shift();
24143
- if (void 0 === ossBucketIndex) break;
24144
- const currentInfo = uploadInfos[ossBucketIndex];
24145
- const ossFileId = currentInfo.fileIds;
24146
- const ossToken = currentInfo.token;
24147
- const ossDomain = currentInfo.uploadAddr;
24148
- try {
24149
- await http.api({
24150
- method: "put",
24151
- url: `https://${ossDomain}/${ossFileId}`,
24152
- data: fileBuffer,
24153
- headers: {
24154
- "x-cos-security-token": ossToken
24155
- },
24156
- defaultErrorMsg: "图片上传异常,请稍后重试发布。"
24102
+ const container = page.locator(".plugin.editor-container");
24103
+ await container.focus();
24104
+ await page.mouse.wheel(0, 500);
24105
+ if (params.address) await selectAddress(page.locator(".media-extension .address-input").filter({
24106
+ hasText: "添加地点"
24107
+ }), params.address.name);
24108
+ if (params.collectionBind) {
24109
+ await page.locator(".media-extension .collection-container").filter({
24110
+ hasText: "添加合集"
24111
+ }).click({
24112
+ timeout: clickTimeout
24113
+ });
24114
+ const collectionName = params.collectionBind.name;
24115
+ const collectionBindInstance = await getPoperInstance();
24116
+ const collectionItemInstance = collectionBindInstance.locator(".d-grid-item .item-label", {
24117
+ hasText: collectionName
24118
+ });
24119
+ await collectionBindInstance.locator(".loading").waitFor({
24120
+ state: "detached"
24121
+ });
24122
+ await collectionItemInstance.click({
24123
+ timeout: clickTimeout
24124
+ });
24125
+ }
24126
+ if (params.groupBind) {
24127
+ await page.locator(".media-extension .address-input").filter({
24128
+ hasText: "选择群聊"
24129
+ }).click({
24130
+ timeout: clickTimeout
24131
+ });
24132
+ const groupBindName = params.groupBind.group_name;
24133
+ const groupBindInstance = await getPoperInstance();
24134
+ const groupItemInstance = groupBindInstance.locator(".d-grid-item .name", {
24135
+ hasText: groupBindName
24136
+ });
24137
+ await groupBindInstance.locator(".loading").waitFor({
24138
+ state: "detached"
24139
+ });
24140
+ await groupItemInstance.click({
24141
+ timeout: clickTimeout
24142
+ });
24143
+ }
24144
+ const OriginalBindBtn = page.locator(".btn-text.red", {
24145
+ hasText: "去声明"
24146
+ });
24147
+ const isOriginalBindBtnVisible = await OriginalBindBtn.isVisible();
24148
+ if (isOriginalBindBtnVisible && params.originalBind) {
24149
+ await OriginalBindBtn.click({
24150
+ timeout: clickTimeout
24151
+ });
24152
+ const poperInstance = await getPoperInstance();
24153
+ await poperInstance.locator(".d-checkbox-simulator").click({
24154
+ timeout: clickTimeout
24155
+ });
24156
+ await poperInstance.locator(".footer .custom-button.bg-red").click({
24157
+ timeout: clickTimeout
24158
+ });
24159
+ }
24160
+ if (params.selfDeclaration) {
24161
+ await page.locator(".media-settings .flexbox").filter({
24162
+ hasText: "内容类型声明"
24163
+ }).locator(".d-select-placeholder").click({
24164
+ timeout: clickTimeout
24165
+ });
24166
+ const poperInstance = await getPoperInstance();
24167
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
24168
+ if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
24169
+ hasText: "虚构演绎,仅供娱乐"
24170
+ }).click({
24171
+ timeout: clickTimeout
24172
+ });
24173
+ else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
24174
+ hasText: "笔记含AI合成内容"
24175
+ }).click({
24176
+ timeout: clickTimeout
24177
+ });
24178
+ else if ("source-statement" === params.selfDeclaration.type) {
24179
+ await selfDeclarationInstance.filter({
24180
+ hasText: /内容来源声明/
24181
+ }).click({
24182
+ timeout: clickTimeout
24183
+ });
24184
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
24185
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
24186
+ if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
24187
+ hasText: "已在正文中自主标注"
24188
+ }).click({
24189
+ timeout: clickTimeout
24190
+ });
24191
+ else if ("self-shooting" === params.selfDeclaration.childType) {
24192
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
24193
+ await selfDeclarationSecondaryMenuInstance.filter({
24194
+ hasText: "自主拍摄"
24195
+ }).click({
24196
+ timeout: clickTimeout
24197
+ });
24198
+ const selfShootingPopup = await getDialogInstance();
24199
+ const hasCustomContent = shootingDate || shootingLocation;
24200
+ if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
24201
+ if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
24202
+ await selfShootingPopup.locator("footer button").filter({
24203
+ hasText: hasCustomContent ? "确认" : "取消"
24204
+ }).click({
24205
+ timeout: clickTimeout
24206
+ });
24207
+ } else if ("transshipment" === params.selfDeclaration.childType) {
24208
+ await selfDeclarationSecondaryMenuInstance.filter({
24209
+ hasText: "来源转载"
24210
+ }).click({
24211
+ timeout: clickTimeout
24212
+ });
24213
+ const selfShootingPopup = await getDialogInstance();
24214
+ const sourceMedia = params.selfDeclaration.sourceMedia;
24215
+ if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
24216
+ await selfShootingPopup.locator("footer button").filter({
24217
+ hasText: sourceMedia ? "确认" : "取消"
24218
+ }).click({
24219
+ timeout: clickTimeout
24157
24220
  });
24158
- return {
24159
- ossFileId,
24160
- ossToken
24161
- };
24162
- } catch (error) {
24163
- task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
24164
- attempt++;
24165
24221
  }
24166
24222
  }
24223
+ }
24224
+ if ("public" !== params.visibleRange) {
24225
+ await page.locator(".media-settings .flexbox").filter({
24226
+ hasText: "可见范围"
24227
+ }).locator(".d-select-wrapper").click({
24228
+ timeout: clickTimeout
24229
+ });
24230
+ const poperInstance = await getPoperInstance();
24231
+ const visibleText = "friends" === params.visibleRange ? "好友可见" : "仅自己可见";
24232
+ await poperInstance.locator(".d-options .custom-option").filter({
24233
+ hasText: visibleText
24234
+ }).click({
24235
+ timeout: clickTimeout
24236
+ });
24237
+ }
24238
+ async function setSwitch(page, label, target) {
24239
+ const item = page.locator(".d-new-form-item", {
24240
+ has: page.locator(".d-form-item__label", {
24241
+ hasText: label
24242
+ })
24243
+ });
24244
+ const switchUI = item.locator(".d-switch-simulator");
24245
+ const cls = await switchUI.getAttribute("class");
24246
+ const isChecked = cls?.includes("checked") || true;
24247
+ if (isChecked !== target) await switchUI.click({
24248
+ timeout: clickTimeout
24249
+ });
24250
+ }
24251
+ if (!params.coProduceBind) await setSwitch(page, "允许合拍", false);
24252
+ if (!params.noteCopyBind) await setSwitch(page, "允许正文复制", false);
24253
+ const releaseTimeInstance = page.locator("label").filter({
24254
+ hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
24255
+ });
24256
+ await releaseTimeInstance.click({
24257
+ timeout: clickTimeout
24258
+ });
24259
+ if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
24260
+ const imgPreviewArea = page.locator(".img-preview-area");
24261
+ try {
24262
+ await imgPreviewArea.locator(".mask.uploading").waitFor({
24263
+ state: "hidden",
24264
+ timeout: 50000
24265
+ });
24266
+ } catch (error) {
24267
+ throw new Error("上传图片超时,请重试!");
24268
+ }
24269
+ if (MockPublish) {
24270
+ const message = "文章模拟发布成功";
24271
+ const data = "123456789";
24272
+ await updateTaskState?.({
24273
+ state: share_namespaceObject.TaskState.SUCCESS,
24274
+ result: {
24275
+ response: data
24276
+ }
24277
+ });
24278
+ return (0, share_namespaceObject.success)(data, message);
24279
+ }
24280
+ const response = await new Promise((resolve)=>{
24281
+ const handleResponse = async (response)=>{
24282
+ if (response.url().includes("/web_api/sns/v2/note")) {
24283
+ const jsonResponse = await response.json();
24284
+ page.off("response", handleResponse);
24285
+ resolve(jsonResponse);
24286
+ }
24287
+ };
24288
+ page.on("response", handleResponse);
24289
+ page.locator(".submit .publishBtn").click({
24290
+ timeout: clickTimeout
24291
+ });
24292
+ page.waitForSelector(".d-toast-icon-danger", {
24293
+ state: "visible",
24294
+ timeout: 2000
24295
+ }).then(async ()=>{
24296
+ await page.waitForTimeout(300);
24297
+ const toastDesc = await page.locator(".d-toast-description").textContent();
24298
+ const desc = toastDesc?.trim();
24299
+ page.off("response", handleResponse);
24300
+ resolve({
24301
+ success: false,
24302
+ msg: desc || "未知错误"
24303
+ });
24304
+ }).catch(()=>{});
24305
+ setTimeout(()=>{
24306
+ page.off("response", handleResponse);
24307
+ resolve({
24308
+ success: false,
24309
+ msg: "发布超时"
24310
+ });
24311
+ }, 7000);
24312
+ });
24313
+ if (!response?.success) {
24314
+ const msg = `发布失败:${response?.msg || "未知错误"}`;
24315
+ await updateTaskState?.({
24316
+ state: share_namespaceObject.TaskState.FAILED,
24317
+ error: msg
24318
+ });
24319
+ await page.close();
24167
24320
  return {
24168
- ossFileId: "",
24169
- ossToken: ""
24321
+ code: 414,
24322
+ message: msg,
24323
+ data: ""
24170
24324
  };
24325
+ }
24326
+ await updateTaskState?.({
24327
+ state: share_namespaceObject.TaskState.SUCCESS,
24328
+ result: {
24329
+ response: response?.data?.id || ""
24330
+ }
24331
+ });
24332
+ await page.close();
24333
+ return (0, share_namespaceObject.success)(response?.data?.id || "");
24334
+ };
24335
+ const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
24336
+ function Md5(input) {
24337
+ return external_node_crypto_default().createHash("md5").update(input).digest("hex");
24338
+ }
24339
+ const rpa_server_mock_errnoMap = {
24340
+ "-1": "未知拦截器错误,请稍后重试。",
24341
+ 915: "所属C端账号手机号被修改,请重新登录",
24342
+ 914: "所属C端账号密码被修改,请重新登录",
24343
+ 903: "账户已登出,需重新登陆重试!",
24344
+ 902: "登录已过期,请重新登录!",
24345
+ 906: "账号存在风险,请重新登录!",
24346
+ "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
24347
+ };
24348
+ const rpa_server_mock_xsEncrypt = new Xhshow();
24349
+ const rpaAction_Server_Mock = async (task, params)=>{
24350
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
24351
+ const tmpCachePath = task.getTmpPath();
24352
+ if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
24353
+ code: 414,
24354
+ message: "原创声明与转载声明互斥,请重新选择后发布!",
24355
+ data: ""
24171
24356
  };
24172
- const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
24173
- const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
24174
- if (invalidUpload) return {
24357
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24358
+ if (!a1Cookie) return {
24175
24359
  code: 414,
24176
- message: "图片上传异常,请稍后重试发布。",
24360
+ message: "账号数据异常,请重新绑定账号后重试。",
24177
24361
  data: ""
24178
24362
  };
24179
- if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
24180
- if (!topic.id) {
24181
- const topicData = {
24182
- topic_names: topic.name
24183
- };
24184
- const topicXsHeader = rpa_server_mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
24185
- const createTopic = await proxyHttp.api({
24186
- method: "POST",
24187
- url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
24188
- headers: topicXsHeader,
24189
- data: topicData,
24190
- defaultErrorMsg: "话题创建异常,请稍后重试。"
24191
- }, {
24192
- retries: 3,
24193
- retryDelay: 20,
24194
- timeout: 3000
24363
+ const defaultPage = task.steelBrowserContext?.pages()[0];
24364
+ if (defaultPage) {
24365
+ if (!defaultPage._routeRegistered) {
24366
+ defaultPage._routeRegistered = true;
24367
+ const blockedPatterns = [
24368
+ "**/ffmpeg-core.wasm*",
24369
+ "**/apm-fe.xiaohongshu.com*",
24370
+ "**/t2.xiaohongshu.com*",
24371
+ "**/fe-video-qc.xhscdn.com*"
24372
+ ].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
24373
+ await defaultPage.route("**/*", async (route)=>{
24374
+ const req = route.request();
24375
+ const url = req.url();
24376
+ const blocked = blockedPatterns.some((regex)=>regex.test(url));
24377
+ if (!blocked) return route.continue();
24378
+ if ("OPTIONS" === req.method()) {
24379
+ console.log("处理 OPTIONS 预检:", url);
24380
+ await route.fulfill({
24381
+ status: 204,
24382
+ headers: {
24383
+ "access-control-allow-origin": "*",
24384
+ "access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
24385
+ "access-control-allow-headers": "*"
24386
+ },
24387
+ body: ""
24388
+ });
24389
+ return;
24390
+ }
24391
+ await route.fulfill({
24392
+ status: 204,
24393
+ body: ""
24394
+ });
24195
24395
  });
24196
- Object.assign(topic, createTopic.data.topic_infos[0]);
24197
24396
  }
24198
- }));
24199
- const visibleRangeMap = {
24200
- public: 0,
24201
- private: 1,
24202
- friends: 4
24397
+ }
24398
+ const pagePromise = task.createPage({
24399
+ show: task.debug,
24400
+ cookies: params.cookies,
24401
+ url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
24402
+ });
24403
+ await updateTaskState?.({
24404
+ state: share_namespaceObject.TaskState.ACTION
24405
+ });
24406
+ const headers = {
24407
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24408
+ origin: "https://creator.xiaohongshu.com",
24409
+ referer: "https://creator.xiaohongshu.com/",
24410
+ "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"
24203
24411
  };
24204
- const publishData = {
24205
- common: {
24206
- ats: [],
24207
- biz_relations: [],
24208
- desc: params?.content,
24209
- goods_info: {},
24210
- hash_tag: params.topic || [],
24211
- note_id: "",
24212
- source: JSON.stringify({
24213
- type: "web",
24214
- ids: "",
24215
- extraInfo: '{"systemId":"web"}'
24216
- }),
24217
- title: params?.title,
24218
- type: "normal",
24219
- privacy_info: {
24220
- op_type: 1,
24412
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24413
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24414
+ return acc;
24415
+ }, {});
24416
+ const args = [
24417
+ {
24418
+ headers
24419
+ },
24420
+ task.logger,
24421
+ params.proxyLoc,
24422
+ params.localIP,
24423
+ params.accountId
24424
+ ];
24425
+ const http = new Http({
24426
+ headers
24427
+ });
24428
+ const proxyHttp = new Http(...args);
24429
+ proxyHttp.addResponseInterceptor((response)=>{
24430
+ const responseData = response.data;
24431
+ if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
24432
+ const errmsg = rpa_server_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
24433
+ return {
24434
+ code: rpa_server_mock_errnoMap[responseData.code] ? 414 : 500,
24435
+ message: errmsg,
24436
+ data: responseData
24437
+ };
24438
+ }
24439
+ });
24440
+ const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
24441
+ const fetchCoverParams = {
24442
+ biz_name: "spectrum",
24443
+ scene: "image",
24444
+ file_count: params.banners.length,
24445
+ version: 1,
24446
+ source: "web"
24447
+ };
24448
+ const fetchCoverXsHeader = rpa_server_mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
24449
+ const uploadInfos = [];
24450
+ if (params.banners.length > 18) {
24451
+ let num = Math.ceil(params.banners.length / 14);
24452
+ for(let i = 0; i < num; i++){
24453
+ const start = 14 * i;
24454
+ params.banners.length;
24455
+ ({
24456
+ ...fetchCoverParams
24457
+ });
24458
+ const batchCoverIdInfo = await proxyHttp.api({
24459
+ method: "get",
24460
+ baseURL: "https://creator.xiaohongshu.com",
24461
+ url: fetchCoverUrl,
24462
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24463
+ headers: fetchCoverXsHeader,
24464
+ params: fetchCoverParams
24465
+ }, {
24466
+ retries: 3,
24467
+ retryDelay: 20,
24468
+ timeout: 3000
24469
+ });
24470
+ for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24471
+ bucket: item.bucket || "",
24472
+ uploadAddr: item.uploadAddr || "",
24473
+ fileIds: fileId,
24474
+ token: item.token || ""
24475
+ });
24476
+ }
24477
+ } else {
24478
+ const coverIdInfo = await proxyHttp.api({
24479
+ method: "get",
24480
+ baseURL: "https://creator.xiaohongshu.com",
24481
+ url: fetchCoverUrl,
24482
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24483
+ headers: fetchCoverXsHeader,
24484
+ params: fetchCoverParams
24485
+ }, {
24486
+ retries: 3,
24487
+ retryDelay: 20,
24488
+ timeout: 3000
24489
+ });
24490
+ for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24491
+ bucket: item.bucket || "",
24492
+ uploadAddr: item.uploadAddr || "",
24493
+ fileIds: fileId,
24494
+ token: item.token || ""
24495
+ });
24496
+ }
24497
+ if (uploadInfos.length < params.banners.length) return {
24498
+ code: 414,
24499
+ message: "可用 OSS bucket 数量不足,无法上传所有图片!",
24500
+ data: ""
24501
+ };
24502
+ if (0 === uploadInfos.length) return {
24503
+ code: 414,
24504
+ message: "图片上传失败,请稍后重试!",
24505
+ data: ""
24506
+ };
24507
+ const availableBuckets = Array.from({
24508
+ length: uploadInfos.length
24509
+ }, (_, i)=>i);
24510
+ const uploadFile = async (url, index)=>{
24511
+ const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
24512
+ const localUrl = await (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
24513
+ const fileBuffer = external_node_fs_default().readFileSync(localUrl);
24514
+ const MAX_RETRIES = uploadInfos.length;
24515
+ task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
24516
+ let attempt = 0;
24517
+ while(attempt < MAX_RETRIES){
24518
+ const ossBucketIndex = availableBuckets.shift();
24519
+ if (void 0 === ossBucketIndex) break;
24520
+ const currentInfo = uploadInfos[ossBucketIndex];
24521
+ const ossFileId = currentInfo.fileIds;
24522
+ const ossToken = currentInfo.token;
24523
+ const ossDomain = currentInfo.uploadAddr;
24524
+ try {
24525
+ await http.api({
24526
+ method: "put",
24527
+ url: `https://${ossDomain}/${ossFileId}`,
24528
+ data: fileBuffer,
24529
+ headers: {
24530
+ "x-cos-security-token": ossToken
24531
+ },
24532
+ defaultErrorMsg: "图片上传异常,请稍后重试发布。"
24533
+ });
24534
+ return {
24535
+ ossFileId,
24536
+ ossToken
24537
+ };
24538
+ } catch (error) {
24539
+ task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
24540
+ attempt++;
24541
+ }
24542
+ }
24543
+ return {
24544
+ ossFileId: "",
24545
+ ossToken: ""
24546
+ };
24547
+ };
24548
+ const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
24549
+ const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
24550
+ if (invalidUpload) return {
24551
+ code: 414,
24552
+ message: "图片上传异常,请稍后重试发布。",
24553
+ data: ""
24554
+ };
24555
+ if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
24556
+ if (!topic.id) {
24557
+ const topicData = {
24558
+ topic_names: topic.name
24559
+ };
24560
+ const topicXsHeader = rpa_server_mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
24561
+ const createTopic = await proxyHttp.api({
24562
+ method: "POST",
24563
+ url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
24564
+ headers: topicXsHeader,
24565
+ data: topicData,
24566
+ defaultErrorMsg: "话题创建异常,请稍后重试。"
24567
+ }, {
24568
+ retries: 3,
24569
+ retryDelay: 20,
24570
+ timeout: 3000
24571
+ });
24572
+ Object.assign(topic, createTopic.data.topic_infos[0]);
24573
+ }
24574
+ }));
24575
+ const visibleRangeMap = {
24576
+ public: 0,
24577
+ private: 1,
24578
+ friends: 4
24579
+ };
24580
+ const publishData = {
24581
+ common: {
24582
+ ats: [],
24583
+ biz_relations: [],
24584
+ desc: params?.content,
24585
+ goods_info: {},
24586
+ hash_tag: params.topic || [],
24587
+ note_id: "",
24588
+ source: JSON.stringify({
24589
+ type: "web",
24590
+ ids: "",
24591
+ extraInfo: '{"systemId":"web"}'
24592
+ }),
24593
+ title: params?.title,
24594
+ type: "normal",
24595
+ privacy_info: {
24596
+ op_type: 1,
24221
24597
  type: visibleRangeMap[params.visibleRange]
24222
24598
  },
24223
24599
  post_loc: params.address ? {
@@ -24390,6 +24766,622 @@ var __webpack_exports__ = {};
24390
24766
  });
24391
24767
  return (0, share_namespaceObject.success)(data, message);
24392
24768
  };
24769
+ const FictionalRendition = schemas_object({
24770
+ type: literal("fictional-rendition")
24771
+ });
24772
+ const AIGenerated = schemas_object({
24773
+ type: literal("ai-generated")
24774
+ });
24775
+ const SourceStatement = schemas_object({
24776
+ type: literal("source-statement"),
24777
+ childType: schemas_enum([
24778
+ "self-labeling",
24779
+ "self-shooting",
24780
+ "transshipment"
24781
+ ]),
24782
+ shootingLocation: custom().optional(),
24783
+ shootingDate: schemas_string().optional(),
24784
+ sourceMedia: schemas_string().optional()
24785
+ });
24786
+ union([
24787
+ FictionalRendition,
24788
+ AIGenerated,
24789
+ SourceStatement
24790
+ ]);
24791
+ const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
24792
+ banners: schemas_array(schemas_string()),
24793
+ title: schemas_string(),
24794
+ content: schemas_string(),
24795
+ address: custom().optional(),
24796
+ selfDeclaration: custom().optional(),
24797
+ topic: schemas_array(custom()).optional(),
24798
+ proxyLoc: schemas_string().optional(),
24799
+ localIP: schemas_string().optional(),
24800
+ huiwenToken: schemas_string().optional(),
24801
+ visibleRange: schemas_enum([
24802
+ "public",
24803
+ "private",
24804
+ "friends"
24805
+ ]),
24806
+ isImmediatelyPublish: schemas_boolean().optional(),
24807
+ scheduledPublish: schemas_string().optional(),
24808
+ collectionId: schemas_string().optional(),
24809
+ collectionBind: custom().optional(),
24810
+ groupBind: custom().optional(),
24811
+ noteCopyBind: schemas_boolean().optional(),
24812
+ coProduceBind: schemas_boolean().optional(),
24813
+ originalBind: schemas_boolean().optional()
24814
+ });
24815
+ const xiaohongshuPublish = async (task, params)=>{
24816
+ if (DisabledReq) return {
24817
+ code: 414,
24818
+ data: "",
24819
+ message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
24820
+ };
24821
+ if ("rpa" === params.actionType) return xiaohongshuPublish_rpa_rpaAction(task, params);
24822
+ if ("mockApi" === params.actionType) return xiaohongshuPublish_mock_mockAction(task, params);
24823
+ if ("server" === params.actionType) return xiaohongshuPublish_rpa_server_rpaAction_Server(task, params);
24824
+ return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, xiaohongshuPublish_rpa_server_rpaAction_Server)(task, params);
24825
+ };
24826
+ const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
24827
+ const xiaohongshuWebCommentAction = async (_task, params)=>{
24828
+ if (DisabledReq) return (0, share_namespaceObject.response)(414, "点赞相关操作失败", {});
24829
+ const headers = {
24830
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24831
+ referer: "https://www.xiaohongshu.com/",
24832
+ origin: "https://www.xiaohongshu.com/"
24833
+ };
24834
+ const args = [
24835
+ {
24836
+ headers
24837
+ },
24838
+ _task.logger,
24839
+ params.proxyLoc,
24840
+ params.localIP,
24841
+ params.accountId
24842
+ ];
24843
+ const http = new Http(...args);
24844
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24845
+ if (!a1Cookie) return {
24846
+ code: 414,
24847
+ message: "账号数据异常,请重新绑定账号后重试。",
24848
+ data: []
24849
+ };
24850
+ if (!params.note_id && !params.comment_id && !params.action) return {
24851
+ code: 414,
24852
+ message: "参数缺失,请检查后重试!",
24853
+ data: {}
24854
+ };
24855
+ const actionParams = {
24856
+ note_id: params.note_id,
24857
+ comment_id: params.comment_id
24858
+ };
24859
+ let likeActionRes = {
24860
+ code: 500,
24861
+ success: false,
24862
+ msg: ""
24863
+ };
24864
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24865
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24866
+ return acc;
24867
+ }, {});
24868
+ switch(params.action){
24869
+ case "like":
24870
+ {
24871
+ const likeAction = "/api/sns/web/v1/comment/like";
24872
+ const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
24873
+ likeActionRes = await http.api({
24874
+ method: "post",
24875
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
24876
+ data: actionParams,
24877
+ headers: likeActionXsHeader
24878
+ }, {
24879
+ retries: 3,
24880
+ retryDelay: 20,
24881
+ timeout: 3000
24882
+ });
24883
+ break;
24884
+ }
24885
+ case "dislike":
24886
+ {
24887
+ const dislikeMentions = "/api/sns/web/v1/comment/dislike";
24888
+ const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
24889
+ likeActionRes = await http.api({
24890
+ method: "post",
24891
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
24892
+ data: actionParams,
24893
+ headers: dislikeXsHeader
24894
+ }, {
24895
+ retries: 3,
24896
+ retryDelay: 20,
24897
+ timeout: 3000
24898
+ });
24899
+ break;
24900
+ }
24901
+ default:
24902
+ return {
24903
+ code: 414,
24904
+ message: "参数action错误,请重试!",
24905
+ data: {}
24906
+ };
24907
+ }
24908
+ const isSuccess = 0 === likeActionRes.code;
24909
+ const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24910
+ const data = isSuccess ? likeActionRes.success : {};
24911
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
24912
+ };
24913
+ const xiaohongshuWebIntimacySearch = async (_task, params)=>{
24914
+ if (DisabledReq) return (0, share_namespaceObject.response)(0, "搜索@列表数据成功", []);
24915
+ const headers = {
24916
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24917
+ referer: "https://www.xiaohongshu.com/",
24918
+ origin: "https://www.xiaohongshu.com"
24919
+ };
24920
+ const args = [
24921
+ {
24922
+ headers
24923
+ },
24924
+ _task.logger,
24925
+ params.proxyLoc,
24926
+ params.localIP,
24927
+ params.accountId
24928
+ ];
24929
+ const http = new Http(...args);
24930
+ let intimacyDetail = [];
24931
+ const res = await http.api({
24932
+ method: "get",
24933
+ url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
24934
+ ...params.searchValue ? {
24935
+ params: {
24936
+ keyword: params.searchValue,
24937
+ page: 1,
24938
+ rows: 30
24939
+ }
24940
+ } : {}
24941
+ }, {
24942
+ retries: 3,
24943
+ retryDelay: 20,
24944
+ timeout: 3000
24945
+ });
24946
+ const isSuccess = 0 === res.code;
24947
+ if (isSuccess) intimacyDetail = res.data.items;
24948
+ const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24949
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, intimacyDetail);
24950
+ };
24951
+ const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
24952
+ const xiaohongshuWebMsgRead = async (_task, params)=>{
24953
+ if (DisabledReq) return (0, share_namespaceObject.response)(414, "Read指定Tab失败", {});
24954
+ const headers = {
24955
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24956
+ referer: "https://www.xiaohongshu.com/",
24957
+ origin: "https://www.xiaohongshu.com/"
24958
+ };
24959
+ const args = [
24960
+ {
24961
+ headers
24962
+ },
24963
+ _task.logger,
24964
+ params.proxyLoc,
24965
+ params.localIP,
24966
+ params.accountId
24967
+ ];
24968
+ const http = new Http(...args);
24969
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24970
+ if (!a1Cookie) return {
24971
+ code: 414,
24972
+ message: "账号数据异常,请重新绑定账号后重试。",
24973
+ data: []
24974
+ };
24975
+ if (!params.type) return {
24976
+ code: 414,
24977
+ message: "参数缺失,请检查后重试!",
24978
+ data: {}
24979
+ };
24980
+ const replyParams = {
24981
+ type: params.type
24982
+ };
24983
+ const fatchMentions = "/api/sns/web/v1/message/read";
24984
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24985
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24986
+ return acc;
24987
+ }, {});
24988
+ const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
24989
+ const res = await http.api({
24990
+ method: "post",
24991
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
24992
+ data: replyParams,
24993
+ headers: fatchMentionsXsHeader
24994
+ }, {
24995
+ retries: 3,
24996
+ retryDelay: 20,
24997
+ timeout: 3000
24998
+ });
24999
+ const isSuccess = 0 === res.code;
25000
+ const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25001
+ const data = isSuccess ? res.success : {};
25002
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
25003
+ };
25004
+ const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
25005
+ const xiaohongshuWebMsgReply = async (_task, params)=>{
25006
+ if (DisabledReq) return (0, share_namespaceObject.response)(414, "评论回复失败", {});
25007
+ const headers = {
25008
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25009
+ referer: "https://www.xiaohongshu.com/",
25010
+ origin: "https://www.xiaohongshu.com/"
25011
+ };
25012
+ const args = [
25013
+ {
25014
+ headers
25015
+ },
25016
+ _task.logger,
25017
+ params.proxyLoc,
25018
+ params.localIP,
25019
+ params.accountId
25020
+ ];
25021
+ const http = new Http(...args);
25022
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25023
+ if (!a1Cookie) return {
25024
+ code: 414,
25025
+ message: "账号数据异常,请重新绑定账号后重试。",
25026
+ data: []
25027
+ };
25028
+ if (!params.note_id || !params.target_comment_id || !params.content) return {
25029
+ code: 414,
25030
+ message: "参数缺失,请检查后重试!",
25031
+ data: {}
25032
+ };
25033
+ const replyParams = {
25034
+ at_users: params.at_users ?? [],
25035
+ content: params.content,
25036
+ note_id: params.note_id,
25037
+ target_comment_id: params.target_comment_id
25038
+ };
25039
+ const replyPath = "/api/sns/web/v1/comment/post";
25040
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25041
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25042
+ return acc;
25043
+ }, {});
25044
+ const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
25045
+ const res = await http.api({
25046
+ method: "post",
25047
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
25048
+ data: replyParams,
25049
+ headers: replyXsHeader
25050
+ }, {
25051
+ retries: 3,
25052
+ retryDelay: 20,
25053
+ timeout: 3000
25054
+ });
25055
+ const isSuccess = 0 === res.code;
25056
+ const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25057
+ const data = isSuccess ? res.data : {};
25058
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
25059
+ };
25060
+ const xiaohongshuWebNoteFeed_xsEncrypt = new xhs_ob_feed_Xhshow();
25061
+ const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
25062
+ const xiaohongshuWebNoteFeed = async (_task, params)=>{
25063
+ if (DisabledReq) return (0, share_namespaceObject.response)(414, "获取指定文章详情失败", {});
25064
+ const headers = {
25065
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25066
+ referer: "https://www.xiaohongshu.com/",
25067
+ origin: "https://www.xiaohongshu.com/"
25068
+ };
25069
+ const args = [
25070
+ {
25071
+ headers
25072
+ },
25073
+ _task.logger,
25074
+ params.proxyLoc,
25075
+ params.localIP,
25076
+ params.accountId
25077
+ ];
25078
+ const http = new Http(...args);
25079
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25080
+ if (!a1Cookie) return {
25081
+ code: 414,
25082
+ message: "账号数据异常,请重新绑定账号后重试。",
25083
+ data: {}
25084
+ };
25085
+ if (!params.source_note_id && !params.xsec_token) return {
25086
+ code: 414,
25087
+ message: "参数缺失,请检查后重试!",
25088
+ data: {}
25089
+ };
25090
+ const feedParams = {
25091
+ source_note_id: params.source_note_id,
25092
+ image_formats: [
25093
+ "jpg",
25094
+ "webp",
25095
+ "avif"
25096
+ ],
25097
+ extra: {
25098
+ need_body_topic: "1"
25099
+ },
25100
+ xsec_source: "pc_feed",
25101
+ xsec_token: params.xsec_token
25102
+ };
25103
+ const fatchFeed = "/api/sns/web/v1/feed";
25104
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25105
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25106
+ return acc;
25107
+ }, {});
25108
+ const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
25109
+ const xT = Date.now().toString();
25110
+ const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
25111
+ _task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
25112
+ _task.logger.info(`X-S: ${xsHeader["X-S"]}`);
25113
+ _task.logger.info(`x-s-common: ${xsCommon}`);
25114
+ const res = await http.api({
25115
+ method: "post",
25116
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
25117
+ data: feedParams,
25118
+ headers: {
25119
+ "X-S": xsHeader["X-S"],
25120
+ "X-S-Common": xsCommon,
25121
+ "X-T": xT
25122
+ }
25123
+ }, {
25124
+ retries: 3,
25125
+ retryDelay: 20,
25126
+ timeout: 3000
25127
+ });
25128
+ _task.logger.info(`API 响应: ${JSON.stringify(res)}`);
25129
+ const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
25130
+ const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25131
+ const data = isSuccess ? res.data?.items[0].note_card || {} : {};
25132
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
25133
+ };
25134
+ const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
25135
+ const xiaohongshuWebRelationAction = async (_task, params)=>{
25136
+ if (DisabledReq) return (0, share_namespaceObject.response)(414, "用户关系操作失败", {});
25137
+ const headers = {
25138
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25139
+ referer: "https://www.xiaohongshu.com/",
25140
+ origin: "https://www.xiaohongshu.com/"
25141
+ };
25142
+ const args = [
25143
+ {
25144
+ headers
25145
+ },
25146
+ _task.logger,
25147
+ params.proxyLoc,
25148
+ params.localIP,
25149
+ params.accountId
25150
+ ];
25151
+ const http = new Http(...args);
25152
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25153
+ if (!a1Cookie) return {
25154
+ code: 414,
25155
+ message: "账号数据异常,请重新绑定账号后重试。",
25156
+ data: {}
25157
+ };
25158
+ if (!params.action || !params.target_user_id) return {
25159
+ code: 414,
25160
+ message: "参数缺失,请检查后重试!",
25161
+ data: {}
25162
+ };
25163
+ const relationParams = {
25164
+ target_user_id: params.target_user_id
25165
+ };
25166
+ let relationActionRes;
25167
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25168
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25169
+ return acc;
25170
+ }, {});
25171
+ switch(params.action){
25172
+ case "follow":
25173
+ {
25174
+ const followMentions = "/api/sns/web/v1/user/follow";
25175
+ const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
25176
+ relationActionRes = await http.api({
25177
+ method: "post",
25178
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
25179
+ data: relationParams,
25180
+ headers: followXsHeader
25181
+ }, {
25182
+ retries: 3,
25183
+ retryDelay: 500,
25184
+ timeout: 3000
25185
+ });
25186
+ break;
25187
+ }
25188
+ case "unfollow":
25189
+ {
25190
+ const unfllowMentions = "/api/sns/web/v1/user/unfollow";
25191
+ const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
25192
+ relationActionRes = await http.api({
25193
+ method: "post",
25194
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
25195
+ data: relationParams,
25196
+ headers: unfllowXsHeader
25197
+ }, {
25198
+ retries: 3,
25199
+ retryDelay: 20,
25200
+ timeout: 3000
25201
+ });
25202
+ break;
25203
+ }
25204
+ default:
25205
+ return {
25206
+ code: 414,
25207
+ message: "参数action错误,请重试!",
25208
+ data: {}
25209
+ };
25210
+ }
25211
+ const isSuccess = 0 === relationActionRes.code;
25212
+ const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25213
+ const data = isSuccess ? relationActionRes.data : {
25214
+ fstatus: null
25215
+ };
25216
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
25217
+ };
25218
+ const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
25219
+ const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
25220
+ keyword: schemas_string(),
25221
+ page: schemas_number(),
25222
+ page_size: schemas_number(),
25223
+ sort_type: schemas_enum([
25224
+ "general",
25225
+ "time_descending",
25226
+ "popular_descending"
25227
+ ]),
25228
+ time_filter: schemas_enum([
25229
+ "不限",
25230
+ "一周内"
25231
+ ])
25232
+ });
25233
+ const createSearchId = ()=>{
25234
+ let r = BigInt(Date.now());
25235
+ const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
25236
+ r <<= BigInt(64);
25237
+ r += o;
25238
+ return r.toString(36);
25239
+ };
25240
+ const xiaohongshuWebSearch = async (_task, params)=>{
25241
+ const headers = {
25242
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25243
+ referer: "https://www.xiaohongshu.com/",
25244
+ origin: "https://www.xiaohongshu.com/"
25245
+ };
25246
+ const args = [
25247
+ {
25248
+ headers
25249
+ },
25250
+ _task.logger,
25251
+ params.proxyLoc,
25252
+ params.localIP,
25253
+ params.accountId
25254
+ ];
25255
+ const http = new Http(...args);
25256
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25257
+ if (!a1Cookie) return {
25258
+ code: 414,
25259
+ message: "账号数据异常,请重新绑定账号后重试。",
25260
+ data: {}
25261
+ };
25262
+ if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
25263
+ if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
25264
+ code: 414,
25265
+ message: "排序类型参数错误,请检查后重试!",
25266
+ data: {}
25267
+ };
25268
+ if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
25269
+ code: 414,
25270
+ message: "时间过滤参数错误,请检查后重试!",
25271
+ data: {}
25272
+ };
25273
+ return {
25274
+ code: 414,
25275
+ message: "参数缺失,请检查后重试!",
25276
+ data: {}
25277
+ };
25278
+ }
25279
+ const filterPath = "/api/sns/web/v1/search/notes";
25280
+ const filterParams = {
25281
+ ext_flags: [],
25282
+ geo: "",
25283
+ image_formats: [
25284
+ "jpg",
25285
+ "webp",
25286
+ "avif"
25287
+ ],
25288
+ filters: [
25289
+ {
25290
+ tags: [
25291
+ params.sort_type
25292
+ ],
25293
+ type: "sort_type"
25294
+ },
25295
+ {
25296
+ tags: [
25297
+ "不限"
25298
+ ],
25299
+ type: "filter_note_type"
25300
+ },
25301
+ {
25302
+ tags: [
25303
+ params.time_filter
25304
+ ],
25305
+ type: "filter_note_time"
25306
+ },
25307
+ {
25308
+ tags: [
25309
+ "不限"
25310
+ ],
25311
+ type: "filter_note_range"
25312
+ },
25313
+ {
25314
+ tags: [
25315
+ "不限"
25316
+ ],
25317
+ type: "filter_pos_distance"
25318
+ }
25319
+ ],
25320
+ keyword: params.keyword,
25321
+ note_type: 0,
25322
+ page: params.page,
25323
+ page_size: params.page_size,
25324
+ search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
25325
+ sort: "general"
25326
+ };
25327
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25328
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25329
+ return acc;
25330
+ }, {});
25331
+ const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
25332
+ const res = await http.api({
25333
+ method: "post",
25334
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
25335
+ data: filterParams,
25336
+ headers: searchXsHeader
25337
+ }, {
25338
+ retries: 3,
25339
+ retryDelay: 20,
25340
+ timeout: 3000
25341
+ });
25342
+ const isSuccess = 0 === res.code;
25343
+ const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25344
+ const data = isSuccess ? res.data : {};
25345
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
25346
+ };
25347
+ const ttConfigDataSchema = schemas_object({
25348
+ fansNum: schemas_number(),
25349
+ fansNumYesterday: schemas_number().nullable(),
25350
+ readNum: schemas_number(),
25351
+ incomeNum: schemas_number(),
25352
+ incomeNumYesterday: schemas_number().nullable(),
25353
+ showNumYesterday: schemas_number().nullable(),
25354
+ readNumYesterday: schemas_number().nullable(),
25355
+ likeNumYesterday: schemas_number().nullable(),
25356
+ commentNumYesterday: schemas_number().nullable()
25357
+ });
25358
+ const xhsConfigDataSchema = schemas_object({
25359
+ fansNum: schemas_number(),
25360
+ favedNum: schemas_number(),
25361
+ watchNumLastWeek: schemas_number(),
25362
+ likeNumLastWeek: schemas_number(),
25363
+ collectNumLastWeek: schemas_number(),
25364
+ commentNumLastWeek: schemas_number(),
25365
+ fansNumLastWeek: schemas_number(),
25366
+ fansNumYesterday: schemas_number()
25367
+ });
25368
+ const wxConfigDataSchema = schemas_object({
25369
+ fansNum: schemas_number(),
25370
+ fansNumYesterday: schemas_number(),
25371
+ readNumYesterday: schemas_number(),
25372
+ shareNumYesterday: schemas_number()
25373
+ });
25374
+ const bjhConfigDataSchema = schemas_object({
25375
+ fansNum: schemas_number(),
25376
+ fansNumYesterday: schemas_number().nullable(),
25377
+ readNum: schemas_number(),
25378
+ incomeNum: schemas_number(),
25379
+ incomeNumYesterday: schemas_number().nullable(),
25380
+ recommendNumYesterday: schemas_number().nullable(),
25381
+ readNumYesterday: schemas_number().nullable(),
25382
+ likeNumYesterday: schemas_number().nullable(),
25383
+ commentNumYesterday: schemas_number().nullable()
25384
+ });
24393
25385
  const BetaFlag = "HuiwenCanary";
24394
25386
  class Action {
24395
25387
  constructor(task){