@iflyrpa/actions 4.0.5 → 4.0.6-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6a453c21-67bd-5554-819f-0c24705e7164")}catch(e){}}();
1
3
  var __webpack_modules__ = {
2
4
  "./src/utils/XhsXsCommonEnc.js": function(module) {
3
5
  var encrypt_lookup = [
@@ -4394,13 +4396,13 @@ var __webpack_exports__ = {};
4394
4396
  bjhConfigDataSchema: ()=>bjhConfigDataSchema,
4395
4397
  Action: ()=>Action,
4396
4398
  ProxyAgent: ()=>ProxyAgent,
4399
+ douyinConfigDataSchema: ()=>douyinConfigDataSchema,
4400
+ shipinhaoConfigDataSchema: ()=>shipinhaoConfigDataSchema,
4397
4401
  version: ()=>package_namespaceObject.i8
4398
4402
  });
4399
4403
  const package_json_namespaceObject = require("@iflyrpa/share/package.json");
4400
4404
  var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
4401
- var package_namespaceObject = {
4402
- i8: "4.0.5"
4403
- };
4405
+ var package_namespaceObject = JSON.parse('{"i8":"4.0.6-beta.1"}');
4404
4406
  const share_namespaceObject = require("@iflyrpa/share");
4405
4407
  const external_node_fs_namespaceObject = require("node:fs");
4406
4408
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
@@ -4503,15 +4505,14 @@ var __webpack_exports__ = {};
4503
4505
  }
4504
4506
  return `socks5h://${ip}:${port}`;
4505
4507
  }
4506
- async function ProxyAgent(task, ip, adr, accountId, refresh) {
4508
+ async function ProxyAgent(task, addr, accountId, refresh) {
4507
4509
  const http = new Http({
4508
4510
  headers: {
4509
4511
  "content-type": "application/json"
4510
4512
  }
4511
4513
  });
4512
4514
  const params = {
4513
- ip: ip,
4514
- addr: adr || null,
4515
+ addr: addr || null,
4515
4516
  accountId: accountId
4516
4517
  };
4517
4518
  const ProxyInfo = await http.api({
@@ -4533,7 +4534,7 @@ var __webpack_exports__ = {};
4533
4534
  data: ProxyInfo.data
4534
4535
  }
4535
4536
  };
4536
- task.logger?.info(`请求代理:区域:${params.addr}, IP:${params.ip}, AccountId:${params.accountId}, 返回代理信息: ${ProxyInfo.data ? `${ProxyInfo.data.proxyIp}:${ProxyInfo.data.proxyPort}` : "无可用代理"}`, loggerInfo);
4537
+ task.logger?.info(`请求代理:区域:${params.addr}, AccountId:${params.accountId}, 返回代理信息: ${ProxyInfo.data ? `${ProxyInfo.data.proxyIp}:${ProxyInfo.data.proxyPort}` : "无可用代理"}`, loggerInfo);
4537
4538
  const proxyAgent = "000000" === ProxyInfo.code && ProxyInfo.data ? {
4538
4539
  ip: ProxyInfo.data.proxyIp,
4539
4540
  port: ProxyInfo.data.proxyPort,
@@ -4550,16 +4551,16 @@ var __webpack_exports__ = {};
4550
4551
  data: error
4551
4552
  };
4552
4553
  }
4553
- constructor(config, logger, adr, ip, accountId, platform){
4554
+ constructor(config, logger, addr, accountId, platform){
4554
4555
  this.agentPromise = void 0;
4555
4556
  this.apiClient = external_axios_default().create({
4556
4557
  ...config
4557
4558
  });
4558
4559
  this.logger = logger;
4559
4560
  this.platform = platform;
4560
- if (ip) this.agentPromise = ProxyAgent({
4561
+ if (addr) this.agentPromise = ProxyAgent({
4561
4562
  logger
4562
- }, ip, adr, accountId);
4563
+ }, addr, accountId);
4563
4564
  this.addResponseInterceptor(()=>void 0);
4564
4565
  }
4565
4566
  clearResponseInterceptors() {
@@ -4649,11 +4650,12 @@ var __webpack_exports__ = {};
4649
4650
  this.logger?.debug(`未处理的网络错误代码: ${error.code} ${error.message}`, {
4650
4651
  errorString: stringifyError(error)
4651
4652
  });
4652
- _message = `未知网络错误: ${error.message}`;
4653
+ _message = `网络错误: ${error.message}`;
4653
4654
  break;
4654
4655
  }
4655
4656
  }
4656
- errorResponse.message = errorResponse.message ? errorResponse.message : _message;
4657
+ if (error.code && !error.response?.data) errorResponse.message = _message || errorResponse.message;
4658
+ else errorResponse.message = errorResponse.message ? errorResponse.message : _message;
4657
4659
  if ("canceled" === errorResponse.message) {
4658
4660
  const message = errorResponse.extra?.isProxyRequest ? "代理连接建立超时,请更换区域或稍后重试!" : "网络请求超时,请稍后重试!";
4659
4661
  errorResponse.message = message;
@@ -8718,16 +8720,11 @@ var __webpack_exports__ = {};
8718
8720
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
8719
8721
  let executionState;
8720
8722
  let proxyUrl;
8721
- if (params.localIP) {
8722
- const args = [
8723
- params.localIP,
8724
- params.proxyLoc,
8725
- params.accountId
8726
- ];
8727
- task.logger?.info(`==> 开始获取代理信息:${args}`);
8723
+ if (params.proxyLoc) {
8724
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
8728
8725
  const ProxyAgentResult = await ProxyAgent({
8729
8726
  logger: task.logger
8730
- }, ...args);
8727
+ }, params.proxyLoc, params.accountId);
8731
8728
  task.logger?.info("==> 代理信息获取成功!");
8732
8729
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
8733
8730
  }
@@ -9072,7 +9069,6 @@ var __webpack_exports__ = {};
9072
9069
  },
9073
9070
  task.logger,
9074
9071
  params.proxyLoc,
9075
- params.localIP,
9076
9072
  params.accountId,
9077
9073
  "baijiahao"
9078
9074
  ];
@@ -9278,7 +9274,6 @@ var __webpack_exports__ = {};
9278
9274
  enverionment: task.enverionment || "development",
9279
9275
  postId: params.articleId,
9280
9276
  eip: proxyHttp.proxyInfo,
9281
- proxyIp: params.localIP,
9282
9277
  accountId: params.accountId,
9283
9278
  uid: params.uid,
9284
9279
  platform: "baijiahao",
@@ -9799,7 +9794,6 @@ var __webpack_exports__ = {};
9799
9794
  },
9800
9795
  _task.logger,
9801
9796
  params.proxyLoc,
9802
- params.localIP,
9803
9797
  params.accountId
9804
9798
  ];
9805
9799
  const http = new Http(...args);
@@ -10929,7 +10923,7 @@ var __webpack_exports__ = {};
10929
10923
  heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
10930
10924
  },
10931
10925
  accountId: params.accountId,
10932
- hasProxy: !!(params.proxyLoc || params.localIP)
10926
+ hasProxy: !!params.proxyLoc
10933
10927
  });
10934
10928
  }
10935
10929
  const check = {
@@ -10952,7 +10946,6 @@ var __webpack_exports__ = {};
10952
10946
  },
10953
10947
  _task.logger,
10954
10948
  params.proxyLoc,
10955
- params.localIP,
10956
10949
  params.accountId
10957
10950
  ];
10958
10951
  const http = new Http(...args);
@@ -10983,7 +10976,7 @@ var __webpack_exports__ = {};
10983
10976
  heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
10984
10977
  heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
10985
10978
  },
10986
- hasProxy: !!(params.proxyLoc || params.localIP),
10979
+ hasProxy: !!params.proxyLoc,
10987
10980
  timeSinceLastLog: Date.now() - lastEnvLogTime
10988
10981
  }
10989
10982
  });
@@ -11381,7 +11374,6 @@ var __webpack_exports__ = {};
11381
11374
  },
11382
11375
  _task.logger,
11383
11376
  params.proxyLoc,
11384
- params.localIP,
11385
11377
  params.accountId
11386
11378
  ];
11387
11379
  const http = new Http(...args);
@@ -11468,7 +11460,6 @@ var __webpack_exports__ = {};
11468
11460
  },
11469
11461
  _task.logger,
11470
11462
  params.proxyLoc,
11471
- params.localIP,
11472
11463
  params.accountId
11473
11464
  ];
11474
11465
  const http = new Http(...args);
@@ -11559,7 +11550,6 @@ var __webpack_exports__ = {};
11559
11550
  },
11560
11551
  _task.logger,
11561
11552
  params.proxyLoc,
11562
- params.localIP,
11563
11553
  params.accountId
11564
11554
  ];
11565
11555
  const http = new Http(...args);
@@ -11645,7 +11635,6 @@ var __webpack_exports__ = {};
11645
11635
  },
11646
11636
  _task.logger,
11647
11637
  params.proxyLoc,
11648
- params.localIP,
11649
11638
  params.accountId
11650
11639
  ];
11651
11640
  const http = new Http(...args);
@@ -11729,7 +11718,6 @@ var __webpack_exports__ = {};
11729
11718
  },
11730
11719
  _task.logger,
11731
11720
  params.proxyLoc,
11732
- params.localIP,
11733
11721
  params.accountId
11734
11722
  ];
11735
11723
  const http = new Http(...args);
@@ -11825,7 +11813,6 @@ var __webpack_exports__ = {};
11825
11813
  },
11826
11814
  _task.logger,
11827
11815
  params.proxyLoc,
11828
- params.localIP,
11829
11816
  params.accountId
11830
11817
  ];
11831
11818
  const http = new Http(...args);
@@ -11925,7 +11912,6 @@ var __webpack_exports__ = {};
11925
11912
  },
11926
11913
  _task.logger,
11927
11914
  params.proxyLoc,
11928
- params.localIP,
11929
11915
  params.accountId
11930
11916
  ];
11931
11917
  const http = new Http(...args);
@@ -12071,7 +12057,6 @@ var __webpack_exports__ = {};
12071
12057
  },
12072
12058
  _task.logger,
12073
12059
  params.proxyLoc,
12074
- params.localIP,
12075
12060
  params.accountId
12076
12061
  ];
12077
12062
  const http = new Http(...args);
@@ -12159,7 +12144,6 @@ var __webpack_exports__ = {};
12159
12144
  },
12160
12145
  _task.logger,
12161
12146
  params.proxyLoc,
12162
- params.localIP,
12163
12147
  params.accountId
12164
12148
  ];
12165
12149
  const http = new Http(...args);
@@ -12247,7 +12231,6 @@ var __webpack_exports__ = {};
12247
12231
  },
12248
12232
  _task.logger,
12249
12233
  params.proxyLoc,
12250
- params.localIP,
12251
12234
  params.accountId
12252
12235
  ];
12253
12236
  const http = new Http(...args);
@@ -12468,7 +12451,6 @@ var __webpack_exports__ = {};
12468
12451
  },
12469
12452
  _task.logger,
12470
12453
  params.proxyLoc,
12471
- params.localIP,
12472
12454
  params.accountId
12473
12455
  ];
12474
12456
  const http = new Http(...args);
@@ -12830,16 +12812,11 @@ var __webpack_exports__ = {};
12830
12812
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
12831
12813
  let executionState;
12832
12814
  let proxyUrl;
12833
- if (params.localIP) {
12834
- const args = [
12835
- params.localIP,
12836
- params.proxyLoc,
12837
- params.accountId
12838
- ];
12839
- task.logger?.info(`==> 开始获取代理信息:${args}`);
12815
+ if (params.proxyLoc) {
12816
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
12840
12817
  const ProxyAgentResult = await ProxyAgent({
12841
12818
  logger: task.logger
12842
- }, ...args);
12819
+ }, params.proxyLoc, params.accountId);
12843
12820
  task.logger?.info("==> 代理信息获取成功!");
12844
12821
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
12845
12822
  }
@@ -13442,408 +13419,427 @@ var __webpack_exports__ = {};
13442
13419
  }
13443
13420
  return randomString;
13444
13421
  }
