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