@iflyrpa/actions 4.0.4 → 4.0.5

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,5 +1,3 @@
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]="e1cb75dd-cee5-50ef-9ae8-80ab2cccd402")}catch(e){}}();
3
1
  var __webpack_modules__ = {
4
2
  "./src/utils/XhsXsCommonEnc.js": function(module) {
5
3
  var encrypt_lookup = [
@@ -4396,14 +4394,12 @@ var __webpack_exports__ = {};
4396
4394
  bjhConfigDataSchema: ()=>bjhConfigDataSchema,
4397
4395
  Action: ()=>Action,
4398
4396
  ProxyAgent: ()=>ProxyAgent,
4399
- douyinConfigDataSchema: ()=>douyinConfigDataSchema,
4400
- shipinhaoConfigDataSchema: ()=>shipinhaoConfigDataSchema,
4401
4397
  version: ()=>package_namespaceObject.i8
4402
4398
  });
4403
4399
  const package_json_namespaceObject = require("@iflyrpa/share/package.json");
4404
4400
  var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
4405
4401
  var package_namespaceObject = {
4406
- i8: "4.0.4"
4402
+ i8: "4.0.5"
4407
4403
  };
4408
4404
  const share_namespaceObject = require("@iflyrpa/share");
4409
4405
  const external_node_fs_namespaceObject = require("node:fs");
@@ -4653,12 +4649,11 @@ var __webpack_exports__ = {};
4653
4649
  this.logger?.debug(`未处理的网络错误代码: ${error.code} ${error.message}`, {
4654
4650
  errorString: stringifyError(error)
4655
4651
  });
4656
- _message = `网络错误: ${error.message}`;
4652
+ _message = `未知网络错误: ${error.message}`;
4657
4653
  break;
4658
4654
  }
4659
4655
  }
4660
- if (error.code && !error.response?.data) errorResponse.message = _message || errorResponse.message;
4661
- else errorResponse.message = errorResponse.message ? errorResponse.message : _message;
4656
+ errorResponse.message = errorResponse.message ? errorResponse.message : _message;
4662
4657
  if ("canceled" === errorResponse.message) {
4663
4658
  const message = errorResponse.extra?.isProxyRequest ? "代理连接建立超时,请更换区域或稍后重试!" : "网络请求超时,请稍后重试!";
4664
4659
  errorResponse.message = message;
@@ -13447,450 +13442,429 @@ var __webpack_exports__ = {};
13447
13442
  }
13448
13443
  return randomString;
13449
13444
  }