13422
+ function safeSerialize(obj) {
13423
+ if (!obj || "object" != typeof obj) return obj;
13424
+ try {
13425
+ return JSON.parse(JSON.stringify(obj));
13426
+ } catch (error) {
13427
+ return {};
13428
+ }
13429
+ }
13445
13430
  const mock_mockAction = async (task, params)=>{
13446
13431
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
13447
- if (!params.extraParam || !params.extraParam["security-sdk/s_sdk_pri_key"] || !params.extraParam["security-sdk/s_sdk_pub_key"] || !params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || !params.extraParam["security-sdk/s_sdk_server_cert_key"] || !params.extraParam["security-sdk/s_sdk_crypt_sdk"]) return (0, share_namespaceObject.response)(414, "extraParam 参数缺失或不完整", "");
13448
- const userAgent = params.userAgent || "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.38";
13449
- const sessionidCookie = params.cookies.find((it)=>"msToken" === it.name)?.value;
13450
- if (!sessionidCookie) return {
13451
- code: 414,
13452
- message: "账号数据异常,请重新绑定账号后重试。",
13453
- data: ""
13454
- };
13455
- const headers = {
13456
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
13457
- origin: "https://creator.douyin.com",
13458
- referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13459
- Accept: "application/json, text/plain, */*",
13460
- "Accept-Encoding": "gzip, deflate, br, zstd",
13461
- "Content-Type": "application/json",
13462
- pragma: "no-cache",
13463
- "cache-control": "no-cache",
13464
- "sec-ch-ua-platform": params.extraParam?.browserInfo?.["sec-ch-ua-platform"] || "",
13465
- "sec-ch-ua": params.extraParam?.browserInfo?.["sec-ch-ua"] || "",
13466
- "bd-ticket-guard-web-version": "2",
13467
- "sec-ch-ua-mobile": "?0",
13468
- "user-agent": userAgent,
13469
- "sec-fetch-site": "same-origin",
13470
- "sec-fetch-mode": "cors",
13471
- "sec-fetch-dest": "empty",
13472
- "accept-language": "zh-CN,zh;q=0.9",
13473
- priority: "u=1, i"
13474
- };
13475
- const publishParams = {
13476
- read_aid: "2906",
13477
- aid: "1128",
13478
- cookie_enabled: "true",
13479
- screen_width: params.extraParam?.browserInfo.screen_width || "1920",
13480
- screen_height: params.extraParam?.browserInfo.screen_height || "1080",
13481
- browser_language: params.extraParam?.browserInfo.browser_language || "zh-CN",
13482
- browser_platform: params.extraParam?.browserInfo.browser_platform || "Win32",
13483
- browser_name: params.extraParam?.browserInfo.browser_name || "Mozilla",
13484
- browser_version: userAgent,
13485
- browser_online: "true",
13486
- timezone_name: "Asia/Shanghai",
13487
- support_h265: "1",
13488
- msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
13489
- a_bogus: ""
13490
- };
13491
- task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
13492
- const publishData = {
13493
- item: {
13494
- common: {
13495
- text: params.content,
13496
- text_extra: params.textExtra,
13497
- activity: "[]",
13498
- challenges: params.challengeIds || "[]",
13499
- hashtag_source: "",
13500
- mentions: "[]",
13501
- music_id: params.musicId || "",
13502
- music_end_time: 1000 * (params.musicDuration || 0),
13503
- hot_sentence: params.hotSentence || "",
13504
- visibility_type: Number(params.visibleRange) || 0,
13505
- download: params.allowSave ? 1 : 0,
13506
- timing: params.isImmediatelyPublish ? -1 : params.scheduledPublish,
13507
- media_type: Number(params.publishType) || 2,
13508
- images: [],
13509
- creation_id: ""
13510
- },
13511
- cover: {
13512
- poster: ""
13432
+ if (!params.extraParam || !params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || !params.extraParam["security-sdk/s_sdk_server_cert_key"] || !params.extraParam["security-sdk/s_sdk_crypt_sdk"]) return (0, share_namespaceObject.response)(414, "extraParam 参数缺失或不完整", "");
13433
+ let currentStep = "初始化";
13434
+ try {
13435
+ currentStep = "验证账号信息";
13436
+ const userAgent = params.userAgent || "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.38";
13437
+ const sessionidCookie = params.cookies.find((it)=>"msToken" === it.name)?.value;
13438
+ if (!sessionidCookie) return {
13439
+ code: 414,
13440
+ message: "账号数据异常,请重新绑定账号后重试。",
13441
+ data: ""
13442
+ };
13443
+ currentStep = "准备请求参数";
13444
+ const headers = {
13445
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
13446
+ origin: "https://creator.douyin.com",
13447
+ referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13448
+ Accept: "application/json, text/plain, */*",
13449
+ "Accept-Encoding": "gzip, deflate, br, zstd",
13450
+ "Content-Type": "application/json",
13451
+ pragma: "no-cache",
13452
+ "cache-control": "no-cache",
13453
+ "sec-ch-ua-platform": params.extraParam?.browserInfo?.["sec-ch-ua-platform"] || "",
13454
+ "sec-ch-ua": params.extraParam?.browserInfo?.["sec-ch-ua"] || "",
13455
+ "bd-ticket-guard-web-version": "2",
13456
+ "sec-ch-ua-mobile": "?0",
13457
+ "user-agent": userAgent,
13458
+ "sec-fetch-site": "same-origin",
13459
+ "sec-fetch-mode": "cors",
13460
+ "sec-fetch-dest": "empty",
13461
+ "accept-language": "zh-CN,zh;q=0.9",
13462
+ priority: "u=1, i"
13463
+ };
13464
+ const publishParams = {
13465
+ read_aid: "2906",
13466
+ aid: "1128",
13467
+ cookie_enabled: "true",
13468
+ screen_width: params.extraParam?.browserInfo.screen_width || "1920",
13469
+ screen_height: params.extraParam?.browserInfo.screen_height || "1080",
13470
+ browser_language: params.extraParam?.browserInfo.browser_language || "zh-CN",
13471
+ browser_platform: params.extraParam?.browserInfo.browser_platform || "Win32",
13472
+ browser_name: params.extraParam?.browserInfo.browser_name || "Mozilla",
13473
+ browser_version: userAgent,
13474
+ browser_online: "true",
13475
+ timezone_name: "Asia/Shanghai",
13476
+ support_h265: "1",
13477
+ msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
13478
+ a_bogus: ""
13479
+ };
13480
+ task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
13481
+ const publishData = {
13482
+ item: {
13483
+ common: {
13484
+ text: params.content,
13485
+ text_extra: params.textExtra,
13486
+ activity: "[]",
13487
+ challenges: params.challengeIds || "[]",
13488
+ hashtag_source: "",
13489
+ mentions: "[]",
13490
+ music_id: params.musicId || "",
13491
+ music_end_time: 1000 * (params.musicDuration || 0),
13492
+ hot_sentence: params.hotSentence || "",
13493
+ visibility_type: Number(params.visibleRange) || 0,
13494
+ download: params.allowSave ? 1 : 0,
13495
+ timing: params.isImmediatelyPublish ? -1 : params.scheduledPublish,
13496
+ media_type: Number(params.publishType) || 2,
13497
+ images: [],
13498
+ creation_id: ""
13499
+ },
13500
+ cover: {
13501
+ poster: ""
13502
+ },
13503
+ mix: params.mix ? {
13504
+ mix_id: params.mix.mix_id,
13505
+ mix_order: params.mix.mix_order || 0
13506
+ } : {},
13507
+ anchor: {},
13508
+ declare: {
13509
+ user_declare_info: "{}"
13510
+ }
13511
+ }
13512
+ };
13513
+ const args = [
13514
+ {
13515
+ headers
13513
13516
  },
13514
- mix: params.mix ? {
13515
- mix_id: params.mix.mix_id,
13516
- mix_order: params.mix.mix_order || 0
13517
- } : {},
13518
- anchor: {},
13519
- declare: {
13520
- user_declare_info: "{}"
13517
+ task.logger,
13518
+ params.proxyLoc,
13519
+ params.accountId,
13520
+ "douyin"
13521
+ ];
13522
+ const http = new Http({
13523
+ headers
13524
+ });
13525
+ const proxyHttp = new Http(...args);
13526
+ const uploadedImgList = params.uploadedImgList ? JSON.parse(params.uploadedImgList) : [];
13527
+ if (uploadedImgList.length > 0) publishData.item.common.images = uploadedImgList;
13528
+ else {
13529
+ const tmpCachePath = task.getTmpPath();
13530
+ const uploader = new DouyinImageUploader(proxyHttp, headers, publishParams, tmpCachePath);
13531
+ if (params.coverImage) {
13532
+ const cover = await uploader.uploadCover(params.coverImage);
13533
+ if (cover) {
13534
+ publishData.item.common.images.push({
13535
+ uri: cover.uri,
13536
+ width: cover.width,
13537
+ height: cover.height
13538
+ });
13539
+ publishData.item.cover = {
13540
+ poster: cover.uri
13541
+ };
13542
+ }
13543
+ }
13544
+ if (params.banners && params.banners.length > 0) {
13545
+ const banners = params.banners.filter((i)=>i !== params.coverImage);
13546
+ const uploadResults = await uploader.uploadImages(banners);
13547
+ publishData.item.common.images = publishData.item.common.images.concat(uploadResults.map((result)=>({
13548
+ uri: result.uri,
13549
+ width: result.width,
13550
+ height: result.height
13551
+ })));
13521
13552
  }
13522
13553
  }
13523
- };
13524
- const args = [
13525
- {
13526
- headers
13527
- },
13528
- task.logger,
13529
- "",
13530
- "",
13531
- params.accountId,
13532
- "douyin"
13533
- ];
13534
- const http = new Http({
13535
- headers
13536
- });
13537
- const proxyHttp = new Http(...args);
13538
- const uploadedImgList = params.uploadedImgList ? JSON.parse(params.uploadedImgList) : [];
13539
- if (uploadedImgList.length > 0) publishData.item.common.images = uploadedImgList;
13540
- else {
13541
- const tmpCachePath = task.getTmpPath();
13542
- const uploader = new DouyinImageUploader(proxyHttp, headers, publishParams, tmpCachePath);
13543
- if (params.coverImage) {
13544
- const cover = await uploader.uploadCover(params.coverImage);
13545
- if (cover) {
13546
- publishData.item.common.images.push({
13547
- uri: cover.uri,
13548
- width: cover.width,
13549
- height: cover.height
13550
- });
13551
- publishData.item.cover = {
13552
- poster: cover.uri
13554
+ publishData.item.common.creation_id = generateRandomString(8) + Date.now();
13555
+ let decision = null;
13556
+ proxyHttp.addResponseInterceptor((response)=>{
13557
+ task.logger.info(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
13558
+ task.logger.info(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
13559
+ decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
13560
+ if (needsVerification(decision)) {
13561
+ task.logger.info(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
13562
+ return;
13563
+ }
13564
+ if (!response || !response.data) return;
13565
+ const responseData = response.data;
13566
+ if (response && responseData?.status_code && 0 !== responseData.status_code) {
13567
+ const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
13568
+ if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
13569
+ return {
13570
+ code: errorCode,
13571
+ message: responseData.status_msg || "文章发布异常,请稍后重试。",
13572
+ data: responseData
13553
13573
  };
13554
13574
  }
13575
+ });
13576
+ task._timerRecord.PrePublish = Date.now();
13577
+ if (MockPublish) {
13578
+ const data = "123456789";
13579
+ const message = `图文模拟发布成功 ${http.proxyInfo}`;
13580
+ await updateTaskState?.({
13581
+ state: share_namespaceObject.TaskState.SUCCESS,
13582
+ result: {
13583
+ response: data
13584
+ }
13585
+ });
13586
+ return (0, share_namespaceObject.response)(0, message, data);
13555
13587
  }
13556
- if (params.banners && params.banners.length > 0) {
13557
- const banners = params.banners.filter((i)=>i !== params.coverImage);
13558
- const uploadResults = await uploader.uploadImages(banners);
13559
- publishData.item.common.images = publishData.item.common.images.concat(uploadResults.map((result)=>({
13560
- uri: result.uri,
13561
- width: result.width,
13562
- height: result.height
13563
- })));
13588
+ let webProtectData;
13589
+ try {
13590
+ webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
13591
+ if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
13592
+ task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
13593
+ return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
13594
+ }
13595
+ } catch (error) {
13596
+ task.logger.error(`解析 webProtectData 失败: ${error}`);
13597
+ return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
13598
+ }
13599
+ let ticket = webProtectData.ticket;
13600
+ let ts_sign = webProtectData.ts_sign;
13601
+ const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
13602
+ if (serverDataCookie) try {
13603
+ const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
13604
+ if (decoded.ticket && decoded.ts_sign) {
13605
+ if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
13606
+ ticket = decoded.ticket;
13607
+ ts_sign = decoded.ts_sign;
13608
+ }
13609
+ } catch (error) {
13610
+ task.logger.info(`[douyinPublish] 解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
13564
13611
  }
13565
- }
13566
- publishData.item.common.creation_id = generateRandomString(8) + Date.now();
13567
- let decision = null;
13568
- proxyHttp.addResponseInterceptor((response)=>{
13569
- task.logger.info(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
13570
- task.logger.info(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
13571
- decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
13612
+ let ec_privateKey;
13613
+ try {
13614
+ ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
13615
+ if (!ec_privateKey) {
13616
+ task.logger.error("[douyinPublish] ec_privateKey 为空");
13617
+ return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
13618
+ }
13619
+ } catch (error) {
13620
+ task.logger.error(`[douyinPublish] 解析 ec_privateKey 失败: ${error}`);
13621
+ return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
13622
+ }
13623
+ let certificate;
13624
+ try {
13625
+ certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
13626
+ if (!certificate) {
13627
+ task.logger.error("[douyinPublish] certificate 为空");
13628
+ return (0, share_namespaceObject.response)(414, "安全参数 certificate 缺失,请重新获取后重试", "");
13629
+ }
13630
+ } catch (error) {
13631
+ task.logger.error(`[douyinPublish] 解析 certificate 失败: ${error}`);
13632
+ return (0, share_namespaceObject.response)(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
13633
+ }
13634
+ const ree_public_key = webProtectData.client_cert.replace("pub.", "");
13635
+ let bdTicketGuardClientData;
13636
+ try {
13637
+ bdTicketGuardClientData = getBdV2({
13638
+ ticket,
13639
+ ts_sign: ts_sign,
13640
+ ec_privateKey: ec_privateKey,
13641
+ certificate: certificate,
13642
+ bd_ticket_guard_ree_public_key: ree_public_key
13643
+ });
13644
+ if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
13645
+ task.logger.error(`[douyinPublish] bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
13646
+ return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
13647
+ }
13648
+ } catch (error) {
13649
+ task.logger.error(`[douyinPublish] 生成 bdTicketGuardClientData 失败: ${error}`);
13650
+ return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
13651
+ }
13652
+ task.logger.info("[douyinPublish] bdTicketGuardClientData 生成成功");
13653
+ const publishQuery = {
13654
+ ...publishParams,
13655
+ a_bogus: ""
13656
+ };
13657
+ const queryString = new URLSearchParams(publishQuery).toString();
13658
+ let aBogus;
13659
+ try {
13660
+ aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
13661
+ if (!aBogus || aBogus.length < 10) {
13662
+ task.logger.error(`[douyinPublish] a_bogus 生成异常,长度过短: ${aBogus}`);
13663
+ return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成失败,请重试", "");
13664
+ }
13665
+ } catch (error) {
13666
+ task.logger.error(`[douyinPublish] 生成 a_bogus 失败: ${error}`);
13667
+ return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成异常,请重试", "");
13668
+ }
13669
+ publishQuery.a_bogus = aBogus;
13670
+ const publishQueryParams = new URLSearchParams(publishQuery).toString();
13671
+ let csrfToken;
13672
+ try {
13673
+ csrfToken = mock_generateCsrfTokenAdvanced({
13674
+ cookies: params.cookies,
13675
+ url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
13676
+ method: "POST",
13677
+ userAgent
13678
+ });
13679
+ if (!csrfToken || csrfToken.length < 10) {
13680
+ task.logger.error(`[douyinPublish] csrfToken 生成异常,长度过短: ${csrfToken}`);
13681
+ return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成失败,请重试", "");
13682
+ }
13683
+ task.logger.info(`[douyinPublish] csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
13684
+ } catch (error) {
13685
+ task.logger.error(`[douyinPublish] 生成 csrfToken 失败: ${error}`);
13686
+ return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成异常,请重试", "");
13687
+ }
13688
+ let sessionDtrait;
13689
+ try {
13690
+ sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
13691
+ task.logger.info(`[douyinPublish] sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
13692
+ } catch (error) {
13693
+ task.logger.error(`[douyinPublish] 生成 sessionDtrait 失败: ${error}`);
13694
+ return (0, share_namespaceObject.response)(414, "安全参数 sessionDtrait 生成异常,请重试", "");
13695
+ }
13696
+ task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
13697
+ ...headers,
13698
+ Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13699
+ "Content-Type": "application/json",
13700
+ Accept: "application/json, text/plain, */*",
13701
+ "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13702
+ "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13703
+ "bd-ticket-guard-version": "2",
13704
+ "bd-ticket-guard-web-sign-type": "1",
13705
+ "bd-ticket-guard-web-version": "2",
13706
+ "x-secsdk-csrf-token": csrfToken,
13707
+ "x-tt-session-dtrait": sessionDtrait || ""
13708
+ })}`);
13709
+ task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
13710
+ let publishResult;
13711
+ try {
13712
+ publishResult = await proxyHttp.api({
13713
+ method: "post",
13714
+ url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
13715
+ data: publishData,
13716
+ defaultErrorMsg: "发布异常,请稍后重试。",
13717
+ headers: {
13718
+ ...headers,
13719
+ Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13720
+ "Content-Type": "application/json",
13721
+ Accept: "application/json, text/plain, */*",
13722
+ "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13723
+ "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13724
+ "bd-ticket-guard-version": "2",
13725
+ "bd-ticket-guard-web-sign-type": "1",
13726
+ "bd-ticket-guard-web-version": "2",
13727
+ "x-secsdk-csrf-token": csrfToken,
13728
+ "x-tt-session-dtrait": sessionDtrait || ""
13729
+ }
13730
+ }, {
13731
+ timeout: 60000,
13732
+ retries: 3,
13733
+ retryDelay: 2000
13734
+ });
13735
+ } catch (error) {
13736
+ const handledError = Http.handleApiError(error);
13737
+ const isProxyOrNetworkError = [
13738
+ 599,
13739
+ 500,
13740
+ 502,
13741
+ 503,
13742
+ 504
13743
+ ].includes(handledError.code);
13744
+ if (isProxyOrNetworkError) {
13745
+ const isProxyRequest = handledError.extra?.isProxyRequest === true;
13746
+ const errorType = 599 === handledError.code || isProxyRequest ? "代理错误" : "网络错误";
13747
+ const message = `图文发布失败,${errorType}:${handledError.message}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13748
+ task.logger.error(`[douyinPublish] ${errorType},直接返回: ${message}`, stringifyError(handledError));
13749
+ await updateTaskState?.({
13750
+ state: share_namespaceObject.TaskState.FAILED,
13751
+ error: message
13752
+ });
13753
+ return {
13754
+ code: 414,
13755
+ data: "",
13756
+ message
13757
+ };
13758
+ }
13759
+ throw error;
13760
+ }
13761
+ task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
13572
13762
  if (needsVerification(decision)) {
13573
- task.logger.info(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
13574
- return;
13763
+ const details = [
13764
+ publishResult.status_msg,
13765
+ decision?.verify_title,
13766
+ decision?.verify_desc
13767
+ ].filter(Boolean).join(" ");
13768
+ const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13769
+ const safeDecision = safeSerialize(decision) ?? {};
13770
+ const mockData = {
13771
+ state: share_namespaceObject.TaskState.FAILED,
13772
+ error: message,
13773
+ result: {
13774
+ ...safeDecision,
13775
+ data: decision,
13776
+ uploadedImgList: JSON.stringify(publishData.item.common.images)
13777
+ }
13778
+ };
13779
+ await updateTaskState?.(mockData);
13780
+ return {
13781
+ code: 0,
13782
+ data: mockData,
13783
+ message: "操作成功"
13784
+ };
13575
13785
  }
13576
- if (!response || !response.data) return;
13577
- const responseData = response.data;
13578
- if (response && responseData?.status_code && 0 !== responseData.status_code) {
13579
- const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
13580
- if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
13786
+ reportLogger({
13787
+ token: params.huiwenToken || "",
13788
+ enverionment: task.enverionment || "development",
13789
+ postId: params.articleId,
13790
+ eip: proxyHttp.proxyInfo,
13791
+ accountId: params.accountId,
13792
+ uid: params.uid,
13793
+ platform: "douyin",
13794
+ publishParams: publishData
13795
+ });
13796
+ task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
13797
+ const isSuccess = 0 === publishResult.status_code;
13798
+ const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13799
+ const data = isSuccess ? publishResult.item_id || "" : "";
13800
+ if (!isSuccess) {
13801
+ const safeDecision = safeSerialize(decision) ?? {};
13802
+ await updateTaskState?.({
13803
+ state: share_namespaceObject.TaskState.FAILED,
13804
+ error: message,
13805
+ result: {
13806
+ ...safeDecision,
13807
+ data: safeDecision,
13808
+ uploadedImgList: JSON.stringify(publishData.item.common.images)
13809
+ }
13810
+ });
13581
13811
  return {
13582
- code: errorCode,
13583
- message: responseData.status_msg || "文章发布异常,请稍后重试。",
13584
- data: responseData
13812
+ code: 414,
13813
+ data: safeDecision,
13814
+ message
13585
13815
  };
13586
13816
  }
13587
- });
13588
- task._timerRecord.PrePublish = Date.now();
13589
- if (MockPublish) {
13590
- const data = "123456789";
13591
- const message = `图文模拟发布成功 ${http.proxyInfo}`;
13592
13817
  await updateTaskState?.({
13593
13818
  state: share_namespaceObject.TaskState.SUCCESS,
13594
13819
  result: {
13595
13820
  response: data
13596
13821
  }
13597
13822
  });
13598
- return (0, share_namespaceObject.response)(0, message, data);
13599
- }
13600
- let webProtectData;
13601
- try {
13602
- webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
13603
- if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
13604
- task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
13605
- return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
13606
- }
13607
- } catch (error) {
13608
- task.logger.error(`解析 webProtectData 失败: ${error}`);
13609
- return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
13610
- }
13611
- let ticket = webProtectData.ticket;
13612
- let ts_sign = webProtectData.ts_sign;
13613
- const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
13614
- if (serverDataCookie) try {
13615
- const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
13616
- if (decoded.ticket && decoded.ts_sign) {
13617
- if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
13618
- ticket = decoded.ticket;
13619
- ts_sign = decoded.ts_sign;
13620
- }
13621
- } catch (error) {
13622
- task.logger.info(`[douyinPublish] 解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
13623
- }
13624
- let ec_privateKey;
13625
- try {
13626
- ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
13627
- if (!ec_privateKey) {
13628
- task.logger.error("[douyinPublish] ec_privateKey 为空");
13629
- return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
13630
- }
13631
- } catch (error) {
13632
- task.logger.error(`[douyinPublish] 解析 ec_privateKey 失败: ${error}`);
13633
- return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
13634
- }
13635
- let certificate;
13636
- try {
13637
- certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
13638
- if (!certificate) {
13639
- task.logger.error("[douyinPublish] certificate 为空");
13640
- return (0, share_namespaceObject.response)(414, "安全参数 certificate 缺失,请重新获取后重试", "");
13641
- }
13823
+ return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
13642
13824
  } catch (error) {
13643
- task.logger.error(`[douyinPublish] 解析 certificate 失败: ${error}`);
13644
- return (0, share_namespaceObject.response)(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
13645
- }
13646
- const ree_public_key = webProtectData.client_cert.replace("pub.", "");
13647
- let bdTicketGuardClientData;
13648
- try {
13649
- bdTicketGuardClientData = getBdV2({
13650
- ticket,
13651
- ts_sign: ts_sign,
13652
- ec_privateKey: ec_privateKey,
13653
- certificate: certificate,
13654
- bd_ticket_guard_ree_public_key: ree_public_key
13825
+ const handledError = Http.handleApiError(error);
13826
+ const errorMsg = handledError.message || "发布失败";
13827
+ const errorCode = handledError.code || 500;
13828
+ task.logger.error(`[douyinPublish] 发布流程异常 (步骤: ${currentStep}): ${errorMsg}`, stringifyError(error), handledError.extra);
13829
+ await updateTaskState?.({
13830
+ state: share_namespaceObject.TaskState.FAILED,
13831
+ error: `${currentStep}失败: ${errorMsg}`
13655
13832
  });
13656
- if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
13657
- task.logger.error(`[douyinPublish] bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
13658
- return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
13659
- }
13660
- } catch (error) {
13661
- task.logger.error(`[douyinPublish] 生成 bdTicketGuardClientData 失败: ${error}`);
13662
- return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
13833
+ return (0, share_namespaceObject.response)(errorCode, errorMsg, "");
13663
13834
  }
13664
- task.logger.info("[douyinPublish] bdTicketGuardClientData 生成成功");
13665
- const publishQuery = {
13666
- ...publishParams,
13667
- a_bogus: ""
13668
- };
13669
- const queryString = new URLSearchParams(publishQuery).toString();
13670
- let aBogus;
13671
- try {
13672
- aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
13673
- if (!aBogus || aBogus.length < 10) {
13674
- task.logger.error(`[douyinPublish] a_bogus 生成异常,长度过短: ${aBogus}`);
13675
- return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成失败,请重试", "");
13676
- }
13677
- } catch (error) {
13678
- task.logger.error(`[douyinPublish] 生成 a_bogus 失败: ${error}`);
13679
- return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成异常,请重试", "");
13680
- }
13681
- publishQuery.a_bogus = aBogus;
13682
- const publishQueryParams = new URLSearchParams(publishQuery).toString();
13683
- let csrfToken;
13684
- try {
13685
- csrfToken = mock_generateCsrfTokenAdvanced({
13686
- cookies: params.cookies,
13687
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
13688
- method: "POST",
13689
- userAgent
13690
- });
13691
- if (!csrfToken || csrfToken.length < 10) {
13692
- task.logger.error(`[douyinPublish] csrfToken 生成异常,长度过短: ${csrfToken}`);
13693
- return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成失败,请重试", "");
13694
- }
13695
- task.logger.info(`[douyinPublish] csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
13696
- } catch (error) {
13697
- task.logger.error(`[douyinPublish] 生成 csrfToken 失败: ${error}`);
13698
- return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成异常,请重试", "");
13699
- }
13700
- let sessionDtrait;
13701
- try {
13702
- sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
13703
- task.logger.info(`[douyinPublish] sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
13704
- } catch (error) {
13705
- task.logger.error(`[douyinPublish] 生成 sessionDtrait 失败: ${error}`);
13706
- return (0, share_namespaceObject.response)(414, "安全参数 sessionDtrait 生成异常,请重试", "");
13707
- }
13708
- task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
13709
- ...headers,
13710
- Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13711
- "Content-Type": "application/json",
13712
- Accept: "application/json, text/plain, */*",
13713
- "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13714
- "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13715
- "bd-ticket-guard-version": "2",
13716
- "bd-ticket-guard-web-sign-type": "1",
13717
- "bd-ticket-guard-web-version": "2",
13718
- "x-secsdk-csrf-token": csrfToken,
13719
- "x-tt-session-dtrait": sessionDtrait || ""
13720
- })}`);
13721
- task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
13722
- let publishResult;
13723
- try {
13724
- publishResult = await proxyHttp.api({
13725
- method: "post",
13726
- url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
13727
- data: publishData,
13728
- defaultErrorMsg: "发布异常,请稍后重试。",
13729
- headers: {
13730
- ...headers,
13731
- Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13732
- "Content-Type": "application/json",
13733
- Accept: "application/json, text/plain, */*",
13734
- "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13735
- "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13736
- "bd-ticket-guard-version": "2",
13737
- "bd-ticket-guard-web-sign-type": "1",
13738
- "bd-ticket-guard-web-version": "2",
13739
- "x-secsdk-csrf-token": csrfToken,
13740
- "x-tt-session-dtrait": sessionDtrait || ""
13741
- }
13742
- }, {
13743
- timeout: 60000,
13744
- retries: 3,
13745
- retryDelay: 2000
13746
- });
13747
- } catch (error) {
13748
- const handledError = Http.handleApiError(error);
13749
- const isProxyOrNetworkError = [
13750
- 599,
13751
- 500,
13752
- 502,
13753
- 503,
13754
- 504
13755
- ].includes(handledError.code);
13756
- if (isProxyOrNetworkError) {
13757
- const isProxyRequest = handledError.extra?.isProxyRequest === true;
13758
- const errorType = 599 === handledError.code || isProxyRequest ? "代理错误" : "网络错误";
13759
- const message = `图文发布失败,${errorType}:${handledError.message}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13760
- task.logger.error(`[douyinPublish] ${errorType},直接返回: ${message}`, stringifyError(handledError));
13761
- await updateTaskState?.({
13762
- state: share_namespaceObject.TaskState.FAILED,
13763
- error: message
13764
- });
13765
- return {
13766
- code: 414,
13767
- data: "",
13768
- message
13769
- };
13770
- }
13771
- throw error;
13772
- }
13773
- task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
13774
- if (needsVerification(decision)) {
13775
- const details = [
13776
- publishResult.status_msg,
13777
- decision?.verify_title,
13778
- decision?.verify_desc
13779
- ].filter(Boolean).join(" ");
13780
- const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13781
- let decisionObj = {};
13782
- if (decision) decisionObj = decision;
13783
- const mockData = {
13784
- state: share_namespaceObject.TaskState.FAILED,
13785
- error: message,
13786
- result: {
13787
- ...decisionObj,
13788
- data: decision,
13789
- uploadedImgList: JSON.stringify(publishData.item.common.images)
13790
- }
13791
- };
13792
- await updateTaskState?.(mockData);
13793
- return {
13794
- code: 0,
13795
- data: mockData,
13796
- message: "操作成功"
13797
- };
13798
- }
13799
- reportLogger({
13800
- token: params.huiwenToken || "",
13801
- enverionment: task.enverionment || "development",
13802
- postId: params.articleId,
13803
- eip: proxyHttp.proxyInfo,
13804
- proxyIp: params.localIP,
13805
- accountId: params.accountId,
13806
- uid: params.uid,
13807
- platform: "douyin",
13808
- publishParams: publishData
13809
- });
13810
- task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
13811
- const isSuccess = 0 === publishResult.status_code;
13812
- const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13813
- const data = isSuccess ? publishResult.item_id || "" : "";
13814
- if (!isSuccess) {
13815
- let decisionObj = {};
13816
- if (decision) decisionObj = decision;
13817
- await updateTaskState?.({
13818
- state: share_namespaceObject.TaskState.FAILED,
13819
- error: message,
13820
- result: {
13821
- ...decisionObj,
13822
- data: decision,
13823
- uploadedImgList: JSON.stringify(publishData.item.common.images)
13824
- }
13825
- });
13826
- return {
13827
- code: 414,
13828
- data,
13829
- message
13830
- };
13831
- }
13832
- await updateTaskState?.({
13833
- state: share_namespaceObject.TaskState.SUCCESS,
13834
- result: {
13835
- response: data
13836
- }
13837
- });
13838
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
13839
- };
13840
- const douyinPublish_rpa_rpaAction = async (task, params)=>{
13841
- const commonCookies = {
13842
- path: "/",
13843
- secure: true,
13844
- domain: "douyin.com",
13845
- url: "https://creator.douyin.com",
13846
- httpOnly: true
13835
+ };
13836
+ const douyinPublish_rpa_rpaAction = async (task, params)=>{
13837
+ const commonCookies = {
13838
+ path: "/",
13839
+ secure: true,
13840
+ domain: "douyin.com",
13841
+ url: "https://creator.douyin.com",
13842
+ httpOnly: true
13847
13843
  };
13848
13844
  const page = await task.createPage({
13849
13845
  show: task.debug,
@@ -14154,18 +14150,13 @@ var __webpack_exports__ = {};
14154
14150
  return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
14155
14151
  }));
14156
14152
  let proxyUrl;
14157
- if (params.localIP) {
14158
- const args = [
14159
- params.localIP,
14160
- params.proxyLoc,
14161
- params.accountId
14162
- ];
14163
- task.logger?.info(`==> 开始获取代理信息:${args}`);
14164
- const proxyAgentResult = await ProxyAgent({
14153
+ if (params.proxyLoc) {
14154
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
14155
+ const ProxyAgentResult = await ProxyAgent({
14165
14156
  logger: task.logger
14166
- }, ...args);
14157
+ }, params.proxyLoc, params.accountId);
14167
14158
  task.logger?.info("==> 代理信息获取成功!");
14168
- proxyUrl = proxyAgentResult ? `http://${proxyAgentResult.ip}:${proxyAgentResult.port}` : void 0;
14159
+ proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
14169
14160
  }
14170
14161
  const commonCookies = {
14171
14162
  path: "/",
@@ -15122,7 +15113,6 @@ var __webpack_exports__ = {};
15122
15113
  },
15123
15114
  _task.logger,
15124
15115
  params.proxyLoc,
15125
- params.localIP,
15126
15116
  params.accountId
15127
15117
  ];
15128
15118
  const http = new Http(...args);
@@ -15180,7 +15170,6 @@ var __webpack_exports__ = {};
15180
15170
  },
15181
15171
  _task.logger,
15182
15172
  params.proxyLoc,
15183
- params.localIP,
15184
15173
  params.accountId
15185
15174
  ];
15186
15175
  const http = new Http(...args);
@@ -15227,7 +15216,6 @@ var __webpack_exports__ = {};
15227
15216
  },
