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