13450
- function safeSerialize(obj) {
13451
- if (!obj || "object" != typeof obj) return obj;
13452
- try {
13453
- return JSON.parse(JSON.stringify(obj));
13454
- } catch (error) {
13455
- return {};
13456
- }
13457
- }
13458
13445
  const mock_mockAction = async (task, params)=>{
13459
13446
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
13460
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 参数缺失或不完整", "");
13461
- let currentStep = "初始化";
13462
- try {
13463
- currentStep = "验证账号信息";
13464
- 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";
13465
- const sessionidCookie = params.cookies.find((it)=>"msToken" === it.name)?.value;
13466
- if (!sessionidCookie) return {
13467
- code: 414,
13468
- message: "账号数据异常,请重新绑定账号后重试。",
13469
- data: ""
13470
- };
13471
- currentStep = "准备请求参数";
13472
- const headers = {
13473
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
13474
- origin: "https://creator.douyin.com",
13475
- referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13476
- Accept: "application/json, text/plain, */*",
13477
- "Accept-Encoding": "gzip, deflate, br, zstd",
13478
- "Content-Type": "application/json",
13479
- pragma: "no-cache",
13480
- "cache-control": "no-cache",
13481
- "sec-ch-ua-platform": params.extraParam?.browserInfo?.["sec-ch-ua-platform"] || "",
13482
- "sec-ch-ua": params.extraParam?.browserInfo?.["sec-ch-ua"] || "",
13483
- "bd-ticket-guard-web-version": "2",
13484
- "sec-ch-ua-mobile": "?0",
13485
- "user-agent": userAgent,
13486
- "sec-fetch-site": "same-origin",
13487
- "sec-fetch-mode": "cors",
13488
- "sec-fetch-dest": "empty",
13489
- "accept-language": "zh-CN,zh;q=0.9",
13490
- priority: "u=1, i"
13491
- };
13492
- const publishParams = {
13493
- read_aid: "2906",
13494
- aid: "1128",
13495
- cookie_enabled: "true",
13496
- screen_width: params.extraParam?.browserInfo.screen_width || "1920",
13497
- screen_height: params.extraParam?.browserInfo.screen_height || "1080",
13498
- browser_language: params.extraParam?.browserInfo.browser_language || "zh-CN",
13499
- browser_platform: params.extraParam?.browserInfo.browser_platform || "Win32",
13500
- browser_name: params.extraParam?.browserInfo.browser_name || "Mozilla",
13501
- browser_version: userAgent,
13502
- browser_online: "true",
13503
- timezone_name: "Asia/Shanghai",
13504
- support_h265: "1",
13505
- msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
13506
- a_bogus: ""
13507
- };
13508
- task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
13509
- const publishData = {
13510
- item: {
13511
- common: {
13512
- text: params.content,
13513
- text_extra: params.textExtra,
13514
- activity: "[]",
13515
- challenges: params.challengeIds || "[]",
13516
- hashtag_source: "",
13517
- mentions: "[]",
13518
- music_id: params.musicId || "",
13519
- music_end_time: 1000 * (params.musicDuration || 0),
13520
- hot_sentence: params.hotSentence || "",
13521
- visibility_type: Number(params.visibleRange) || 0,
13522
- download: params.allowSave ? 1 : 0,
13523
- timing: params.isImmediatelyPublish ? -1 : params.scheduledPublish,
13524
- media_type: Number(params.publishType) || 2,
13525
- images: [],
13526
- creation_id: ""
13527
- },
13528
- cover: {
13529
- poster: ""
13530
- },
13531
- mix: params.mix ? {
13532
- mix_id: params.mix.mix_id,
13533
- mix_order: params.mix.mix_order || 0
13534
- } : {},
13535
- anchor: {},
13536
- declare: {
13537
- user_declare_info: "{}"
13538
- }
13539
- }
13540
- };
13541
- const args = [
13542
- {
13543
- headers
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: ""
13544
13510
  },
13545
- task.logger,
13546
- "",
13547
- "",
13548
- params.accountId,
13549
- "douyin"
13550
- ];
13551
- const http = new Http({
13552
- headers
13553
- });
13554
- const proxyHttp = new Http(...args);
13555
- const uploadedImgList = params.uploadedImgList ? JSON.parse(params.uploadedImgList) : [];
13556
- if (uploadedImgList.length > 0) publishData.item.common.images = uploadedImgList;
13557
- else {
13558
- const tmpCachePath = task.getTmpPath();
13559
- const uploader = new DouyinImageUploader(proxyHttp, headers, publishParams, tmpCachePath);
13560
- if (params.coverImage) {
13561
- const cover = await uploader.uploadCover(params.coverImage);
13562
- if (cover) {
13563
- publishData.item.common.images.push({
13564
- uri: cover.uri,
13565
- width: cover.width,
13566
- height: cover.height
13567
- });
13568
- publishData.item.cover = {
13569
- poster: cover.uri
13570
- };
13571
- }
13572
- }
13573
- if (params.banners && params.banners.length > 0) {
13574
- const banners = params.banners.filter((i)=>i !== params.coverImage);
13575
- const uploadResults = await uploader.uploadImages(banners);
13576
- publishData.item.common.images = publishData.item.common.images.concat(uploadResults.map((result)=>({
13577
- uri: result.uri,
13578
- width: result.width,
13579
- height: result.height
13580
- })));
13581
- }
13582
- }
13583
- publishData.item.common.creation_id = generateRandomString(8) + Date.now();
13584
- let decision = null;
13585
- proxyHttp.addResponseInterceptor((response)=>{
13586
- task.logger.info(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
13587
- task.logger.info(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
13588
- decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
13589
- if (needsVerification(decision)) {
13590
- task.logger.info(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
13591
- return;
13592
- }
13593
- if (!response || !response.data) return;
13594
- const responseData = response.data;
13595
- if (response && responseData?.status_code && 0 !== responseData.status_code) {
13596
- const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
13597
- if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
13598
- return {
13599
- code: errorCode,
13600
- message: responseData.status_msg || "文章发布异常,请稍后重试。",
13601
- data: responseData
13602
- };
13603
- }
13604
- });
13605
- task._timerRecord.PrePublish = Date.now();
13606
- if (MockPublish) {
13607
- const data = "123456789";
13608
- const message = `图文模拟发布成功 ${http.proxyInfo}`;
13609
- await updateTaskState?.({
13610
- state: share_namespaceObject.TaskState.SUCCESS,
13611
- result: {
13612
- response: data
13613
- }
13614
- });
13615
- return (0, share_namespaceObject.response)(0, message, data);
13616
- }
13617
- let webProtectData;
13618
- try {
13619
- webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
13620
- if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
13621
- task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
13622
- return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
13623
- }
13624
- } catch (error) {
13625
- task.logger.error(`解析 webProtectData 失败: ${error}`);
13626
- return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
13627
- }
13628
- let ticket = webProtectData.ticket;
13629
- let ts_sign = webProtectData.ts_sign;
13630
- const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
13631
- if (serverDataCookie) try {
13632
- const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
13633
- if (decoded.ticket && decoded.ts_sign) {
13634
- if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
13635
- ticket = decoded.ticket;
13636
- ts_sign = decoded.ts_sign;
13637
- }
13638
- } catch (error) {
13639
- task.logger.info(`[douyinPublish] 解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
13640
- }
13641
- let ec_privateKey;
13642
- try {
13643
- ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
13644
- if (!ec_privateKey) {
13645
- task.logger.error("[douyinPublish] ec_privateKey 为空");
13646
- return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
13647
- }
13648
- } catch (error) {
13649
- task.logger.error(`[douyinPublish] 解析 ec_privateKey 失败: ${error}`);
13650
- return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
13651
- }
13652
- let certificate;
13653
- try {
13654
- certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
13655
- if (!certificate) {
13656
- task.logger.error("[douyinPublish] certificate 为空");
13657
- return (0, share_namespaceObject.response)(414, "安全参数 certificate 缺失,请重新获取后重试", "");
13658
- }
13659
- } catch (error) {
13660
- task.logger.error(`[douyinPublish] 解析 certificate 失败: ${error}`);
13661
- return (0, share_namespaceObject.response)(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
13662
- }
13663
- const ree_public_key = webProtectData.client_cert.replace("pub.", "");
13664
- let bdTicketGuardClientData;
13665
- try {
13666
- bdTicketGuardClientData = getBdV2({
13667
- ticket,
13668
- ts_sign: ts_sign,
13669
- ec_privateKey: ec_privateKey,
13670
- certificate: certificate,
13671
- bd_ticket_guard_ree_public_key: ree_public_key
13672
- });
13673
- if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
13674
- task.logger.error(`[douyinPublish] bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
13675
- return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
13676
- }
13677
- } catch (error) {
13678
- task.logger.error(`[douyinPublish] 生成 bdTicketGuardClientData 失败: ${error}`);
13679
- return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
13680
- }
13681
- task.logger.info("[douyinPublish] bdTicketGuardClientData 生成成功");
13682
- const publishQuery = {
13683
- ...publishParams,
13684
- a_bogus: ""
13685
- };
13686
- const queryString = new URLSearchParams(publishQuery).toString();
13687
- let aBogus;
13688
- try {
13689
- aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
13690
- if (!aBogus || aBogus.length < 10) {
13691
- task.logger.error(`[douyinPublish] a_bogus 生成异常,长度过短: ${aBogus}`);
13692
- return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成失败,请重试", "");
13693
- }
13694
- } catch (error) {
13695
- task.logger.error(`[douyinPublish] 生成 a_bogus 失败: ${error}`);
13696
- return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成异常,请重试", "");
13697
- }
13698
- publishQuery.a_bogus = aBogus;
13699
- const publishQueryParams = new URLSearchParams(publishQuery).toString();
13700
- let csrfToken;
13701
- try {
13702
- csrfToken = mock_generateCsrfTokenAdvanced({
13703
- cookies: params.cookies,
13704
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
13705
- method: "POST",
13706
- userAgent
13707
- });
13708
- if (!csrfToken || csrfToken.length < 10) {
13709
- task.logger.error(`[douyinPublish] csrfToken 生成异常,长度过短: ${csrfToken}`);
13710
- return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成失败,请重试", "");
13511
+ cover: {
13512
+ poster: ""
13513
+ },
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: "{}"
13711
13521
  }
13712
- task.logger.info(`[douyinPublish] csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
13713
- } catch (error) {
13714
- task.logger.error(`[douyinPublish] 生成 csrfToken 失败: ${error}`);
13715
- return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成异常,请重试", "");
13716
13522
  }
13717
- let sessionDtrait;
13718
- try {
13719
- sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
13720
- task.logger.info(`[douyinPublish] sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
13721
- } catch (error) {
13722
- task.logger.error(`[douyinPublish] 生成 sessionDtrait 失败: ${error}`);
13723
- return (0, share_namespaceObject.response)(414, "安全参数 sessionDtrait 生成异常,请重试", "");
13724
- }
13725
- task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
13726
- ...headers,
13727
- Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13728
- "Content-Type": "application/json",
13729
- Accept: "application/json, text/plain, */*",
13730
- "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13731
- "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13732
- "bd-ticket-guard-version": "2",
13733
- "bd-ticket-guard-web-sign-type": "1",
13734
- "bd-ticket-guard-web-version": "2",
13735
- "x-secsdk-csrf-token": csrfToken,
13736
- "x-tt-session-dtrait": sessionDtrait || ""
13737
- })}`);
13738
- task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
13739
- let publishResult;
13740
- try {
13741
- publishResult = await proxyHttp.api({
13742
- method: "post",
13743
- url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
13744
- data: publishData,
13745
- defaultErrorMsg: "发布异常,请稍后重试。",
13746
- headers: {
13747
- ...headers,
13748
- Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
13749
- "Content-Type": "application/json",
13750
- Accept: "application/json, text/plain, */*",
13751
- "bd-ticket-guard-client-data": bdTicketGuardClientData["headers_bd_ticket_guard_client_data"],
13752
- "bd-ticket-guard-ree-public-key": bdTicketGuardClientData["headers_bd_ticket_guard_ree_public_key"],
13753
- "bd-ticket-guard-version": "2",
13754
- "bd-ticket-guard-web-sign-type": "1",
13755
- "bd-ticket-guard-web-version": "2",
13756
- "x-secsdk-csrf-token": csrfToken,
13757
- "x-tt-session-dtrait": sessionDtrait || ""
13758
- }
13759
- }, {
13760
- timeout: 60000,
13761
- retries: 3,
13762
- retryDelay: 2000
13763
- });
13764
- } catch (error) {
13765
- const handledError = Http.handleApiError(error);
13766
- const isProxyOrNetworkError = [
13767
- 599,
13768
- 500,
13769
- 502,
13770
- 503,
13771
- 504
13772
- ].includes(handledError.code);
13773
- if (isProxyOrNetworkError) {
13774
- const isProxyRequest = handledError.extra?.isProxyRequest === true;
13775
- const errorType = 599 === handledError.code || isProxyRequest ? "代理错误" : "网络错误";
13776
- const message = `图文发布失败,${errorType}:${handledError.message}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13777
- task.logger.error(`[douyinPublish] ${errorType},直接返回: ${message}`, stringifyError(handledError));
13778
- await updateTaskState?.({
13779
- state: share_namespaceObject.TaskState.FAILED,
13780
- error: message
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
13781
13550
  });
13782
- return {
13783
- code: 414,
13784
- data: "",
13785
- message
13551
+ publishData.item.cover = {
13552
+ poster: cover.uri
13786
13553
  };
13787
13554
  }
13788
- throw error;
13789
13555
  }
13790
- task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
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
+ })));
13564
+ }
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"]);
13791
13572
  if (needsVerification(decision)) {
13792
- const details = [
13793
- publishResult.status_msg,
13794
- decision?.verify_title,
13795
- decision?.verify_desc
13796
- ].filter(Boolean).join(" ");
13797
- const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13798
- const safeDecision = safeSerialize(decision) ?? {};
13799
- const mockData = {
13800
- state: share_namespaceObject.TaskState.FAILED,
13801
- error: message,
13802
- result: {
13803
- ...safeDecision,
13804
- data: decision,
13805
- uploadedImgList: JSON.stringify(publishData.item.common.images)
13806
- }
13807
- };
13808
- await updateTaskState?.(mockData);
13809
- return {
13810
- code: 0,
13811
- data: mockData,
13812
- message: "操作成功"
13813
- };
13573
+ task.logger.info(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
13574
+ return;
13814
13575
  }
13815
- reportLogger({
13816
- token: params.huiwenToken || "",
13817
- enverionment: task.enverionment || "development",
13818
- postId: params.articleId,
13819
- eip: proxyHttp.proxyInfo,
13820
- proxyIp: params.localIP,
13821
- accountId: params.accountId,
13822
- uid: params.uid,
13823
- platform: "douyin",
13824
- publishParams: publishData
13825
- });
13826
- task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
13827
- const isSuccess = 0 === publishResult.status_code;
13828
- const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
13829
- const data = isSuccess ? publishResult.item_id || "" : "";
13830
- if (!isSuccess) {
13831
- const safeDecision = safeSerialize(decision) ?? {};
13832
- await updateTaskState?.({
13833
- state: share_namespaceObject.TaskState.FAILED,
13834
- error: message,
13835
- result: {
13836
- ...safeDecision,
13837
- data: safeDecision,
13838
- uploadedImgList: JSON.stringify(publishData.item.common.images)
13839
- }
13840
- });
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)}`);
13841
13581
  return {
13842
- code: 414,
13843
- data: safeDecision,
13844
- message
13582
+ code: errorCode,
13583
+ message: responseData.status_msg || "文章发布异常,请稍后重试。",
13584
+ data: responseData
13845
13585
  };
13846
13586
  }
13587
+ });
13588
+ task._timerRecord.PrePublish = Date.now();
13589
+ if (MockPublish) {
13590
+ const data = "123456789";
13591
+ const message = `图文模拟发布成功 ${http.proxyInfo}`;
13847
13592
  await updateTaskState?.({
13848
13593
  state: share_namespaceObject.TaskState.SUCCESS,
13849
13594
  result: {
13850
13595
  response: data
13851
13596
  }
13852
13597
  });
13853
- return (0, share_namespaceObject.response)(isSuccess ? 0 : 414, message, data);
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
+ }
13854
13607
  } catch (error) {
13855
- const handledError = Http.handleApiError(error);
13856
- const errorMsg = handledError.message || "发布失败";
13857
- const errorCode = handledError.code || 500;
13858
- task.logger.error(`[douyinPublish] 发布流程异常 (步骤: ${currentStep}): ${errorMsg}`, stringifyError(error), handledError.extra);
13859
- await updateTaskState?.({
13860
- state: share_namespaceObject.TaskState.FAILED,
13861
- error: `${currentStep}失败: ${errorMsg}`
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
+ }
13642
+ } 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
13862
13655
  });
13863
- return (0, share_namespaceObject.response)(errorCode, errorMsg, "");
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 生成异常,请重新获取后重试", "");
13864
13663
  }
13865
- };
13866
- const douyinPublish_rpa_rpaAction = async (task, params)=>{
13867
- const commonCookies = {
13868
- path: "/",
13869
- secure: true,
13870
- domain: "douyin.com",
13871
- url: "https://creator.douyin.com",
13872
- httpOnly: true
13664
+ task.logger.info("[douyinPublish] bdTicketGuardClientData 生成成功");
13665
+ const publishQuery = {
13666
+ ...publishParams,
13667
+ a_bogus: ""
13873
13668
  };
13874
- const page = await task.createPage({
13875
- show: task.debug,
13876
- url: params.url || "https://creator.douyin.com/creator-micro/content/upload?default-tab=3",
13877
- cookies: params.cookies?.map((it)=>({
13878
- ...it,
13879
- ...commonCookies
13880
- }))
13881
- });
13882
- const tmpCachePath = task.getTmpPath();
13883
- const waitForElement = async (selector, timeout = 10000)=>{
13884
- try {
13885
- const element = page.locator(selector);
13886
- task.logger.warn(`element: ${element}`);
13887
- await element.waitFor({
13888
- state: "visible",
13889
- timeout
13890
- });
13891
- return element;
13892
- } catch {
13893
- task.logger.warn(`元素未找到: ${selector}`);
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
13847
+ };
13848
+ const page = await task.createPage({
13849
+ show: task.debug,
13850
+ url: params.url || "https://creator.douyin.com/creator-micro/content/upload?default-tab=3",
13851
+ cookies: params.cookies?.map((it)=>({
13852
+ ...it,
13853
+ ...commonCookies
13854
+ }))
13855
+ });
13856
+ const tmpCachePath = task.getTmpPath();
13857
+ const waitForElement = async (selector, timeout = 10000)=>{
13858
+ try {
13859
+ const element = page.locator(selector);
13860
+ task.logger.warn(`element: ${element}`);
13861
+ await element.waitFor({
13862
+ state: "visible",
13863
+ timeout
13864
+ });
13865
+ return element;
13866
+ } catch {
13867
+ task.logger.warn(`元素未找到: ${selector}`);
13894
13868
  return null;
13895
13869
  }
13896
13870
  };
@@ -15387,241 +15361,6 @@ var __webpack_exports__ = {};
15387
15361
  };
15388
15362
  return (0, share_namespaceObject.success)(bjhData, "百家号平台数据获取成功!");
15389
15363
  }
15390
- async function getDouyinData(_task, params) {
15391
- try {
15392
- const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15393
- if (!sessionidCookie) return types_errorResponse("抖音账号数据异常,请重新绑定账号后重试。", 414);
15394
- const csrfToken = params.cookies.find((it)=>"passport_csrf_token" === it.name)?.value || "";
15395
- const headers = {
15396
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15397
- referer: "https://creator.douyin.com/creator-micro/home",
15398
- origin: "https://creator.douyin.com",
15399
- "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",
15400
- ...csrfToken ? {
15401
- "x-secsdk-csrf-token": csrfToken
15402
- } : {}
15403
- };
15404
- const args = [
15405
- {
15406
- headers
15407
- },
15408
- _task.logger,
15409
- params.proxyLoc,
15410
- params.localIP,
15411
- params.accountId
15412
- ];
15413
- const http = new Http(...args);
15414
- const toNum = (val)=>{
15415
- if (null == val) return 0;
15416
- const n = Number.parseInt(String(val).replace(/[+,]/g, ""), 10);
15417
- return Number.isNaN(n) ? 0 : n;
15418
- };
15419
- const userProfileP = http.api({
15420
- method: "get",
15421
- url: "https://www.douyin.com/aweme/v1/web/user/profile/self/",
15422
- params: {
15423
- device_platform: "webapp",
15424
- aid: "6383",
15425
- channel: "channel_pc_web",
15426
- pc_client_type: "1",
15427
- version_code: "170400",
15428
- version_name: "17.4.0",
15429
- cookie_enabled: "true",
15430
- platform: "PC"
15431
- }
15432
- }, {
15433
- retries: 3,
15434
- retryDelay: 100,
15435
- timeout: 10000
15436
- }).catch((e)=>{
15437
- _task.logger.warn(`抖音用户信息获取失败: ${e instanceof Error ? e.message : String(e)}`);
15438
- return null;
15439
- });
15440
- const overviewP = http.api({
15441
- method: "get",
15442
- url: "https://creator.douyin.com/aweme/janus/creator/data/overview/all/",
15443
- params: {
15444
- last_days_type: 1,
15445
- aid: 2906,
15446
- app_name: "aweme_creator_platform",
15447
- device_platform: "web"
15448
- }
15449
- }, {
15450
- retries: 3,
15451
- retryDelay: 100,
15452
- timeout: 5000
15453
- }).catch((e)=>{
15454
- _task.logger.warn(`抖音近7日数据获取失败(可能未开通数据中心或被风控): ${e instanceof Error ? e.message : String(e)}`);
15455
- return null;
15456
- });
15457
- const [userProfile, overview] = await Promise.all([
15458
- userProfileP,
15459
- overviewP
15460
- ]);
15461
- let fansNum = 0;
15462
- let favedNum = 0;
15463
- let followingNum = 0;
15464
- if (userProfile?.status_code === 0 && userProfile.user) {
15465
- const user = userProfile.user;
15466
- fansNum = toNum(user.follower_count);
15467
- followingNum = toNum(user.following_count);
15468
- favedNum = toNum(user.total_favorited);
15469
- } else _task.logger.warn(`用户信息接口返回异常: status_code=${userProfile?.status_code}, msg=${userProfile?.status_msg}`);
15470
- const ov = overview?.data;
15471
- const douyinData = {
15472
- fansNum,
15473
- favedNum,
15474
- fansNumLastWeek: toNum(ov?.new_fans?.last_period_incr),
15475
- watchNumLastWeek: toNum(ov?.play?.last_period_incr),
15476
- likeNumLastWeek: toNum(ov?.digg?.last_period_incr),
15477
- commentNumLastWeek: toNum(ov?.comment?.last_period_incr),
15478
- shareNumLastWeek: toNum(ov?.share?.last_period_incr),
15479
- visitNumLastWeek: toNum(ov?.profile?.last_period_incr)
15480
- };
15481
- return (0, share_namespaceObject.success)(douyinData, "抖音平台数据获取成功!");
15482
- } catch (error) {
15483
- if (error && "object" == typeof error && "code" in error && "message" in error) {
15484
- const err = error;
15485
- _task.logger.error(`抖音账号数据获取失败: ${err.message} (${err.code})`);
15486
- return types_errorResponse(err.message, err.code);
15487
- }
15488
- const errMsg = error instanceof Error ? error.message : String(error);
15489
- _task.logger.error(`抖音账号数据获取失败: ${errMsg}`);
15490
- return types_errorResponse(errMsg || "抖音账号数据获取失败");
15491
- }
15492
- }
15493
- async function getShipinhaoData(_task, params) {
15494
- try {
15495
- const sessionidCookie = params.cookies.find((it)=>"sessionid" === it.name)?.value;
15496
- if (!sessionidCookie) return types_errorResponse("视频号账号数据异常,请重新绑定账号后重试。", 414);
15497
- const uinCookie = params.cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
15498
- const deviceIdCookie = params.cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
15499
- const aid = params.cookies.find((it)=>"_aid" === it.name)?.value || "9d3e0e9f-b842-498d-a273-4285d58df264";
15500
- const finderId = params.cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
15501
- const headers = {
15502
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
15503
- referer: "https://channels.weixin.qq.com/platform",
15504
- origin: "https://channels.weixin.qq.com",
15505
- "content-type": "application/json",
15506
- "X-WECHAT-UIN": uinCookie,
15507
- ...deviceIdCookie ? {
15508
- "finger-print-device-id": deviceIdCookie
15509
- } : {}
15510
- };
15511
- const args = [
15512
- {
15513
- headers
15514
- },
15515
- _task.logger,
15516
- params.proxyLoc,
15517
- params.localIP,
15518
- params.accountId
15519
- ];
15520
- const http = new Http(...args);
15521
- const authData = await http.api({
15522
- method: "post",
15523
- url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/auth/auth_data",
15524
- params: {
15525
- _aid: aid,
15526
- _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15527
- _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15528
- },
15529
- data: {
15530
- timestamp: Date.now().toString(),
15531
- _log_finder_uin: "",
15532
- _log_finder_id: finderId,
15533
- rawKeyBuff: "",
15534
- pluginSessionId: null,
15535
- scene: 7,
15536
- reqScene: 7
15537
- }
15538
- }, {
15539
- retries: 3,
15540
- retryDelay: 100,
15541
- timeout: 5000
15542
- });
15543
- const AUTH_ERROR_CODES = [
15544
- 300333,
15545
- 300334,
15546
- 300330,
15547
- 300331,
15548
- 300332
15549
- ];
15550
- if (authData.errCode && AUTH_ERROR_CODES.includes(authData.errCode)) {
15551
- _task.logger.warn(`视频号登录已失效:${authData.errMsg} (${authData.errCode})`);
15552
- return types_errorResponse("视频号账号信息获取失败,请检查账号状态", 414);
15553
- }
15554
- if (authData.errCode) {
15555
- _task.logger.warn(`视频号账号API错误:${authData.errMsg} (${authData.errCode})`);
15556
- return types_errorResponse(`视频号账号信息获取失败:${authData.errMsg || "未知错误"}`, 414);
15557
- }
15558
- const finderUser = authData.data?.finderUser;
15559
- const now = new Date();
15560
- const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 2);
15561
- const startTs = Math.floor(yesterday.getTime() / 1000);
15562
- const endTs = startTs + 86400;
15563
- _task.logger.info(`视频号昨日数据范围 start: ${startTs} ~ end: ${endTs}`);
15564
- let fansNumYesterday = 0;
15565
- let playNumYesterday = 0;
15566
- let likeNumYesterday = 0;
15567
- let commentNumYesterday = 0;
15568
- try {
15569
- const statsData = await http.api({
15570
- method: "post",
15571
- url: "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/statistic/new_post_total_data",
15572
- params: {
15573
- _aid: aid,
15574
- _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
15575
- _pageUrl: encodeURIComponent("https://channels.weixin.qq.com/platform")
15576
- },
15577
- data: {
15578
- startTs: startTs.toString(),
15579
- endTs: endTs.toString(),
15580
- interval: 3,
15581
- timestamp: Date.now().toString(),
15582
- _log_finder_uin: "",
15583
- _log_finder_id: finderId,
15584
- rawKeyBuff: "",
15585
- pluginSessionId: null,
15586
- scene: 7,
15587
- reqScene: 7
15588
- }
15589
- }, {
15590
- retries: 3,
15591
- retryDelay: 100,
15592
- timeout: 5000
15593
- });
15594
- if (!statsData.errCode && statsData.data?.totalData) {
15595
- const data = statsData.data.totalData;
15596
- fansNumYesterday = Number.parseInt(data.follow?.[1] || "0", 10) || 0;
15597
- playNumYesterday = Number.parseInt(data.browse?.[1] || "0", 10) || 0;
15598
- likeNumYesterday = Number.parseInt(data.like?.[1] || "0", 10) || 0;
15599
- commentNumYesterday = Number.parseInt(data.comment?.[1] || "0", 10) || 0;
15600
- }
15601
- } catch (error) {
15602
- const errMsg = error instanceof Error ? error.message : String(error);
15603
- _task.logger.warn(`视频号昨日数据获取失败(降级为null): ${errMsg}`);
15604
- }
15605
- const shipinhaoData = {
15606
- fansNum: finderUser?.fansCount || 0,
15607
- feedsCount: finderUser?.feedsCount || 0,
15608
- fansNumYesterday,
15609
- playNumYesterday,
15610
- likeNumYesterday,
15611
- commentNumYesterday
15612
- };
15613
- return (0, share_namespaceObject.success)(shipinhaoData, "视频号平台数据获取成功!");
15614
- } catch (error) {
15615
- if (error && "object" == typeof error && "code" in error && "message" in error) {
15616
- const err = error;
15617
- _task.logger.error(`视频号账号数据获取失败: ${err.message} (${err.code})`);
15618
- return types_errorResponse(err.message, err.code);
15619
- }
15620
- const errMsg = error instanceof Error ? error.message : String(error);
15621
- _task.logger.error(`视频号账号数据获取失败: ${errMsg}`);
15622
- return types_errorResponse(errMsg || "视频号账号数据获取失败");
15623
- }
15624
- }
15625
15364
  async function getToutiaoData(_task, params) {
15626
15365
  const http = new Http({
15627
15366
  headers: {
@@ -15720,7 +15459,7 @@ var __webpack_exports__ = {};
15720
15459
  userInfoHtmlPromise,
15721
15460
  userSummaryHtmlPromise
15722
15461
  ]);
15723
- if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15462
+ if (userInfoHtml.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return types_errorResponse("Token已失效,请重新获取", 414);
15724
15463
  const userInfoJson = exportWxCgiData(userInfoHtml);
15725
15464
  const userSummaryJson = exportWxCgiData(userSummaryHtml);
15726
15465
  const wxData = {
@@ -15797,9 +15536,7 @@ var __webpack_exports__ = {};
15797
15536
  "toutiao",
15798
15537
  "xiaohongshu",
15799
15538
  "weixin",
15800
- "baijiahao",
15801
- "douyin",
15802
- "shipinhao"
15539
+ "baijiahao"
15803
15540
  ])
15804
15541
  });
15805
15542
  const SearchAccountInfo = async (_task, params)=>{
@@ -15813,10 +15550,6 @@ var __webpack_exports__ = {};
15813
15550
  return getWeixinData(_task, params);
15814
15551
  case "baijiahao":
15815
15552
  return getBaijiahaoData(_task, params);
15816
- case "douyin":
15817
- return getDouyinData(_task, params);
15818
- case "shipinhao":
15819
- return getShipinhaoData(_task, params);
15820
15553
  default:
15821
15554
  return (0, share_namespaceObject.success)(null, "暂不支持该平台");
15822
15555
  }
@@ -15911,45 +15644,18 @@ var __webpack_exports__ = {};
15911
15644
  collectNum: schemas_number(),
15912
15645
  shareNum: schemas_number()
15913
15646
  });
15914
- const DouyinArticleSchema = BaseArticleSchema.extend({
15915
- playNum: schemas_number(),
15916
- likeNum: schemas_number(),
15917
- commentNum: schemas_number(),
15918
- shareNum: schemas_number(),
15919
- collectNum: schemas_number(),
15920
- awemeId: schemas_string(),
15921
- awemeType: schemas_number(),
15922
- duration: schemas_number().optional(),
15923
- status: schemas_string(),
15924
- publicUrl: schemas_string()
15925
- });
15926
- const ShipinhaoArticleSchema = BaseArticleSchema.extend({
15927
- readNum: schemas_number(),
15928
- likeNum: schemas_number(),
15929
- commentNum: schemas_number(),
15930
- forwardNum: schemas_number(),
15931
- favNum: schemas_number(),
15932
- objectId: schemas_string(),
15933
- postType: schemas_string(),
15934
- postStatus: schemas_number(),
15935
- effectiveTime: schemas_number().optional()
15936
- });
15937
15647
  const FetchArticlesDataSchema = schemas_object({
15938
15648
  articleCell: schemas_array(union([
15939
15649
  ToutiaoArticleSchema,
15940
15650
  WeixinArticleSchema,
15941
15651
  BaijiahaoArticleSchema,
15942
- XiaohongshuArticleSchema,
15943
- DouyinArticleSchema,
15944
- ShipinhaoArticleSchema
15652
+ XiaohongshuArticleSchema
15945
15653
  ])).optional(),
15946
15654
  timerPublish: schemas_array(union([
15947
15655
  ToutiaoArticleSchema,
15948
15656
  WeixinArticleSchema,
15949
15657
  BaijiahaoArticleSchema,
15950
- XiaohongshuArticleSchema,
15951
- DouyinArticleSchema,
15952
- ShipinhaoArticleSchema
15658
+ XiaohongshuArticleSchema
15953
15659
  ])).optional(),
15954
15660
  pagination: schemas_object({
15955
15661
  total: schemas_number().optional(),
@@ -16064,269 +15770,6 @@ var __webpack_exports__ = {};
16064
15770
  return searchPublishInfo_types_errorResponse(error instanceof Error ? error.message : "百家号文章数据获取失败");
16065
15771
  }
16066
15772
  }
16067
- async function handleDouyinData(_task, params) {
16068
- try {
16069
- const { cookies, pageSize = 12, status = 0, showOriginalData = false, onlySuccess = false } = params;
16070
- const pageNum = params.pageNum || 1;
16071
- const headers = {
16072
- cookie: cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
16073
- referer: "https://creator.douyin.com"
16074
- };
16075
- const args = [
16076
- {
16077
- headers
16078
- },
16079
- _task.logger,
16080
- params.proxyLoc,
16081
- params.localIP,
16082
- params.accountId
16083
- ];
16084
- const http = new Http(...args);
16085
- async function fetchWorks(cursor) {
16086
- return await http.api({
16087
- method: "get",
16088
- url: "https://creator.douyin.com/janus/douyin/creator/pc/work_list",
16089
- params: {
16090
- scene: "star_atlas",
16091
- device_platform: "android",
16092
- aid: 1128,
16093
- status,
16094
- count: pageSize,
16095
- max_cursor: cursor
16096
- }
16097
- }, {
16098
- retries: 3,
16099
- retryDelay: 100,
16100
- timeout: 5000
16101
- });
16102
- }
16103
- const isHasMore = (v)=>true === v || 1 === v;
16104
- const skipCount = (pageNum - 1) * pageSize;
16105
- const needCount = skipCount + pageSize;
16106
- const workListResponse = await fetchWorks(0);
16107
- if (!workListResponse || !Array.isArray(workListResponse.aweme_list)) return searchPublishInfo_types_errorResponse("抖音数据获取失败,请检查账号状态", 414);
16108
- const allWorks = [
16109
- ...workListResponse.aweme_list
16110
- ];
16111
- let hasMore = isHasMore(workListResponse.has_more);
16112
- let currentCursor = workListResponse.cursor ?? workListResponse.max_cursor ?? 0;
16113
- let guard = 0;
16114
- while(allWorks.length < needCount && hasMore && guard < 20){
16115
- const nextPageResponse = await fetchWorks(currentCursor);
16116
- if (!Array.isArray(nextPageResponse.aweme_list) || 0 === nextPageResponse.aweme_list.length) break;
16117
- allWorks.push(...nextPageResponse.aweme_list);
16118
- hasMore = isHasMore(nextPageResponse.has_more);
16119
- currentCursor = nextPageResponse.cursor ?? nextPageResponse.max_cursor ?? currentCursor;
16120
- guard++;
16121
- }
16122
- const finalWorks = allWorks.slice(skipCount, needCount);
16123
- const articleCell = finalWorks.map((item)=>{
16124
- const workDetailUrl = `https://creator.douyin.com/creator-micro/work-management/work-detail/${item.aweme_id}`;
16125
- const workPublicUrl = item.share_url || `https://www.douyin.com/video/${item.aweme_id}`;
16126
- let statusText;
16127
- statusText = item.status?.is_delete ? "deleted" : item.status?.is_private ? "private" : item.status?.in_reviewing ? "reviewing" : "public";
16128
- return {
16129
- title: item.desc || "无作品描述",
16130
- imageUrl: item.Cover?.url_list?.[0] || "",
16131
- createTime: item.create_time,
16132
- redirectUrl: workDetailUrl,
16133
- playNum: item.statistics?.play_count || 0,
16134
- likeNum: item.statistics?.digg_count || 0,
16135
- commentNum: item.statistics?.comment_count || 0,
16136
- shareNum: item.statistics?.share_count || 0,
16137
- collectNum: item.statistics?.collect_count || 0,
16138
- awemeId: item.aweme_id,
16139
- awemeType: item.aweme_type ?? 0,
16140
- duration: item.duration,
16141
- status: statusText,
16142
- publicUrl: workPublicUrl,
16143
- ...showOriginalData ? {
16144
- originalData: item
16145
- } : {}
16146
- };
16147
- });
16148
- return (0, share_namespaceObject.success)({
16149
- articleCell,
16150
- ...onlySuccess ? {
16151
- pagination: {
16152
- total: workListResponse.total || allWorks.length,
16153
- nextPage: hasMore,
16154
- pageNum,
16155
- pageSize
16156
- }
16157
- } : null
16158
- }, "抖音数据获取成功");
16159
- } catch (error) {
16160
- return searchPublishInfo_types_errorResponse(error instanceof Error ? error.message : "抖音数据获取失败");
16161
- }
16162
- }
16163
- async function handleShipinhaoData(_task, params) {
16164
- try {
16165
- const { cookies, postType = "all", pageSize = 10, showOriginalData = false } = params;
16166
- const pageNum = params.pageNum || 1;
16167
- const aidCookie = cookies.find((it)=>"_aid" === it.name)?.value;
16168
- const aid = aidCookie || "9d3e0e9f-b842-498d-a273-4285d58df264";
16169
- const uinCookie = cookies.find((it)=>"uin" === it.name || "wxuin" === it.name)?.value || "0000000000";
16170
- const deviceIdCookie = cookies.find((it)=>"device_id" === it.name || "finger_print_device_id" === it.name)?.value;
16171
- const headers = {
16172
- cookie: cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
16173
- referer: "https://channels.weixin.qq.com",
16174
- origin: "https://channels.weixin.qq.com",
16175
- "content-type": "application/json",
16176
- "X-WECHAT-UIN": uinCookie,
16177
- ...deviceIdCookie ? {
16178
- "finger-print-device-id": deviceIdCookie
16179
- } : {}
16180
- };
16181
- const args = [
16182
- {
16183
- headers
16184
- },
16185
- _task.logger,
16186
- params.proxyLoc,
16187
- params.localIP,
16188
- params.accountId
16189
- ];
16190
- const http = new Http(...args);
16191
- const finderIdCookie = cookies.find((it)=>"_log_finder_id" === it.name || "finder_id" === it.name)?.value || "";
16192
- async function fetchPosts(currentPage, userpageType, pageUrl, rawKeyBuff = "") {
16193
- return await http.api({
16194
- method: "post",
16195
- url: "https://channels.weixin.qq.com/micro/content/cgi-bin/mmfinderassistant-bin/post/post_list",
16196
- params: {
16197
- _aid: aid,
16198
- _rid: `${Date.now().toString(16)}-${Math.random().toString(36).substring(2, 9)}`,
16199
- _pageUrl: encodeURIComponent(pageUrl)
16200
- },
16201
- data: {
16202
- pageSize,
16203
- currentPage,
16204
- userpageType,
16205
- stickyOrder: true,
16206
- timestamp: Date.now().toString(),
16207
- _log_finder_uin: "",
16208
- _log_finder_id: finderIdCookie,
16209
- rawKeyBuff,
16210
- pluginSessionId: null,
16211
- scene: 7,
16212
- reqScene: 7
16213
- }
16214
- }, {
16215
- retries: 3,
16216
- retryDelay: 100,
16217
- timeout: 5000
16218
- });
16219
- }
16220
- async function fetchAllPosts(userpageType, pageUrl) {
16221
- const allPosts = [];
16222
- let currentPage = 1;
16223
- let rawKeyBuff = "";
16224
- let continueFlag = true;
16225
- let totalCount = 0;
16226
- while(continueFlag){
16227
- const response = await fetchPosts(currentPage, userpageType, pageUrl, rawKeyBuff);
16228
- if (response.errCode && AUTH_ERROR_CODES.includes(response.errCode)) throw new Error(`AUTH_ERROR:${response.errMsg || "登录已失效"}`);
16229
- if (response.errCode) {
16230
- _task.logger.warn(`视频号API错误:${response.errMsg} (${response.errCode})`);
16231
- throw new Error(`视频号API错误:${response.errMsg} (${response.errCode})`);
16232
- }
16233
- if (1 === currentPage) totalCount = response.data?.totalCount ?? 0;
16234
- const posts = response.data?.list || response.posts || response.post_list || [];
16235
- allPosts.push(...posts);
16236
- continueFlag = response.data?.continueFlag ?? false;
16237
- rawKeyBuff = response.data?.lastBuff || "";
16238
- currentPage++;
16239
- if (currentPage > 100) {
16240
- _task.logger.warn("分页超过100页,停止请求");
16241
- break;
16242
- }
16243
- }
16244
- if (totalCount > 0 && allPosts.length !== totalCount) _task.logger.warn(`视频号分页可能不完整:期望${totalCount}条,实际${allPosts.length}条`);
16245
- return {
16246
- posts: allPosts,
16247
- totalCount
16248
- };
16249
- }
16250
- const mapPost = (item, forcePostType)=>{
16251
- let imageUrl = "";
16252
- if (item.desc?.media?.[0]?.thumbUrl) imageUrl = item.desc.media[0].thumbUrl;
16253
- else if (item.desc?.media?.[0]?.coverUrl) imageUrl = item.desc.media[0].coverUrl;
16254
- else if (item.cover?.url) imageUrl = item.cover.url;
16255
- else if (item.media_url) imageUrl = item.media_url;
16256
- const title = item.desc?.description || item.object_desc || "无标题";
16257
- return {
16258
- title,
16259
- imageUrl,
16260
- createTime: item.createTime || item.create_time,
16261
- redirectUrl: "https://channels.weixin.qq.com/platform",
16262
- readNum: item.readCount || item.read_count || 0,
16263
- likeNum: item.likeCount || item.like_count || 0,
16264
- commentNum: item.commentCount || item.comment_count || 0,
16265
- forwardNum: item.forwardCount || item.forward_count || 0,
16266
- favNum: item.favCount || item.fav_count || 0,
16267
- objectId: item.exportId || item.objectId || "",
16268
- postType: forcePostType,
16269
- postStatus: item.status || item.post_status || 0,
16270
- ...item.effectiveTime ? {
16271
- effectiveTime: item.effectiveTime
16272
- } : {},
16273
- ...showOriginalData ? {
16274
- originalData: item
16275
- } : {}
16276
- };
16277
- };
16278
- const allArticles = [];
16279
- const needVideo = "all" === postType || "video" === postType;
16280
- const needArticle = "all" === postType || "article" === postType;
16281
- const AUTH_ERROR_CODES = [
16282
- 300333,
16283
- 300334,
16284
- 300330,
16285
- 300331,
16286
- 300332
16287
- ];
16288
- let combinedTotal = 0;
16289
- if (needVideo) try {
16290
- const videoPageUrl = "https://channels.weixin.qq.com/micro/content/post/list";
16291
- const { posts, totalCount } = await fetchAllPosts(11, videoPageUrl);
16292
- const videoArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "video"));
16293
- allArticles.push(...videoArticles);
16294
- combinedTotal += totalCount || videoArticles.length;
16295
- } catch (error) {
16296
- const errMsg = error instanceof Error ? error.message : String(error);
16297
- if (errMsg.startsWith("AUTH_ERROR:")) throw error;
16298
- _task.logger.warn(`获取视频号视频失败:${errMsg}`);
16299
- }
16300
- if (needArticle) try {
16301
- const articlePageUrl = "https://channels.weixin.qq.com/micro/content/post/finderNewLifePostList";
16302
- const { posts, totalCount } = await fetchAllPosts(10, articlePageUrl);
16303
- const articleArticles = posts.filter((item)=>item.createTime || item.create_time).map((item)=>mapPost(item, "article"));
16304
- allArticles.push(...articleArticles);
16305
- combinedTotal += totalCount || articleArticles.length;
16306
- } catch (error) {
16307
- const errMsg = error instanceof Error ? error.message : String(error);
16308
- if (errMsg.startsWith("AUTH_ERROR:")) throw error;
16309
- _task.logger.warn(`获取视频号图文失败:${errMsg}`);
16310
- }
16311
- allArticles.sort((a, b)=>b.createTime - a.createTime);
16312
- const total = allArticles.length;
16313
- const start = (pageNum - 1) * pageSize;
16314
- const pageItems = allArticles.slice(start, start + pageSize);
16315
- return (0, share_namespaceObject.success)({
16316
- articleCell: pageItems,
16317
- pagination: {
16318
- total,
16319
- nextPage: start + pageSize < total,
16320
- pageNum,
16321
- pageSize
16322
- }
16323
- }, "视频号数据获取成功");
16324
- } catch (error) {
16325
- const errMsg = error instanceof Error ? error.message : String(error);
16326
- if (errMsg.startsWith("AUTH_ERROR:")) return searchPublishInfo_types_errorResponse("视频号数据获取失败,请检查账号状态", 414);
16327
- return searchPublishInfo_types_errorResponse(errMsg || "视频号数据获取失败");
16328
- }
16329
- }
16330
15773
  async function handleToutiaoData(_task, params) {
16331
15774
  try {
16332
15775
  const { cookies, pageNum = 1, pageSize = 10, showOriginalData = false, onlySuccess = false, containsArticle = false } = params;
@@ -16359,7 +15802,7 @@ var __webpack_exports__ = {};
16359
15802
  app_id: 1231
16360
15803
  }
16361
15804
  });