15228
15217
  _task.logger,
15229
15218
  params.proxyLoc,
15230
- params.localIP,
15231
15219
  params.accountId
15232
15220
  ];
15233
15221
  const http = new Http(...args);
@@ -15288,7 +15276,6 @@ var __webpack_exports__ = {};
15288
15276
  },
15289
15277
  _task.logger,
15290
15278
  params.proxyLoc,
15291
- params.localIP,
15292
15279
  params.accountId
15293
15280
  ];
15294
15281
  const http = new Http(...args);
@@ -15361,6 +15348,239 @@ var __webpack_exports__ = {};
15361
15348
  };
15362
15349
  return (0, share_namespaceObject.success)(bjhData, "百家号平台数据获取成功!");
15363
15350
  }
15351
+ async function getDouyinData(_task, params) {
15352
+ try {
15353
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15354
+ if (!sessionidCookie) return types_errorResponse("抖音账号数据异常,请重新绑定账号后重试。", 414);
15355
+ const csrfToken = params.cookies.find((it)=>"passport_csrf_token" === it.name)?.value || "";
15356
+ const headers = {
15357
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15358
+ referer: "https://creator.douyin.com/creator-micro/home",
15359
+ origin: "https://creator.douyin.com",
15360
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
15361
+ ...csrfToken ? {
15362
+ "x-secsdk-csrf-token": csrfToken
15363
+ } : {}
15364
+ };
15365
+ const args = [
15366
+ {
15367
+ headers
15368
+ },
15369
+ _task.logger,
15370
+ params.proxyLoc,
15371
+ params.accountId
15372
+ ];
15373
+ const http = new Http(...args);
15374
+ const toNum = (val)=>{
15375
+ if (null == val) return 0;
15376
+ const n = Number.parseInt(String(val).replace(/[+,]/g, ""), 10);
15377
+ return Number.isNaN(n) ? 0 : n;
15378
+ };
15379
+ const userProfileP = http.api({
15380
+ method: "get",
15381
+ url: "https://www.douyin.com/aweme/v1/web/user/profile/self/",
15382
+ params: {
15383
+ device_platform: "webapp",
15384
+ aid: "6383",
15385
+ channel: "channel_pc_web",
15386
+ pc_client_type: "1",
15387
+ version_code: "170400",
15388
+ version_name: "17.4.0",
15389
+ cookie_enabled: "true",
15390
+ platform: "PC"
15391
+ }
15392
+ }, {
15393
+ retries: 3,
15394
+ retryDelay: 100,
15395
+ timeout: 10000
15396
+ }).catch((e)=>{
15397
+ _task.logger.warn(`抖音用户信息获取失败: ${e instanceof Error ? e.message : String(e)}`);
15398
+ return null;
15399
+ });
15400
+ const overviewP = http.api({
15401
+ method: "get",
15402
+ url: "https://creator.douyin.com/aweme/janus/creator/data/overview/all/",
15403
+ params: {
15404
+ last_days_type: 1,
15405
+ aid: 2906,
15406
+ app_name: "aweme_creator_platform",
15407
+ device_platform: "web"
15408
+ }
15409
+ }, {
15410
+ retries: 3,
15411
+ retryDelay: 100,
15412
+ timeout: 5000
15413
+ }).catch((e)=>{
15414
+ _task.logger.warn(`抖音近7日数据获取失败(可能未开通数据中心或被风控): ${e instanceof Error ? e.message : String(e)}`);
15415
+ return null;
15416
+ });
15417
+ const [userProfile, overview] = await Promise.all([
15418
+ userProfileP,
15419
+ overviewP
15420
+ ]);
15421
+ let fansNum = 0;
15422
+ let favedNum = 0;
15423
+ let followingNum = 0;
15424
+ if (userProfile?.status_code === 0 && userProfile.user) {
15425
+ const user = userProfile.user;
15426
+ fansNum = toNum(user.follower_count);
15427
+ followingNum = toNum(user.following_count);
15428
+ favedNum = toNum(user.total_favorited);
15429
+ } else _task.logger.warn(`用户信息接口返回异常: status_code=${userProfile?.status_code}, msg=${userProfile?.status_msg}`);
15430
+ const ov = overview?.data;
15431
+ const douyinData = {
15432
+ fansNum,
15433
+ favedNum,
15434
+ fansNumLastWeek: toNum(ov?.new_fans?.last_period_incr),
15435
+ watchNumLastWeek: toNum(ov?.play?.last_period_incr),
15436
+ likeNumLastWeek: toNum(ov?.digg?.last_period_incr),
15437
+ commentNumLastWeek: toNum(ov?.comment?.last_period_incr),
15438
+ shareNumLastWeek: toNum(ov?.share?.last_period_incr),
15439
+ visitNumLastWeek: toNum(ov?.profile?.last_period_incr)
15440
+ };
15441
+ return (0, share_namespaceObject.success)(douyinData, "抖音平台数据获取成功!");
15442
+ } catch (error) {
15443
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15444
+ const err = error;
15445
+ _task.logger.error(`抖音账号数据获取失败: ${err.message} (${err.code})`);
15446
+ return types_errorResponse(err.message, err.code);
15447
+ }
15448
+ const errMsg = error instanceof Error ? error.message : String(error);
15449
+ _task.logger.error(`抖音账号数据获取失败: ${errMsg}`);
15450
+ return types_errorResponse(errMsg || "抖音账号数据获取失败");
15451
+ }
15452
+ }
15453
+ async function getShipinhaoData(_task, params) {
15454
+ try {
15455
+ const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15456
+ if (!sessionidCookie) return types_errorResponse("视频号账号数据异常,请重新绑定账号后重试。", 414);
15457
+ const uinCookie = params.cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
15458
+ const deviceIdCookie = params.cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
15459
+ const aid = params.cookies.find((it)=>"_aid" === it.name)?.value || "9d3e0e9f-b842-498d-a273-4285d58df264";
15460
+ const finderId = params.cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
15461
+ const headers = {
15462
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15463
+ referer: "https://channels.weixin.qq.com/platform",
15464
+ origin: "https://channels.weixin.qq.com",
15465
+ "content-type": "application/json",
15466
+ "X-WECHAT-UIN": uinCookie,
15467
+ ...deviceIdCookie ? {
15468
+ "finger-print-device-id": deviceIdCookie
15469
+ } : {}
15470
+ };
15471
+ const args = [
15472
+ {
15473
+ headers
15474
+ },
15475
+ _task.logger,
15476
+ params.proxyLoc,
15477
+ params.accountId
15478
+ ];
15479
+ const http = new Http(...args);
15480
+ const authData = await http.api({
15481
+ method: "post",
15482
+ url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/auth/auth_data",
15483
+ params: {
15484
+ _aid: aid,
15485
+ _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15486
+ _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15487
+ },
15488
+ data: {
15489
+ timestamp: Date.now().toString(),
15490
+ _log_finder_uin: "",
15491
+ _log_finder_id: finderId,
15492
+ rawKeyBuff: "",
15493
+ pluginSessionId: null,
15494
+ scene: 7,
15495
+ reqScene: 7
15496
+ }
15497
+ }, {
15498
+ retries: 3,
15499
+ retryDelay: 100,
15500
+ timeout: 5000
15501
+ });
15502
+ const AUTH_ERROR_CODES = [
15503
+ 300333,
15504
+ 300334,
15505
+ 300330,
15506
+ 300331,
15507
+ 300332
15508
+ ];
15509
+ if (authData.errCode && AUTH_ERROR_CODES.includes(authData.errCode)) {
15510
+ _task.logger.warn(`视频号登录已失效:${authData.errMsg} (${authData.errCode})`);
15511
+ return types_errorResponse("视频号账号信息获取失败,请检查账号状态", 414);
15512
+ }
15513
+ if (authData.errCode) {
15514
+ _task.logger.warn(`视频号账号API错误:${authData.errMsg} (${authData.errCode})`);
15515
+ return types_errorResponse(`视频号账号信息获取失败:${authData.errMsg || "未知错误"}`, 414);
15516
+ }
15517
+ const finderUser = authData.data?.finderUser;
15518
+ const now = new Date();
15519
+ const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 2);
15520
+ const startTs = Math.floor(yesterday.getTime() / 1000);
15521
+ const endTs = startTs + 86400;
15522
+ _task.logger.info(`视频号昨日数据范围 start: ${startTs} ~ end: ${endTs}`);
15523
+ let fansNumYesterday = 0;
15524
+ let playNumYesterday = 0;
15525
+ let likeNumYesterday = 0;
15526
+ let commentNumYesterday = 0;
15527
+ try {
15528
+ const statsData = await http.api({
15529
+ method: "post",
15530
+ url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/statistic/new_post_total_data",
15531
+ params: {
15532
+ _aid: aid,
15533
+ _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15534
+ _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15535
+ },
15536
+ data: {
15537
+ startTs: startTs.toString(),
15538
+ endTs: endTs.toString(),
15539
+ interval: 3,
15540
+ timestamp: Date.now().toString(),
15541
+ _log_finder_uin: "",
15542
+ _log_finder_id: finderId,
15543
+ rawKeyBuff: "",
15544
+ pluginSessionId: null,
15545
+ scene: 7,
15546
+ reqScene: 7
15547
+ }
15548
+ }, {
15549
+ retries: 3,
15550
+ retryDelay: 100,
15551
+ timeout: 5000
15552
+ });
15553
+ if (!statsData.errCode && statsData.data?.totalData) {
15554
+ const data = statsData.data.totalData;
15555
+ fansNumYesterday = Number.parseInt(data.follow?.[1] || "0", 10) || 0;
15556
+ playNumYesterday = Number.parseInt(data.browse?.[1] || "0", 10) || 0;
15557
+ likeNumYesterday = Number.parseInt(data.like?.[1] || "0", 10) || 0;
15558
+ commentNumYesterday = Number.parseInt(data.comment?.[1] || "0", 10) || 0;
15559
+ }
15560
+ } catch (error) {
15561
+ const errMsg = error instanceof Error ? error.message : String(error);
15562
+ _task.logger.warn(`视频号昨日数据获取失败(降级为null): ${errMsg}`);
15563
+ }
15564
+ const shipinhaoData = {
15565
+ fansNum: finderUser?.fansCount || 0,
15566
+ feedsCount: finderUser?.feedsCount || 0,
15567
+ fansNumYesterday,
15568
+ playNumYesterday,
15569
+ likeNumYesterday,
15570
+ commentNumYesterday
15571
+ };
15572
+ return (0, share_namespaceObject.success)(shipinhaoData, "视频号平台数据获取成功!");
15573
+ } catch (error) {
15574
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
15575
+ const err = error;
15576
+ _task.logger.error(`视频号账号数据获取失败: ${err.message} (${err.code})`);
15577
+ return types_errorResponse(err.message, err.code);
15578
+ }
15579
+ const errMsg = error instanceof Error ? error.message : String(error);
15580
+ _task.logger.error(`视频号账号数据获取失败: ${errMsg}`);
15581
+ return types_errorResponse(errMsg || "视频号账号数据获取失败");
15582
+ }
15583
+ }
15364
15584
  async function getToutiaoData(_task, params) {
15365
15585
  const http = new Http({
15366
15586
  headers: {
@@ -15459,7 +15679,7 @@ var __webpack_exports__ = {};
15459
15679
  userInfoHtmlPromise,
15460
15680
  userSummaryHtmlPromise
15461
15681
  ]);
15462
- if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("Token已失效,请重新获取", 414);
15682
+ if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15463
15683
  const userInfoJson = exportWxCgiData(userInfoHtml);
15464
15684
  const userSummaryJson = exportWxCgiData(userSummaryHtml);
15465
15685
  const wxData = {
@@ -15484,7 +15704,6 @@ var __webpack_exports__ = {};
15484
15704
  },
15485
15705
  _task.logger,
15486
15706
  params.proxyLoc,
15487
- params.localIP,
15488
15707
  params.accountId
15489
15708
  ];
15490
15709
  const http = new Http(...args);
@@ -15536,7 +15755,9 @@ var __webpack_exports__ = {};
15536
15755
  "toutiao",
15537
15756
  "xiaohongshu",
15538
15757
  "weixin",
15539
- "baijiahao"
15758
+ "baijiahao",
15759
+ "douyin",
15760
+ "shipinhao"
15540
15761
  ])