16362
- if (0 !== visitedUid.code) return searchPublishInfo_types_errorResponse("头条号数据获取失败,请检查账号状态", 414);
15805
+ if (0 !== visitedUid.code) return searchPublishInfo_types_errorResponse("头条号账号信息获取失败,请检查账号状态", 414);
16363
15806
  const articleInfo = await http.api({
16364
15807
  method: "get",
16365
15808
  url: "https://mp.toutiao.com/api/feed/mp_provider/v1/",
@@ -16468,7 +15911,7 @@ var __webpack_exports__ = {};
16468
15911
  const size = onlySuccess ? 10 : pageSize > 20 ? 20 : pageSize;
16469
15912
  let begin = (lastPage ?? pageNum) - 1;
16470
15913
  const rawArticlesInfo = await fetchArticles(begin * size, size, token);
16471
- if (rawArticlesInfo.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return searchPublishInfo_types_errorResponse("微信公众号数据获取失败,请检查账号状态", 414);
15914
+ if (rawArticlesInfo.includes("请重新<a id='jumpUrl' href='/'>登录</a>")) return searchPublishInfo_types_errorResponse("登陆已失效,请重新登陆!", 414);
16472
15915
  const articlesInfo = ParsePublishPage(rawArticlesInfo);
16473
15916
  let articleCell = [];
16474
15917
  if (!onlySuccess && pageSize > 20) {
@@ -16630,7 +16073,7 @@ var __webpack_exports__ = {};
16630
16073
  const a1Cookie = cookies.find((it)=>"a1" === it.name)?.value;
16631
16074
  if (!a1Cookie) return {
16632
16075
  code: 414,
16633
- message: "小红书数据获取失败,请检查账号状态",
16076
+ message: "账号数据异常",
16634
16077
  data: {}
16635
16078
  };
16636
16079
  if (onlySuccess && 10 !== pageSize) return {
@@ -16749,7 +16192,7 @@ var __webpack_exports__ = {};
16749
16192
  }, "小红书文章数据获取成功");
16750
16193
  }
16751
16194
  const FetchArticlesParamsSchema = ActionCommonParamsSchema.extend({
16752
- platform: schemas_string().describe("社交平台:weixin, toutiao, baijiahao, xiaohongshu, douyin, shipinhao"),
16195
+ platform: schemas_string().describe("社交平台:weixin, toutiao, baijiahao, xiaohongshu"),
16753
16196
  token: union([
16754
16197
  schemas_string(),
16755
16198
  schemas_number()
@@ -16761,14 +16204,7 @@ var __webpack_exports__ = {};
16761
16204
  showOriginalData: schemas_boolean().optional().describe("是否展示原始数据,默认false"),
16762
16205
  cursor: schemas_number().optional().describe("仅用于微信分页游标,默认为空"),
16763
16206
  lastPage: schemas_number().optional(),
16764
- containsArticle: schemas_boolean().optional().describe("是否包含文章内容,默认false"),
16765
- status: schemas_number().optional().describe("抖音作品状态:0=全部"),
16766
- includeAccount: schemas_boolean().optional().describe("是否包含账号数据,默认true"),
16767
- postType: schemas_enum([
16768
- "video",
16769
- "article",
16770
- "all"
16771
- ]).optional().describe("视频号作品类型:video=视频, article=图文, all=全部")
16207
+ containsArticle: schemas_boolean().optional().describe("是否包含文章内容,默认false")
16772
16208
  });
16773
16209
  const FetchArticles = async (_task, params)=>{
16774
16210
  const { platform } = params;
@@ -16781,10 +16217,6 @@ var __webpack_exports__ = {};
16781
16217
  return handleBaijiahaoData(_task, params);
16782
16218
  case "xiaohongshu":
16783
16219
  return handleXiaohongshuData(_task, params);
16784
- case "douyin":
16785
- return handleDouyinData(_task, params);
16786
- case "shipinhao":
16787
- return handleShipinhaoData(_task, params);
16788
16220
  default:
16789
16221
  return (0, share_namespaceObject.success)({}, "暂不支持该平台");
16790
16222
  }
@@ -18188,11 +17620,6 @@ var __webpack_exports__ = {};
18188
17620
  this.concurrentLimit = config.concurrentLimit || 4;
18189
17621
  this.singleFileSize = config.singleFileSize || 10485760;
18190
17622
  this.http = config.http || new Http();
18191
- this.reqOptions = {
18192
- timeout: config.timeout ?? 60000,
18193
- retries: config.retries ?? 3,
18194
- retryDelay: config.retryDelay ?? 2000
18195
- };
18196
17623
  }
18197
17624
  calculateMd5(buffer) {
18198
17625
  const MAX_SIZE = 5242880;
@@ -18249,7 +17676,7 @@ var __webpack_exports__ = {};
18249
17676
  url: filePath,
18250
17677
  method: "get",
18251
17678
  responseType: "arraybuffer"
18252
- }, this.reqOptions);
17679
+ });
18253
17680
  return Buffer.from(resp);
18254
17681
  }
18255
17682
  return external_node_fs_default().promises.readFile(filePath);
@@ -18279,7 +17706,7 @@ var __webpack_exports__ = {};
18279
17706
  headers,
18280
17707
  data: requestBody,
18281
17708
  defaultErrorMsg: "获取UploadID失败"
18282
- }, this.reqOptions);
17709
+ });
18283
17710
  if (!resp?.UploadID) throw new Error(`获取 UploadID 失败: ${resp?.errMsg || "未知错误"}`);
18284
17711
  return resp.UploadID;
18285
17712
  }
@@ -18300,7 +17727,7 @@ var __webpack_exports__ = {};
18300
17727
  headers,
18301
17728
  data: chunk,
18302
17729
  defaultErrorMsg: `分片 ${partNumber} 上传失败`
18303
- }, this.reqOptions);
17730
+ });
18304
17731
  if (resp?.errCode !== void 0 && 0 !== resp.errCode) throw new Error(`分片 ${partNumber} 上传失败: ${resp.errMsg}`);
18305
17732
  if (onProgress) onProgress(chunk.length);
18306
17733
  return resp.ETag || "";
@@ -18324,7 +17751,7 @@ var __webpack_exports__ = {};
18324
17751
  headers,
18325
17752
  data: requestBody,