15541
15762
  });
15542
15763
  const SearchAccountInfo = async (_task, params)=>{
@@ -15550,6 +15771,10 @@ var __webpack_exports__ = {};
15550
15771
  return getWeixinData(_task, params);
15551
15772
  case "baijiahao":
15552
15773
  return getBaijiahaoData(_task, params);
15774
+ case "douyin":
15775
+ return getDouyinData(_task, params);
15776
+ case "shipinhao":
15777
+ return getShipinhaoData(_task, params);
15553
15778
  default:
15554
15779
  return (0, share_namespaceObject.success)(null, "暂不支持该平台");
15555
15780
  }
@@ -15644,18 +15869,45 @@ var __webpack_exports__ = {};
15644
15869
  collectNum: schemas_number(),
15645
15870
  shareNum: schemas_number()
15646
15871
  });
15872
+ const DouyinArticleSchema = BaseArticleSchema.extend({
15873
+ playNum: schemas_number(),
15874
+ likeNum: schemas_number(),
15875
+ commentNum: schemas_number(),
15876
+ shareNum: schemas_number(),
15877
+ collectNum: schemas_number(),
15878
+ awemeId: schemas_string(),
15879
+ awemeType: schemas_number(),
15880
+ duration: schemas_number().optional(),
15881
+ status: schemas_string(),
15882
+ publicUrl: schemas_string()
15883
+ });
15884
+ const ShipinhaoArticleSchema = BaseArticleSchema.extend({
15885
+ readNum: schemas_number(),
15886
+ likeNum: schemas_number(),
15887
+ commentNum: schemas_number(),
15888
+ forwardNum: schemas_number(),
15889
+ favNum: schemas_number(),
15890
+ objectId: schemas_string(),
15891
+ postType: schemas_string(),
15892
+ postStatus: schemas_number(),
15893
+ effectiveTime: schemas_number().optional()
15894
+ });
15647
15895
  const FetchArticlesDataSchema = schemas_object({
15648
15896
  articleCell: schemas_array(union([
15649
15897
  ToutiaoArticleSchema,
15650
15898
  WeixinArticleSchema,
15651
15899
  BaijiahaoArticleSchema,
15652
- XiaohongshuArticleSchema
15900
+ XiaohongshuArticleSchema,
15901
+ DouyinArticleSchema,
15902
+ ShipinhaoArticleSchema
15653
15903
  ])).optional(),
15654
15904
  timerPublish: schemas_array(union([
15655
15905
  ToutiaoArticleSchema,
15656
15906
  WeixinArticleSchema,
15657
15907
  BaijiahaoArticleSchema,
15658
- XiaohongshuArticleSchema
15908
+ XiaohongshuArticleSchema,
15909
+ DouyinArticleSchema,
15910
+ ShipinhaoArticleSchema
15659
15911
  ])).optional(),
15660
15912
  pagination: schemas_object({
15661
15913
  total: schemas_number().optional(),
@@ -15770,6 +16022,267 @@ var __webpack_exports__ = {};
15770
16022
  return searchPublishInfo_types_errorResponse(error instanceof Error ? error.message : "百家号文章数据获取失败");
15771
16023
  }
15772
16024
  }
16025
+ async function handleDouyinData(_task, params) {
16026
+ try {
16027
+ const { cookies, pageSize = 12, status = 0, showOriginalData = false, onlySuccess = false } = params;
16028
+ const pageNum = params.pageNum || 1;
16029
+ const headers = {
16030
+ cookie: cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
16031
+ referer: "https://creator.douyin.com"
16032
+ };
16033
+ const args = [
16034
+ {
16035
+ headers
16036
+ },
16037
+ _task.logger,
16038
+ params.proxyLoc,
16039
+ params.accountId
16040
+ ];
16041
+ const http = new Http(...args);
16042
+ async function fetchWorks(cursor) {
16043
+ return await http.api({
16044
+ method: "get",
16045
+ url: "https://creator.douyin.com/janus/douyin/creator/pc/work_list",
16046
+ params: {
16047
+ scene: "star_atlas",
16048
+ device_platform: "android",
16049
+ aid: 1128,
16050
+ status,
16051
+ count: pageSize,
16052
+ max_cursor: cursor
16053
+ }
16054
+ }, {
16055
+ retries: 3,
16056
+ retryDelay: 100,
16057
+ timeout: 5000
16058
+ });
16059
+ }
16060
+ const isHasMore = (v)=>true === v || 1 === v;
16061
+ const skipCount = (pageNum - 1) * pageSize;
16062
+ const needCount = skipCount + pageSize;
16063
+ const workListResponse = await fetchWorks(0);
16064
+ if (!workListResponse || !Array.isArray(workListResponse.aweme_list)) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
16065
+ const allWorks = [
16066
+ ...workListResponse.aweme_list
16067
+ ];
16068
+ let hasMore = isHasMore(workListResponse.has_more);
16069
+ let currentCursor = workListResponse.cursor ?? workListResponse.max_cursor ?? 0;
16070
+ let guard = 0;
16071
+ while(allWorks.length < needCount && hasMore && guard < 20){
16072
+ const nextPageResponse = await fetchWorks(currentCursor);
16073
+ if (!Array.isArray(nextPageResponse.aweme_list) || 0 === nextPageResponse.aweme_list.length) break;
16074
+ allWorks.push(...nextPageResponse.aweme_list);
16075
+ hasMore = isHasMore(nextPageResponse.has_more);
16076
+ currentCursor = nextPageResponse.cursor ?? nextPageResponse.max_cursor ?? currentCursor;
16077
+ guard++;
16078
+ }
16079
+ const finalWorks = allWorks.slice(skipCount, needCount);
16080
+ const articleCell = finalWorks.map((item)=>{
16081
+ const workDetailUrl = `https://creator.douyin.com/creator-micro/work-management/work-detail/${item.aweme_id}`;
16082
+ const workPublicUrl = item.share_url || `https://www.douyin.com/video/${item.aweme_id}`;
16083
+ let statusText;
16084
+ statusText = item.status?.is_delete ? "deleted" : item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public";
16085
+ return {
16086
+ title: item.desc || "无作品描述",
16087
+ imageUrl: item.Cover?.url_list?.[0] || "",
16088
+ createTime: item.create_time,
16089
+ redirectUrl: workDetailUrl,
16090
+ playNum: item.statistics?.play_count || 0,
16091
+ likeNum: item.statistics?.digg_count || 0,
16092
+ commentNum: item.statistics?.comment_count || 0,
16093
+ shareNum: item.statistics?.share_count || 0,
16094
+ collectNum: item.statistics?.collect_count || 0,
16095
+ awemeId: item.aweme_id,
16096
+ awemeType: item.aweme_type ?? 0,
16097
+ duration: item.duration,
16098
+ status: statusText,
16099
+ publicUrl: workPublicUrl,
16100
+ ...showOriginalData ? {
16101
+ originalData: item
16102
+ } : {}
16103
+ };
16104
+ });
16105
+ return (0, share_namespaceObject.success)({
16106
+ articleCell,
16107
+ ...onlySuccess ? {
16108
+ pagination: {
16109
+ total: workListResponse.total || allWorks.length,
16110
+ nextPage: hasMore,
16111
+ pageNum,
16112
+ pageSize
16113
+ }
16114
+ } : null
16115
+ }, "抖音数据获取成功");
16116
+ } catch (error) {
16117
+ return searchPublishInfo_types_errorResponse(error instanceof Error ? error.message : "抖音数据获取失败");
16118
+ }
16119
+ }
16120
+ async function handleShipinhaoData(_task, params) {
16121
+ try {
16122
+ const { cookies, postType = "all", pageSize = 10, showOriginalData = false } = params;
16123
+ const pageNum = params.pageNum || 1;
16124
+ const aidCookie = cookies.find((it)=>"_aid" === it.name)?.value;
16125
+ const aid = aidCookie || "9d3e0e9f-b842-498d-a273-4285d58df264";
16126
+ const uinCookie = cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
16127
+ const deviceIdCookie = cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
16128
+ const headers = {
16129
+ cookie: cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
16130
+ referer: "https://channels.weixin.qq.com",
16131
+ origin: "https://channels.weixin.qq.com",
16132
+ "content-type": "application/json",
16133
+ "X-WECHAT-UIN": uinCookie,
16134
+ ...deviceIdCookie ? {
16135
+ "finger-print-device-id": deviceIdCookie
16136
+ } : {}
16137
+ };
16138
+ const args = [
16139
+ {
16140
+ headers
16141
+ },
16142
+ _task.logger,
16143
+ params.proxyLoc,
16144
+ params.accountId
16145
+ ];
16146
+ const http = new Http(...args);
16147
+ const finderIdCookie = cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
16148
+ async function fetchPosts(currentPage, userpageType, pageUrl, rawKeyBuff = "") {
16149
+ return await http.api({
16150
+ method: "post",
16151
+ url: "https://channels.weixin.qq.com/micro/content/cgi-bin/mmfinderassistant-bin/post/post_list",
16152
+ params: {
16153
+ _aid: aid,
16154
+ _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
16155
+ _pageUrl: encodeURIComponent(pageUrl)
16156
+ },
16157
+ data: {
16158
+ pageSize,
16159
+ currentPage,
16160
+ userpageType,
16161
+ stickyOrder: true,
16162
+ timestamp: Date.now().toString(),
16163
+ _log_finder_uin: "",
16164
+ _log_finder_id: finderIdCookie,
16165
+ rawKeyBuff,
16166
+ pluginSessionId: null,
16167
+ scene: 7,
16168
+ reqScene: 7
16169
+ }
16170
+ }, {
16171
+ retries: 3,
16172
+ retryDelay: 100,
16173
+ timeout: 5000
16174
+ });
16175
+ }
16176
+ async function fetchAllPosts(userpageType, pageUrl) {
16177
+ const allPosts = [];
16178
+ let currentPage = 1;
16179
+ let rawKeyBuff = "";
16180
+ let continueFlag = true;
16181
+ let totalCount = 0;
16182
+ while(continueFlag){
16183
+ const response = await fetchPosts(currentPage, userpageType, pageUrl, rawKeyBuff);
16184
+ if (response.errCode && AUTH_ERROR_CODES.includes(response.errCode)) throw new Error(`AUTH_ERROR:${response.errMsg || "登录已失效"}`);
16185
+ if (response.errCode) {
16186
+ _task.logger.warn(`视频号API错误:${response.errMsg} (${response.errCode})`);
16187
+ throw new Error(`视频号API错误:${response.errMsg} (${response.errCode})`);
16188
+ }
16189
+ if (1 === currentPage) totalCount = response.data?.totalCount ?? 0;
16190
+ const posts = response.data?.list || response.posts || response.post_list || [];
16191
+ allPosts.push(...posts);
16192
+ continueFlag = response.data?.continueFlag ?? false;
16193
+ rawKeyBuff = response.data?.lastBuff || "";
16194
+ currentPage++;
16195
+ if (currentPage > 100) {
16196
+ _task.logger.warn("分页超过100页,停止请求");
16197
+ break;
16198
+ }
16199
+ }
16200
+ if (totalCount > 0 && allPosts.length !== totalCount) _task.logger.warn(`视频号分页可能不完整:期望${totalCount}条,实际${allPosts.length}条`);
16201
+ return {
16202
+ posts: allPosts,
16203
+ totalCount
16204
+ };
16205
+ }
16206
+ const mapPost = (item, forcePostType)=>{
16207
+ let imageUrl = "";
16208
+ if (item.desc?.media?.[0]?.thumbUrl) imageUrl = item.desc.media[0].thumbUrl;
16209
+ else if (item.desc?.media?.[0]?.coverUrl) imageUrl = item.desc.media[0].coverUrl;
16210
+ else if (item.cover?.url) imageUrl = item.cover.url;
16211
+ else if (item.media_url) imageUrl = item.media_url;
16212
+ const title = item.desc?.description || item.object_desc || "无标题";
16213
+ return {
16214
+ title,
16215
+ imageUrl,
16216
+ createTime: item.createTime || item.create_time,
16217
+ redirectUrl: "https://channels.weixin.qq.com/platform",
16218
+ readNum: item.readCount || item.read_count || 0,
16219
+ likeNum: item.likeCount || item.like_count || 0,
16220
+ commentNum: item.commentCount || item.comment_count || 0,
16221
+ forwardNum: item.forwardCount || item.forward_count || 0,
16222
+ favNum: item.favCount || item.fav_count || 0,
16223
+ objectId: item.exportId || item.objectId || "",
16224
+ postType: forcePostType,
16225
+ postStatus: item.status || item.post_status || 0,
16226
+ ...item.effectiveTime ? {
16227
+ effectiveTime: item.effectiveTime
16228
+ } : {},
16229
+ ...showOriginalData ? {
16230
+ originalData: item
16231
+ } : {}
16232
+ };
16233
+ };
16234
+ const allArticles = [];
16235
+ const needVideo = "all" === postType || "video" === postType;
16236
+ const needArticle = "all" === postType || "article" === postType;
16237
+ const AUTH_ERROR_CODES = [
16238
+ 300333,
16239
+ 300334,
16240
+ 300330,
16241
+ 300331,
16242
+ 300332
16243
+ ];
16244
+ let combinedTotal = 0;
16245
+ if (needVideo) try {
16246
+ const videoPageUrl = "https://channels.weixin.qq.com/micro/content/post/list";
16247
+ const { posts, totalCount } = await fetchAllPosts(11, videoPageUrl);
16248
+ const videoArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "video"));
16249
+ allArticles.push(...videoArticles);
16250
+ combinedTotal += totalCount || videoArticles.length;
16251
+ } catch (error) {
16252
+ const errMsg = error instanceof Error ? error.message : String(error);
16253
+ if (errMsg.startsWith("AUTH_ERROR:")) throw error;
16254
+ _task.logger.warn(`获取视频号视频失败:${errMsg}`);
16255
+ }
16256
+ if (needArticle) try {
16257
+ const articlePageUrl = "https://channels.weixin.qq.com/micro/content/post/finderNewLifePostList";
16258
+ const { posts, totalCount } = await fetchAllPosts(10, articlePageUrl);
16259
+ const articleArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "article"));
16260
+ allArticles.push(...articleArticles);
16261
+ combinedTotal += totalCount || articleArticles.length;
16262
+ } catch (error) {
16263
+ const errMsg = error instanceof Error ? error.message : String(error);
16264
+ if (errMsg.startsWith("AUTH_ERROR:")) throw error;
16265
+ _task.logger.warn(`获取视频号图文失败:${errMsg}`);
16266
+ }
16267
+ allArticles.sort((a, b)=>b.createTime - a.createTime);
16268
+ const total = allArticles.length;
16269
+ const start = (pageNum - 1) * pageSize;
16270
+ const pageItems = allArticles.slice(start, start + pageSize);
16271
+ return (0, share_namespaceObject.success)({
16272
+ articleCell: pageItems,
16273
+ pagination: {
16274
+ total,
16275
+ nextPage: start + pageSize < total,
16276
+ pageNum,
16277
+ pageSize
16278
+ }
16279
+ }, "视频号数据获取成功");
16280
+ } catch (error) {
16281
+ const errMsg = error instanceof Error ? error.message : String(error);
16282
+ if (errMsg.startsWith("AUTH_ERROR:")) return searchPublishInfo_types_errorResponse("视频号数据获取失败,请检查账号状态", 414);
16283
+ return searchPublishInfo_types_errorResponse(errMsg || "视频号数据获取失败");
16284
+ }
16285
+ }
15773
16286
  async function handleToutiaoData(_task, params) {
15774
16287
  try {
15775
16288
  const { cookies, pageNum = 1, pageSize = 10, showOriginalData = false, onlySuccess = false, containsArticle = false } = params;
@@ -15802,7 +16315,7 @@ var __webpack_exports__ = {};
15802
16315
  app_id: 1231
15803
16316
  }
15804
16317
  });