18326
17753
  defaultErrorMsg: "确认分片上传失败"
18327
- }, this.reqOptions);
17754
+ });
18328
17755
  if (resp?.ListPartsResult?.Part) return resp.ListPartsResult.Part.map((p)=>({
18329
17756
  PartNumber: parseInt(p.PartNumber),
18330
17757
  ETag: p.ETag
@@ -18350,7 +17777,7 @@ var __webpack_exports__ = {};
18350
17777
  headers,
18351
17778
  data: requestBody,
18352
17779
  defaultErrorMsg: "完成上传失败"
18353
- }, this.reqOptions);
17780
+ });
18354
17781
  if (!resp?.DownloadURL) throw new Error(`完成上传失败: ${resp?.errMsg || "未知错误"}`);
18355
17782
  return resp.DownloadURL;
18356
17783
  }
@@ -18701,9 +18128,7 @@ var __webpack_exports__ = {};
18701
18128
  task.logger.info("[shipinhaoPublish] 开始执行视频号发布 - Mock API 方式");
18702
18129
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
18703
18130
  if (!params.extraParam.fingerPrintDeviceId || !params.extraParam.aId) return (0, share_namespaceObject.response)(400, "fingerPrintDeviceId和aId 不能为空", "");
18704
- let currentStep = "初始化";
18705
18131
  try {
18706
- currentStep = "解析认证信息";
18707
18132
  const cookieString = params.cookies.map((c)=>`${c.name}=${c.value}`).join("; ");
18708
18133
  const fingerPrintDeviceId = params.extraParam.fingerPrintDeviceId;
18709
18134
  const aId = params.extraParam.aId;
@@ -18724,10 +18149,8 @@ var __webpack_exports__ = {};
18724
18149
  headers
18725
18150
  });
18726
18151
  const proxyHttp = new Http(...args);
18727
- currentStep = "验证发布参数";
18728
18152
  if (!params.banners || 0 === params.banners.length) return (0, share_namespaceObject.response)(400, "至少需要一张图片", "");
18729
18153
  const images = params.banners.slice(0, 18).filter((img)=>"string" == typeof img);
18730
- currentStep = "获取用户信息";
18731
18154
  task.logger.info("[shipinhaoPublish] 获取用户信息...");
18732
18155
  console.log("cookieString", cookieString);
18733
18156
  const userInfo = await mock_getUserInfo(cookieString, http);
@@ -18738,7 +18161,6 @@ var __webpack_exports__ = {};
18738
18161
  }
18739
18162
  const finderUsername = userInfo.data.finderUser.finderUsername;
18740
18163
  console.log(finderUsername);
18741
- currentStep = "获取上传认证密钥";
18742
18164
  task.logger.info("[shipinhaoPublish] 获取上传认证密钥...");
18743
18165
  const authKeyResponse = await getUploadAuthKey(cookieString, finderUsername, http);
18744
18166
  if (0 !== authKeyResponse.errCode || !authKeyResponse.data?.authKey) return (0, share_namespaceObject.response)(authKeyResponse.errCode || 500, `获取上传认证参数失败: ${authKeyResponse.errMsg}`, "");