15805
- if (0 !== visitedUid.code) return searchPublishInfo_types_errorResponse("头条号账号信息获取失败,请检查账号状态", 414);
16318
+ if (0 !== visitedUid.code) return searchPublishInfo_types_errorResponse("头条号数据获取失败,请检查账号状态", 414);
15806
16319
  const articleInfo = await http.api({
15807
16320
  method: "get",
15808
16321
  url: "https://mp.toutiao.com/api/feed/mp_provider/v1/",
@@ -15911,7 +16424,7 @@ var __webpack_exports__ = {};
15911
16424
  const size = onlySuccess ? 10 : pageSize > 20 ? 20 : pageSize;
15912
16425
  let begin = (lastPage ?? pageNum) - 1;
15913
16426
  const rawArticlesInfo = await fetchArticles(begin * size, size, token);
15914
- if (rawArticlesInfo.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return searchPublishInfo_types_errorResponse("登陆已失效,请重新登陆!", 414);
16427
+ if (rawArticlesInfo.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return searchPublishInfo_types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15915
16428
  const articlesInfo = ParsePublishPage(rawArticlesInfo);
15916
16429
  let articleCell = [];
15917
16430
  if (!onlySuccess && pageSize > 20) {
@@ -16073,7 +16586,7 @@ var __webpack_exports__ = {};
16073
16586
  const a1Cookie = cookies.find((it)=>"a1" === it.name)?.value;
16074
16587
  if (!a1Cookie) return {
16075
16588
  code: 414,
16076
- message: "账号数据异常",
16589
+ message: "小红书数据获取失败,请检查账号状态",
16077
16590
  data: {}
16078
16591
  };
16079
16592
  if (onlySuccess && 10 !== pageSize) return {
@@ -16092,7 +16605,6 @@ var __webpack_exports__ = {};
16092
16605
  },
16093
16606
  _task.logger,
16094
16607
  params.proxyLoc,
16095
- params.localIP,
16096
16608
  params.accountId
16097
16609
  ];
16098
16610
  const http = new Http(...args);
@@ -16192,7 +16704,7 @@ var __webpack_exports__ = {};
16192
16704
  }, "小红书文章数据获取成功");
16193
16705
  }
16194
16706
  const FetchArticlesParamsSchema = ActionCommonParamsSchema.extend({
16195
- platform: schemas_string().describe("社交平台:weixin, toutiao, baijiahao, xiaohongshu"),
16707
+ platform: schemas_string().describe("社交平台:weixin, toutiao, baijiahao, xiaohongshu, douyin, shipinhao"),
16196
16708
  token: union([
16197
16709
  schemas_string(),
16198
16710
  schemas_number()
@@ -16204,7 +16716,14 @@ var __webpack_exports__ = {};
16204
16716
  showOriginalData: schemas_boolean().optional().describe("是否展示原始数据,默认false"),
16205
16717
  cursor: schemas_number().optional().describe("仅用于微信分页游标,默认为空"),
16206
16718
  lastPage: schemas_number().optional(),
16207
- containsArticle: schemas_boolean().optional().describe("是否包含文章内容,默认false")
16719
+ containsArticle: schemas_boolean().optional().describe("是否包含文章内容,默认false"),
16720
+ status: schemas_number().optional().describe("抖音作品状态:0=全部"),
16721
+ includeAccount: schemas_boolean().optional().describe("是否包含账号数据,默认true"),
16722
+ postType: schemas_enum([
16723
+ "video",
16724
+ "article",
16725
+ "all"
16726
+ ]).optional().describe("视频号作品类型:video=视频, article=图文, all=全部")
16208
16727
  });
16209
16728
  const FetchArticles = async (_task, params)=>{
16210
16729
  const { platform } = params;
@@ -16217,6 +16736,10 @@ var __webpack_exports__ = {};
16217
16736
  return handleBaijiahaoData(_task, params);
16218
16737
  case "xiaohongshu":
16219
16738
  return handleXiaohongshuData(_task, params);
16739
+ case "douyin":
16740
+ return handleDouyinData(_task, params);
16741
+ case "shipinhao":
16742
+ return handleShipinhaoData(_task, params);
16220
16743
  default:
16221
16744
  return (0, share_namespaceObject.success)({}, "暂不支持该平台");
16222
16745
  }
@@ -16412,7 +16935,6 @@ var __webpack_exports__ = {};
16412
16935
  },
16413
16936
  _task.logger,
16414
16937
  params.proxyLoc,
16415
- params.localIP,
16416
16938
  params.accountId
16417
16939
  ];
16418
16940
  const http = new Http(...args);
@@ -16465,7 +16987,6 @@ var __webpack_exports__ = {};
16465
16987
  },