@@ -18746,12 +18168,10 @@ var __webpack_exports__ = {};
18746
18168
  const uin = authKeyResponse.data.uin;
18747
18169
  if (!uin) return (0, share_namespaceObject.response)(500, "获取用户 uin 失败", "");
18748
18170
  const taskId = String(generateUUID());
18749
- currentStep = "上传图片";
18750
18171
  task.logger.info(`[shipinhaoPublish] 开始上传 ${images.length} 张图片...`);
18751
18172
  const uploadedImages = [];
18752
18173
  for(let i = 0; i < images.length; i++){
18753
- currentStep = `上传图片 ${i + 1}/${images.length}`;
18754
- task.logger.info(`[shipinhaoPublish] ${currentStep}...`);
18174
+ task.logger.info(`[shipinhaoPublish] 上传图片 ${i + 1}/${images.length}...`);
18755
18175
  const uploadResult = await uploadImageComplete(images[i], taskId, finderUsername, uin, authKey, http);
18756
18176
  console.log(JSON.stringify(uploadResult));
18757
18177
  if (!uploadResult.DownloadURL) return (0, share_namespaceObject.response)(500, `图片上传失败: ${uploadResult.errMsg}`, "");
@@ -18768,7 +18188,6 @@ var __webpack_exports__ = {};
18768
18188
  urlCdnTaskId: ""
18769
18189
  });