16466
16988
  _task.logger,
16467
16989
  params.proxyLoc,
16468
- params.localIP,
16469
16990
  params.accountId
16470
16991
  ];
16471
16992
  const http = new Http(...args);
@@ -16518,7 +17039,6 @@ var __webpack_exports__ = {};
16518
17039
  },
16519
17040
  _task.logger,
16520
17041
  params.proxyLoc,
16521
- params.localIP,
16522
17042
  params.accountId
16523
17043
  ];
16524
17044
  const http = new Http(...args);
@@ -16565,7 +17085,6 @@ var __webpack_exports__ = {};
16565
17085
  },
16566
17086
  _task.logger,
16567
17087
  params.proxyLoc,
16568
- params.localIP,
16569
17088
  params.accountId
16570
17089
  ];
16571
17090
  const http = new Http(...args);
@@ -16604,7 +17123,6 @@ var __webpack_exports__ = {};
16604
17123
  },
16605
17124
  _task.logger,
16606
17125
  params.proxyLoc,
16607
- params.localIP,
16608
17126
  params.accountId
16609
17127
  ];
16610
17128
  const http = new Http(...args);
@@ -16666,7 +17184,6 @@ var __webpack_exports__ = {};
16666
17184
  },
16667
17185
  _task.logger,
16668
17186
  params.proxyLoc,