18770
18190
  }
18771
- currentStep = "发布图文内容";
18772
18191
  task.logger.info("[shipinhaoPublish] 正在发布...");
18773
18192
  const topicNames = params.topic || void 0;
18774
18193
  const addressInfo = params.address ? {
@@ -18855,15 +18274,9 @@ var __webpack_exports__ = {};
18855
18274
  });
18856
18275
  return (0, share_namespaceObject.response)(resultCode || 500, errorMessage, "");
18857
18276
  } catch (error) {
18858
- const handledError = Http.handleApiError(error);
18859
- const errorMsg = handledError.message || "发布失败,请稍后重试";
18860
- const errorCode = handledError.code || 500;
18861
- task.logger.error(`[shipinhaoPublish] 发布流程异常: ${errorMsg}`, stringifyError(error), handledError.extra);
18862
- await updateTaskState?.({
18863
- state: share_namespaceObject.TaskState.FAILED,
18864
- error: errorMsg
18865
- });
18866
- return (0, share_namespaceObject.response)(errorCode, errorMsg, "");
18277
+ const errorMsg = error instanceof Error ? error.message : "发布失败";
18278
+ task.logger.error(`[shipinhaoPublish] 发布异常: ${errorMsg}`);
18279
+ return (0, share_namespaceObject.response)(500, errorMsg, "");
18867
18280
  }
18868
18281
  };
18869
18282
  const shipinhaoPublish_rpa_rpaAction = async (task, params)=>{
@@ -25369,24 +24782,6 @@ var __webpack_exports__ = {};
25369
24782
  likeNumYesterday: schemas_number().nullable(),
25370
24783
  commentNumYesterday: schemas_number().nullable()
25371
24784
  });
25372
- const douyinConfigDataSchema = schemas_object({
25373
- fansNum: schemas_number(),
25374
- favedNum: schemas_number(),
25375
- fansNumLastWeek: schemas_number(),
25376
- watchNumLastWeek: schemas_number(),
25377
- likeNumLastWeek: schemas_number(),
25378
- commentNumLastWeek: schemas_number(),
25379
- shareNumLastWeek: schemas_number(),
25380
- visitNumLastWeek: schemas_number()
25381
- });
25382
- const shipinhaoConfigDataSchema = schemas_object({
25383
- fansNum: schemas_number(),
25384
- feedsCount: schemas_number(),
25385
- fansNumYesterday: schemas_number().nullable(),
25386
- playNumYesterday: schemas_number().nullable(),
25387
- likeNumYesterday: schemas_number().nullable(),
25388
- commentNumYesterday: schemas_number().nullable()
25389
- });
25390
24785
  const BetaFlag = "HuiwenCanary";
25391
24786
  class Action {
25392
24787
  constructor(task){
@@ -25675,5 +25070,4 @@ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_targe
25675
25070
  value: true
25676
25071
  });
25677
25072
 
25678
- //# sourceMappingURL=index.js.map
25679
- //# debugId=e1cb75dd-cee5-50ef-9ae8-80ab2cccd402
25073
+ //# sourceMappingURL=index.js.map