16669
- params.localIP,
16670
17187
  params.accountId
16671
17188
  ];
16672
17189
  const http = new Http(...args);
@@ -16723,7 +17240,6 @@ var __webpack_exports__ = {};
16723
17240
  },
16724
17241
  _task.logger,
16725
17242
  params.proxyLoc,
16726
- params.localIP,
16727
17243
  params.accountId
16728
17244
  ];
16729
17245
  const http = new Http(...args);
@@ -16809,7 +17325,6 @@ var __webpack_exports__ = {};
16809
17325
  },
16810
17326
  _task.logger,
16811
17327
  params.proxyLoc,
16812
- params.localIP,
16813
17328
  params.accountId
16814
17329
  ];
16815
17330
  const http = new Http(...args);
@@ -16897,7 +17412,6 @@ var __webpack_exports__ = {};
16897
17412
  },
16898
17413
  _task.logger,
16899
17414
  params.proxyLoc,
16900
- params.localIP,
16901
17415
  params.accountId
16902
17416
  ];
16903
17417
  const http = new Http(...args);
@@ -17007,7 +17521,6 @@ var __webpack_exports__ = {};
17007
17521
  },
17008
17522
  _task.logger,
17009
17523
  params.proxyLoc,
17010
- params.localIP,
17011
17524
  params.accountId
17012
17525
  ];
17013
17526
  const http = new Http(...args);
@@ -17285,16 +17798,11 @@ var __webpack_exports__ = {};
17285
17798
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
17286
17799
  let executionState;
17287
17800
  let proxyUrl;
17288
- if (params.localIP) {
17289
- const args = [
17290
- params.localIP,
17291
- params.proxyLoc,
17292
- params.accountId
17293
- ];
17294
- task.logger?.info(`==> 开始获取代理信息:${args}`);
17801
+ if (params.proxyLoc) {
17802
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
17295
17803
  const ProxyAgentResult = await ProxyAgent({
17296
17804
  logger: task.logger
17297
- }, ...args);
17805
+ }, params.proxyLoc, params.accountId);
17298
17806
  task.logger?.info("==> 代理信息获取成功!");
17299
17807
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
17300
17808
  }
@@ -17620,6 +18128,11 @@ var __webpack_exports__ = {};
17620
18128
  this.concurrentLimit = config.concurrentLimit || 4;
17621
18129
  this.singleFileSize = config.singleFileSize || 10485760;
17622
18130
  this.http = config.http || new Http();
18131
+ this.reqOptions = {
18132
+ timeout: config.timeout ?? 60000,
18133
+ retries: config.retries ?? 3,
18134
+ retryDelay: config.retryDelay ?? 2000
18135
+ };
17623
18136
  }
17624
18137
  calculateMd5(buffer) {
17625
18138
  const MAX_SIZE = 5242880;
@@ -17676,7 +18189,7 @@ var __webpack_exports__ = {};
17676
18189
  url: filePath,
17677
18190
  method: "get",
17678
18191
  responseType: "arraybuffer"
17679
- });
18192
+ }, this.reqOptions);
17680
18193
  return Buffer.from(resp);
17681
18194
  }
17682
18195
  return external_node_fs_default().promises.readFile(filePath);
@@ -17706,7 +18219,7 @@ var __webpack_exports__ = {};
17706
18219
  headers,
17707
18220
  data: requestBody,
17708
18221
  defaultErrorMsg: "获取UploadID失败"
17709
- });
18222
+ }, this.reqOptions);
17710
18223
  if (!resp?.UploadID) throw new Error(`获取 UploadID 失败: ${resp?.errMsg || "未知错误"}`);
17711
18224
  return resp.UploadID;
17712
18225
  }
@@ -17727,7 +18240,7 @@ var __webpack_exports__ = {};
17727
18240
  headers,
17728
18241
  data: chunk,
17729
18242
  defaultErrorMsg: `分片 ${partNumber} 上传失败`
17730
- });
18243
+ }, this.reqOptions);
17731
18244
  if (resp?.errCode !== void 0 && 0 !== resp.errCode) throw new Error(`分片 ${partNumber} 上传失败: ${resp.errMsg}`);
17732
18245
  if (onProgress) onProgress(chunk.length);
17733
18246
  return resp.ETag || "";
@@ -17751,7 +18264,7 @@ var __webpack_exports__ = {};
17751
18264
  headers,
17752
18265
  data: requestBody,
17753
18266
  defaultErrorMsg: "确认分片上传失败"
17754
- });
18267
+ }, this.reqOptions);
17755
18268
  if (resp?.ListPartsResult?.Part) return resp.ListPartsResult.Part.map((p)=>({
17756
18269
  PartNumber: parseInt(p.PartNumber),
17757
18270
  ETag: p.ETag
@@ -17777,7 +18290,7 @@ var __webpack_exports__ = {};
17777
18290
  headers,
17778
18291
  data: requestBody,
17779
18292
  defaultErrorMsg: "完成上传失败"
17780
- });
18293
+ }, this.reqOptions);
17781
18294
  if (!resp?.DownloadURL) throw new Error(`完成上传失败: ${resp?.errMsg || "未知错误"}`);
17782
18295
  return resp.DownloadURL;
17783
18296
  }
@@ -18116,7 +18629,6 @@ var __webpack_exports__ = {};
18116
18629
  enverionment: confParams.enverionment || "development",
18117
18630
  postId: confParams.articleId,
18118
18631
  eip: proxyHttp.proxyInfo,
18119
- proxyIp: confParams.proxyIp,
18120
18632
  accountId: confParams.accountId,
18121
18633
  uid: confParams.uid,
18122
18634
  publishParams: publishData,
@@ -18128,7 +18640,9 @@ var __webpack_exports__ = {};
18128
18640
  task.logger.info("[shipinhaoPublish] 开始执行视频号发布 - Mock API 方式");
18129
18641
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
18130
18642
  if (!params.extraParam.fingerPrintDeviceId || !params.extraParam.aId) return (0, share_namespaceObject.response)(400, "fingerPrintDeviceId和aId 不能为空", "");
18643
+ let currentStep = "初始化";
18131
18644
  try {
18645
+ currentStep = "解析认证信息";
18132
18646
  const cookieString = params.cookies.map((c)=>`${c.name}=${c.value}`).join("; ");
18133
18647
  const fingerPrintDeviceId = params.extraParam.fingerPrintDeviceId;
18134
18648
  const aId = params.extraParam.aId;
@@ -18141,7 +18655,6 @@ var __webpack_exports__ = {};
18141
18655
  },
18142
18656
  task.logger,
18143
18657
  params.proxyLoc,
18144
- params.localIP,
18145
18658
  params.accountId,
18146
18659
  "shipinhao"
18147
18660
  ];
@@ -18149,8 +18662,10 @@ var __webpack_exports__ = {};
18149
18662
  headers
18150
18663
  });
18151
18664
  const proxyHttp = new Http(...args);
18665
+ currentStep = "验证发布参数";
18152
18666
  if (!params.banners || 0 === params.banners.length) return (0, share_namespaceObject.response)(400, "至少需要一张图片", "");
18153
18667
  const images = params.banners.slice(0, 18).filter((img)=>"string" == typeof img);
18668
+ currentStep = "获取用户信息";
18154
18669
  task.logger.info("[shipinhaoPublish] 获取用户信息...");
18155
18670
  console.log("cookieString", cookieString);
18156
18671
  const userInfo = await mock_getUserInfo(cookieString, http);
@@ -18161,6 +18676,7 @@ var __webpack_exports__ = {};
18161
18676
  }
18162
18677
  const finderUsername = userInfo.data.finderUser.finderUsername;
18163
18678
  console.log(finderUsername);
18679
+ currentStep = "获取上传认证密钥";
18164
18680
  task.logger.info("[shipinhaoPublish] 获取上传认证密钥...");
18165
18681
  const authKeyResponse = await getUploadAuthKey(cookieString, finderUsername, http);
18166
18682
  if (0 !== authKeyResponse.errCode || !authKeyResponse.data?.authKey) return (0, share_namespaceObject.response)(authKeyResponse.errCode || 500, `获取上传认证参数失败: ${authKeyResponse.errMsg}`, "");
@@ -18168,10 +18684,12 @@ var __webpack_exports__ = {};
18168
18684
  const uin = authKeyResponse.data.uin;
18169
18685
  if (!uin) return (0, share_namespaceObject.response)(500, "获取用户 uin 失败", "");
18170
18686
  const taskId = String(generateUUID());
18687
+ currentStep = "上传图片";
18171
18688
  task.logger.info(`[shipinhaoPublish] 开始上传 ${images.length} 张图片...`);
18172
18689
  const uploadedImages = [];
18173
18690
  for(let i = 0; i < images.length; i++){
18174
- task.logger.info(`[shipinhaoPublish] 上传图片 ${i + 1}/${images.length}...`);
18691
+ currentStep = `上传图片 ${i + 1}/${images.length}`;
18692
+ task.logger.info(`[shipinhaoPublish] ${currentStep}...`);
18175
18693
  const uploadResult = await uploadImageComplete(images[i], taskId, finderUsername, uin, authKey, http);
18176
18694
  console.log(JSON.stringify(uploadResult));
18177
18695
  if (!uploadResult.DownloadURL) return (0, share_namespaceObject.response)(500, `图片上传失败: ${uploadResult.errMsg}`, "");
@@ -18188,6 +18706,7 @@ var __webpack_exports__ = {};
18188
18706
  urlCdnTaskId: ""
18189
18707
  });
18190
18708
  }
18709
+ currentStep = "发布图文内容";
18191
18710
  task.logger.info("[shipinhaoPublish] 正在发布...");
18192
18711
  const topicNames = params.topic || void 0;
18193
18712
  const addressInfo = params.address ? {
@@ -18206,7 +18725,6 @@ var __webpack_exports__ = {};
18206
18725
  articleId: params.articleId,
18207
18726
  postId: params.articleId,
18208
18727
  eip: proxyHttp.proxyInfo,
18209
- proxyIp: params.localIP,
18210
18728
  accountId: params.accountId,
18211
18729
  uid: params.uid
18212
18730
  }, {
@@ -18274,9 +18792,15 @@ var __webpack_exports__ = {};
18274
18792
  });
18275
18793
  return (0, share_namespaceObject.response)(resultCode || 500, errorMessage, "");
18276
18794
  } catch (error) {
18277
- const errorMsg = error instanceof Error ? error.message : "发布失败";
18278
- task.logger.error(`[shipinhaoPublish] 发布异常: ${errorMsg}`);
18279
- return (0, share_namespaceObject.response)(500, errorMsg, "");
18795
+ const handledError = Http.handleApiError(error);
18796
+ const errorMsg = handledError.message || "发布失败,请稍后重试";
18797
+ const errorCode = handledError.code || 500;
18798
+ task.logger.error(`[shipinhaoPublish] 发布流程异常: ${errorMsg}`, stringifyError(error), handledError.extra);
18799
+ await updateTaskState?.({
18800
+ state: share_namespaceObject.TaskState.FAILED,
18801
+ error: errorMsg
18802
+ });
18803
+ return (0, share_namespaceObject.response)(errorCode, errorMsg, "");
18280
18804
  }
18281
18805
  };
18282
18806
  const shipinhaoPublish_rpa_rpaAction = async (task, params)=>{
@@ -18587,16 +19111,11 @@ var __webpack_exports__ = {};
18587
19111
  return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
18588
19112
  }));
18589
19113
  let proxyUrl;
18590
- if (params.localIP) {
18591
- const args = [
18592
- params.localIP,
18593
- params.proxyLoc,
18594
- params.accountId
18595
- ];
18596
- task.logger?.info(`==> 开始获取代理信息:${args}`);
19114
+ if (params.proxyLoc) {
19115
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
18597
19116
  const ProxyAgentResult = await ProxyAgent({
18598
19117
  logger: task.logger
18599
- }, ...args);
19118
+ }, params.proxyLoc, params.accountId);
18600
19119
  task.logger?.info("==> 代理信息获取成功!");
18601
19120
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
18602
19121
  }
@@ -19246,16 +19765,11 @@ var __webpack_exports__ = {};
19246
19765
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
19247
19766
  let executionState;
19248
19767
  let proxyUrl;
19249
- if (params.localIP) {
19250
- const args = [
19251
- params.localIP,
19252
- params.proxyLoc,
19253
- params.accountId
19254
- ];
19255
- task.logger?.info(`==> 开始获取代理信息:${args}`);
19768
+ if (params.proxyLoc) {
19769
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
19256
19770
  const ProxyAgentResult = await ProxyAgent({
19257
19771
  logger: task.logger
19258
- }, ...args);
19772
+ }, params.proxyLoc, params.accountId);
19259
19773
  task.logger?.info("==> 代理信息获取成功!");
19260
19774
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
19261
19775
  }
@@ -19506,7 +20020,6 @@ var __webpack_exports__ = {};
19506
20020
  },
19507
20021
  task.logger,
19508
20022
  params.proxyLoc,
19509
- params.localIP,
19510
20023
  params.accountId,
19511
20024
  "toutiao"
19512
20025
  ];
@@ -19704,7 +20217,6 @@ var __webpack_exports__ = {};
19704
20217
  enverionment: task.enverionment || "development",
19705
20218
  postId: params.articleId,
19706
20219
  eip: proxyHttp.proxyInfo,
19707
- proxyIp: params.localIP,
19708
20220
  accountId: params.accountId,
19709
20221
  uid: params.uid,
19710
20222
  platform: "toutiao",
@@ -20339,16 +20851,11 @@ var __webpack_exports__ = {};
20339
20851
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
20340
20852
  let executionState;
20341
20853
  let proxyUrl;
20342
- if (params.localIP) {
20343
- const args = [
20344
- params.localIP,
20345
- params.proxyLoc,
20346
- params.accountId
20347
- ];
20348
- task.logger?.info(`==> 开始获取代理信息:${args}`);
20854
+ if (params.proxyLoc) {
20855
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
20349
20856
  const ProxyAgentResult = await ProxyAgent({
20350
20857
  logger: task.logger
20351
- }, ...args);
20858
+ }, params.proxyLoc, params.accountId);
20352
20859
  task.logger?.info("==> 代理信息获取成功!");
20353
20860
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
20354
20861
  }
@@ -20840,7 +21347,6 @@ var __webpack_exports__ = {};
20840
21347
  },
20841
21348
  task.logger,
20842
21349
  params.proxyLoc,
20843
- params.localIP,
20844
21350
  params.accountId,
20845
21351
  "weixin"
20846
21352
  ];
@@ -21619,7 +22125,6 @@ var __webpack_exports__ = {};
21619
22125
  enverionment: task.enverionment || "development",
21620
22126
  postId: params.articleId,
21621
22127
  eip: proxyHttp.proxyInfo,
21622
- proxyIp: params.localIP,
21623
22128
  accountId: params.accountId,
21624
22129
  uid: params.uid,
21625
22130
  platform: "weixin",
@@ -22424,16 +22929,11 @@ var __webpack_exports__ = {};
22424
22929
  const reporter = task.reportService?.reportLoginStatus ?? (()=>Promise.resolve());
22425
22930
  let executionState;
22426
22931
  let proxyUrl;
22427
- if (params.localIP) {
22428
- const args = [
22429
- params.localIP,
22430
- params.proxyLoc,
22431
- params.accountId
22432
- ];
22433
- task.logger?.info(`==> 开始获取代理信息:${args}`);
22932
+ if (params.proxyLoc) {
22933
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
22434
22934
  const ProxyAgentResult = await ProxyAgent({
22435
22935
  logger: task.logger
22436
- }, ...args);
22936
+ }, params.proxyLoc, params.accountId);
22437
22937
  task.logger?.info("==> 代理信息获取成功!");
22438
22938
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
22439
22939
  }
@@ -22750,7 +23250,6 @@ var __webpack_exports__ = {};
22750
23250
  },
22751
23251
  task.logger,
22752
23252
  params.proxyLoc,
22753
- params.localIP,
22754
23253
  params.accountId,
22755
23254
  "xiaohongshu"
22756
23255
  ];
@@ -22791,8 +23290,8 @@ var __webpack_exports__ = {};
22791
23290
  params: fetchCoverParams
22792
23291
  }, {
22793
23292
  retries: 3,
22794
- retryDelay: 20,
22795
- timeout: 3000
23293
+ retryDelay: 500,
23294
+ timeout: 30000
22796
23295
  });
22797
23296
  for (const item of batchCoverIdInfo?.data?.uploadTempPermits ?? [])for (const fileId of item.fileIds)uploadInfos.push({
22798
23297
  bucket: item.bucket || "",
@@ -22811,8 +23310,8 @@ var __webpack_exports__ = {};
22811
23310
  params: fetchCoverParams
22812
23311
  }, {
22813
23312
  retries: 3,
22814
- retryDelay: 20,
22815
- timeout: 3000
23313
+ retryDelay: 500,
23314
+ timeout: 30000
22816
23315
  });
22817
23316
  for (const item of coverIdInfo?.data?.uploadTempPermits ?? [])for (const fileId of item.fileIds)uploadInfos.push({
22818
23317
  bucket: item.bucket || "",
@@ -22873,7 +23372,9 @@ var __webpack_exports__ = {};
22873
23372
  headers: {
22874
23373
  "x-cos-security-token": ossToken
22875
23374
  },
22876
- defaultErrorMsg: "图片上传异常,请稍后重试发布。"
23375
+ defaultErrorMsg: "图片上传异常,请稍后重试。"
23376
+ }, {
23377
+ timeout: 60000
22877
23378
  });
22878
23379
  return {
22879
23380
  ossFileId,
@@ -22883,6 +23384,8 @@ var __webpack_exports__ = {};
22883
23384
  originSize
22884
23385
  };
22885
23386
  } catch (error) {
23387
+ const e = Http.handleApiError(error);
23388
+ task.logger.warn(`[xhs upload] 第${attempt + 1}次失败 index=${index} bucket=${ossBucketIndex} domain=${ossDomain} fileId=${ossFileId} code=${e.code} msg=${e.message} data=${stringifyError(e.data)}`);
22886
23389
  attempt++;
22887
23390
  }
22888
23391
  }
@@ -23116,7 +23619,6 @@ var __webpack_exports__ = {};
23116
23619
  enverionment: task.enverionment || "development",
23117
23620
  postId: params.articleId,
23118
23621
  eip: proxyHttp.proxyInfo,
23119
- proxyIp: params.localIP,
23120
23622
  accountId: params.accountId,
23121
23623
  uid: params.uid,
23122
23624
  platform: "xiaohongshu",
@@ -23378,16 +23880,11 @@ var __webpack_exports__ = {};
23378
23880
  return (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
23379
23881
  }));
23380
23882
  let proxyUrl;
23381
- if (params.localIP) {
23382
- const args = [
23383
- params.localIP,
23384
- params.proxyLoc,
23385
- params.accountId
23386
- ];
23387
- task.logger?.info(`==> 开始获取代理信息:${args}`);
23883
+ if (params.proxyLoc) {
23884
+ task.logger?.info(`==> 开始获取代理信息:${params}`);
23388
23885
  const ProxyAgentResult = await ProxyAgent({
23389
23886
  logger: task.logger
23390
- }, ...args);
23887
+ }, params.proxyLoc, params.accountId);
23391
23888
  task.logger?.info("==> 代理信息获取成功!");
23392
23889
  proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
23393
23890
  }
@@ -23816,7 +24313,6 @@ var __webpack_exports__ = {};
23816
24313
  },
23817
24314
  task.logger,
23818
24315
  params.proxyLoc,
23819
- params.localIP,
23820
24316
  params.accountId,
23821
24317
  "xiaohongshu-rpa"
23822
24318
  ];
@@ -23862,8 +24358,8 @@ var __webpack_exports__ = {};
23862
24358
  params: fetchCoverParams
23863
24359
  }, {
23864
24360
  retries: 3,
23865
- retryDelay: 20,
23866
- timeout: 3000
24361
+ retryDelay: 500,
24362
+ timeout: 8000
23867
24363
  });
23868
24364
  for (const item of batchCoverIdInfo?.data?.uploadTempPermits ?? [])for (const fileId of item?.fileIds ?? [])uploadInfos.push({
23869
24365
  bucket: item.bucket || "",
@@ -23882,8 +24378,8 @@ var __webpack_exports__ = {};
23882
24378
  params: fetchCoverParams
23883
24379
  }, {
23884
24380
  retries: 3,
23885
- retryDelay: 20,
23886
- timeout: 3000
24381
+ retryDelay: 500,
24382
+ timeout: 8000
23887
24383
  });
23888
24384
  for (const item of coverIdInfo?.data?.uploadTempPermits ?? [])for (const fileId of item?.fileIds ?? [])uploadInfos.push({
23889
24385
  bucket: item.bucket || "",
@@ -23928,6 +24424,8 @@ var __webpack_exports__ = {};
23928
24424
  "x-cos-security-token": ossToken
23929
24425
  },
23930
24426
  defaultErrorMsg: "图片上传异常,请稍后重试发布。"
24427
+ }, {
24428
+ timeout: 60000
23931
24429
  });
23932
24430
  return {
23933
24431
  ossFileId,
@@ -24237,7 +24735,6 @@ var __webpack_exports__ = {};
24237
24735
  },
24238
24736
  _task.logger,
24239
24737
  params.proxyLoc,
24240
- params.localIP,
24241
24738
  params.accountId
24242
24739
  ];
24243
24740
  const http = new Http(...args);
@@ -24323,7 +24820,6 @@ var __webpack_exports__ = {};
24323
24820
  },
24324
24821
  _task.logger,
24325
24822
  params.proxyLoc,
24326
- params.localIP,
24327
24823
  params.accountId
24328
24824
  ];
24329
24825
  const http = new Http(...args);
@@ -24362,7 +24858,6 @@ var __webpack_exports__ = {};
24362
24858
  },
24363
24859
  _task.logger,
24364
24860
  params.proxyLoc,
24365
- params.localIP,
24366
24861
  params.accountId
24367
24862
  ];
24368
24863
  const http = new Http(...args);
@@ -24415,7 +24910,6 @@ var __webpack_exports__ = {};
24415
24910
  },
24416
24911
  _task.logger,
24417
24912
  params.proxyLoc,
24418
- params.localIP,
24419
24913
  params.accountId
24420
24914
  ];
24421
24915
  const http = new Http(...args);
@@ -24472,7 +24966,6 @@ var __webpack_exports__ = {};
24472
24966
  },
24473
24967
  _task.logger,
24474
24968
  params.proxyLoc,
24475
- params.localIP,
24476
24969
  params.accountId
24477
24970
  ];
24478
24971
  const http = new Http(...args);
@@ -24545,7 +25038,6 @@ var __webpack_exports__ = {};
24545
25038
  },
24546
25039
  _task.logger,
24547
25040
  params.proxyLoc,
24548
- params.localIP,
24549
25041
  params.accountId
24550
25042
  ];
24551
25043
  const http = new Http(...args);
@@ -24649,7 +25141,6 @@ var __webpack_exports__ = {};
24649
25141
  },
24650
25142
  _task.logger,
24651
25143
  params.proxyLoc,
24652
- params.localIP,
24653
25144
  params.accountId
24654
25145
  ];
24655
25146
  const http = new Http(...args);
@@ -24782,6 +25273,24 @@ var __webpack_exports__ = {};
24782
25273
  likeNumYesterday: schemas_number().nullable(),
24783
25274
  commentNumYesterday: schemas_number().nullable()
24784
25275
  });
25276
+ const douyinConfigDataSchema = schemas_object({
25277
+ fansNum: schemas_number(),
25278
+ favedNum: schemas_number(),
25279
+ fansNumLastWeek: schemas_number(),
25280
+ watchNumLastWeek: schemas_number(),
25281
+ likeNumLastWeek: schemas_number(),
25282
+ commentNumLastWeek: schemas_number(),
25283
+ shareNumLastWeek: schemas_number(),
25284
+ visitNumLastWeek: schemas_number()
25285
+ });
25286
+ const shipinhaoConfigDataSchema = schemas_object({
25287
+ fansNum: schemas_number(),
25288
+ feedsCount: schemas_number(),
25289
+ fansNumYesterday: schemas_number().nullable(),
25290
+ playNumYesterday: schemas_number().nullable(),
25291
+ likeNumYesterday: schemas_number().nullable(),
25292
+ commentNumYesterday: schemas_number().nullable()
25293
+ });
24785
25294
  const BetaFlag = "HuiwenCanary";
24786
25295
  class Action {
24787
25296
  constructor(task){
@@ -25070,4 +25579,5 @@ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_targe
25070
25579
  value: true
25071
25580
  });
25072
25581
 
25073
- //# sourceMappingURL=index.js.map
25582
+ //# sourceMappingURL=index.js.map
25583
+ //# debugId=6a453c21-67bd-5554-819f-0c24705e7164