@iflyrpa/actions 4.0.0-beta.1 → 4.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bundle.js CHANGED
@@ -8733,10 +8733,8 @@ var __webpack_exports__ = {};
8733
8733
  navigator: ()=>_navigator,
8734
8734
  origin: ()=>utils_origin
8735
8735
  });
8736
- var package_namespaceObject = {
8737
- i8: "0.1.0"
8738
- };
8739
- var package_namespaceObject_0 = JSON.parse('{"i8":"3.0.5-beta.0"}');
8736
+ var package_namespaceObject = JSON.parse('{"i8":"1.0.0-beta.1"}');
8737
+ var package_namespaceObject_0 = JSON.parse('{"i8":"4.0.0-beta.9"}');
8740
8738
  const external_node_fs_namespaceObject = require("node:fs");
8741
8739
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
8742
8740
  const external_node_http_namespaceObject = require("node:http");
@@ -8777,6 +8775,7 @@ var __webpack_exports__ = {};
8777
8775
  }
8778
8776
  });
8779
8777
  }
8778
+ const DOWNLOAD_BASE_TIMEOUT = 60000;
8780
8779
  async function downloadImage(url, savePath, retries = 3) {
8781
8780
  const RETRYABLE_CODES = new Set([
8782
8781
  "ECONNRESET",
@@ -8784,20 +8783,25 @@ var __webpack_exports__ = {};
8784
8783
  "EAI_AGAIN",
8785
8784
  "ENOTFOUND"
8786
8785
  ]);
8787
- try {
8788
- return await downloadImageOnce(url, savePath);
8789
- } catch (err) {
8790
- var _err_extra;
8791
- const errCode = (null == err ? void 0 : err.code) ?? (null == err ? void 0 : null === (_err_extra = err.extra) || void 0 === _err_extra ? void 0 : _err_extra.code);
8792
- if (retries > 0 && (RETRYABLE_CODES.has(errCode) || (null == err ? void 0 : err.code) === 500)) {
8793
- console.warn(`downloadImage 失败,剩余重试次数 ${retries},url: ${url},原因:`, (null == err ? void 0 : err.message) ?? err);
8786
+ const maxAttempts = retries;
8787
+ let lastErr;
8788
+ for(let attempt = 1; attempt <= maxAttempts; attempt++){
8789
+ const timeout = attempt * DOWNLOAD_BASE_TIMEOUT;
8790
+ try {
8791
+ return await downloadImageOnce(url, savePath, timeout);
8792
+ } catch (err) {
8793
+ var _err_extra;
8794
+ lastErr = err;
8795
+ const errCode = (null == err ? void 0 : err.code) ?? (null == err ? void 0 : null === (_err_extra = err.extra) || void 0 === _err_extra ? void 0 : _err_extra.code);
8796
+ const retryable = RETRYABLE_CODES.has(errCode) || (null == err ? void 0 : err.code) === 500;
8797
+ if (attempt >= maxAttempts || !retryable) throw err;
8798
+ console.warn(`downloadImage 失败,已尝试 ${attempt}/${maxAttempts} 次,下次超时 ${(attempt + 1) * DOWNLOAD_BASE_TIMEOUT / 1000}s,url: ${url},原因:`, (null == err ? void 0 : err.message) ?? err);
8794
8799
  await new Promise((r)=>setTimeout(r, 1000));
8795
- return downloadImage(url, savePath, retries - 1);
8796
8800
  }
8797
- throw err;
8798
8801
  }
8802
+ throw lastErr;
8799
8803
  }
8800
- async function downloadImageOnce(url, savePath) {
8804
+ async function downloadImageOnce(url, savePath, timeout = DOWNLOAD_BASE_TIMEOUT) {
8801
8805
  await ensureFile(savePath);
8802
8806
  return new Promise((resolve, reject)=>{
8803
8807
  const handleResponse = (response)=>{
@@ -8879,11 +8883,24 @@ var __webpack_exports__ = {};
8879
8883
  };
8880
8884
  const requestFn = url.startsWith("http://") ? external_node_http_namespaceObject.get : external_node_https_namespaceObject.get;
8881
8885
  const req = requestFn(url, handleResponse);
8882
- req.setTimeout(60000, ()=>{
8886
+ let remoteAddress = "";
8887
+ req.on("socket", (socket)=>{
8888
+ socket.on("connect", ()=>{
8889
+ remoteAddress = `${socket.remoteAddress ?? ""}:${socket.remotePort ?? ""}`;
8890
+ });
8891
+ if (socket.remoteAddress) remoteAddress = `${socket.remoteAddress}:${socket.remotePort ?? ""}`;
8892
+ });
8893
+ req.setTimeout(timeout, ()=>{
8883
8894
  req.destroy();
8895
+ const remoteInfo = remoteAddress || "未建立连接";
8896
+ console.warn(`图片下载超时 (${timeout / 1000}s),远端IP: ${remoteInfo},Url:${url}`);
8884
8897
  reject({
8885
8898
  code: 500,
8886
- message: `图片下载超时 (${url}),请检查网络连接或稍后重试!`
8899
+ message: `图片下载超时 (${timeout / 1000}s) Url:${url},请检查网络连接或稍后重试! 远端ip: ${remoteInfo}`,
8900
+ extra: {
8901
+ url,
8902
+ remoteAddress: remoteInfo
8903
+ }
8887
8904
  });
8888
8905
  });
8889
8906
  req.on("error", handleError);
@@ -23451,7 +23468,7 @@ var __webpack_exports__ = {};
23451
23468
  599
23452
23469
  ].includes(handledError.code);
23453
23470
  if (Rtimes < retries && isRetry) {
23454
- this.logger?.info(`进入第${Rtimes + 1}次重试!`);
23471
+ this.logger?.info(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}`);
23455
23472
  await new Promise((resolve)=>setTimeout(resolve, retryDelay));
23456
23473
  return sessionRt(Rtimes + 1);
23457
23474
  }
@@ -30619,16 +30636,35 @@ var __webpack_exports__ = {};
30619
30636
  }, "微信账号有效性检测完成!");
30620
30637
  };
30621
30638
  const XhsSessionCheck = async (_task, params)=>{
30639
+ const logger = _task.logger;
30640
+ const startedAt = Date.now();
30622
30641
  const check = {
30623
30642
  isValidSession: false,
30624
30643
  isValidWebSession: false
30625
30644
  };
30645
+ const cookieNames = params.cookies.map((it)=>it.name);
30646
+ logger?.info("[XhsSessionCheck] 开始执行小红书账号有效性检测", {
30647
+ accountId: params.accountId,
30648
+ proxyLoc: params.proxyLoc,
30649
+ localIP: params.localIP,
30650
+ willUseProxyAgent: !!params.localIP,
30651
+ cookieCount: params.cookies.length,
30652
+ cookieNames,
30653
+ hasA1: cookieNames.includes("a1"),
30654
+ hasWebSession: cookieNames.includes("web_session")
30655
+ });
30626
30656
  const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
30627
- if (!a1Cookie) return {
30628
- code: 414,
30629
- message: "账号数据异常,请重新绑定账号后重试。",
30630
- data: check
30631
- };
30657
+ if (!a1Cookie) {
30658
+ logger?.warn("[XhsSessionCheck] 缺失关键 cookie a1,提前返回", {
30659
+ accountId: params.accountId,
30660
+ cookieNames
30661
+ });
30662
+ return {
30663
+ code: 414,
30664
+ message: "账号数据异常,请重新绑定账号后重试。",
30665
+ data: check
30666
+ };
30667
+ }
30632
30668
  const headers = {
30633
30669
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
30634
30670
  referer: "https://creator.xiaohongshu.com/new/home?source=official"
@@ -30656,6 +30692,7 @@ var __webpack_exports__ = {};
30656
30692
  return acc;
30657
30693
  }, {});
30658
30694
  const loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
30695
+ const baseInfoStart = Date.now();
30659
30696
  const _baseInfo = http.api({
30660
30697
  method: "get",
30661
30698
  baseURL: "https://creator.xiaohongshu.com",
@@ -30665,7 +30702,28 @@ var __webpack_exports__ = {};
30665
30702
  retries: 3,
30666
30703
  retryDelay: 20,
30667
30704
  timeout: 3000
30668
- }).catch((e)=>e.data);
30705
+ }).then((res)=>{
30706
+ logger?.info("[XhsSessionCheck] creator base 接口请求成功", {
30707
+ accountId: params.accountId,
30708
+ duration: Date.now() - baseInfoStart,
30709
+ code: res?.code,
30710
+ msg: res?.msg,
30711
+ proxyInfo: http.proxyInfo
30712
+ });
30713
+ return res;
30714
+ }).catch((e)=>{
30715
+ logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
30716
+ accountId: params.accountId,
30717
+ duration: Date.now() - baseInfoStart,
30718
+ code: e?.code,
30719
+ message: e?.message,
30720
+ data: e?.data,
30721
+ extra: e?.extra,
30722
+ proxyInfo: http.proxyInfo
30723
+ });
30724
+ return e.data;
30725
+ });
30726
+ const webSessionStart = Date.now();
30669
30727
  const _web_session = http.api({
30670
30728
  method: "get",
30671
30729
  url: "https://edith.xiaohongshu.com/api/sns/web/unread_count"
@@ -30673,6 +30731,26 @@ var __webpack_exports__ = {};
30673
30731
  retries: 3,
30674
30732
  retryDelay: 20,
30675
30733
  timeout: 3000
30734
+ }).then((res)=>{
30735
+ logger?.info("[XhsSessionCheck] edith unread_count 接口请求成功", {
30736
+ accountId: params.accountId,
30737
+ duration: Date.now() - webSessionStart,
30738
+ code: res?.code,
30739
+ msg: res?.msg,
30740
+ proxyInfo: http.proxyInfo
30741
+ });
30742
+ return res;
30743
+ }).catch((e)=>{
30744
+ logger?.warn("[XhsSessionCheck] edith unread_count 接口请求失败", {
30745
+ accountId: params.accountId,
30746
+ duration: Date.now() - webSessionStart,
30747
+ code: e?.code,
30748
+ message: e?.message,
30749
+ data: e?.data,
30750
+ extra: e?.extra,
30751
+ proxyInfo: http.proxyInfo
30752
+ });
30753
+ throw e;
30676
30754
  });
30677
30755
  const [baseInfo, web_session] = await Promise.all([
30678
30756
  _baseInfo,
@@ -30680,8 +30758,18 @@ var __webpack_exports__ = {};
30680
30758
  ]);
30681
30759
  if (baseInfo?.code === 0) check.isValidSession = true;
30682
30760
  if (0 === web_session.code) check.isValidWebSession = true;
30683
- baseInfo?.code, web_session.code;
30761
+ const _isSuccess = baseInfo?.code === web_session.code;
30684
30762
  const message = `小红书账号有效性检测成功${_task.debug ? ` ${http.proxyInfo}` : ""}`;
30763
+ logger?.info("[XhsSessionCheck] 检测完成", {
30764
+ accountId: params.accountId,
30765
+ totalDuration: Date.now() - startedAt,
30766
+ baseInfoCode: baseInfo?.code,
30767
+ webSessionCode: web_session?.code,
30768
+ isValidSession: check.isValidSession,
30769
+ isValidWebSession: check.isValidWebSession,
30770
+ codeAligned: _isSuccess,
30771
+ proxyInfo: http.proxyInfo
30772
+ });
30685
30773
  return success(check, message);
30686
30774
  };
30687
30775
  const BjhSessionCheck = async (_task, params)=>{
@@ -34701,7 +34789,10 @@ var __webpack_exports__ = {};
34701
34789
  task.logger.info(`拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
34702
34790
  decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
34703
34791
  if (needsVerification(decision)) {
34704
- task.logger.info(`需要验证: ${JSON.stringify(decision)}`);
34792
+ task.logger.warn(`检测到需要验证: ${JSON.stringify(decision)}`);
34793
+ task.logger.warn(`验证类型: ${decision?.verify_ways?.join(", ")}`);
34794
+ task.logger.warn(`验证标题: ${decision?.verify_title}`);
34795
+ task.logger.warn(`验证描述: ${decision?.verify_desc}`);
34705
34796
  return;
34706
34797
  }
34707
34798
  if (!response || !response.data) return;
@@ -34728,38 +34819,105 @@ var __webpack_exports__ = {};
34728
34819
  });
34729
34820
  return utils_response(0, message, data);
34730
34821
  }
34731
- const webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
34822
+ let webProtectData;
34823
+ try {
34824
+ webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
34825
+ if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
34826
+ task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
34827
+ return utils_response(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
34828
+ }
34829
+ } catch (error) {
34830
+ task.logger.error(`解析 webProtectData 失败: ${error}`);
34831
+ return utils_response(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
34832
+ }
34732
34833
  const ticket = webProtectData.ticket;
34733
34834
  const ts_sign = webProtectData.ts_sign;
34734
- const ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
34735
- const certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
34835
+ let ec_privateKey;
34836
+ try {
34837
+ ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
34838
+ if (!ec_privateKey) {
34839
+ task.logger.error("ec_privateKey 为空");
34840
+ return utils_response(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
34841
+ }
34842
+ } catch (error) {
34843
+ task.logger.error(`解析 ec_privateKey 失败: ${error}`);
34844
+ return utils_response(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
34845
+ }
34846
+ let certificate;
34847
+ try {
34848
+ certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
34849
+ if (!certificate) {
34850
+ task.logger.error("certificate 为空");
34851
+ return utils_response(414, "安全参数 certificate 缺失,请重新获取后重试", "");
34852
+ }
34853
+ } catch (error) {
34854
+ task.logger.error(`解析 certificate 失败: ${error}`);
34855
+ return utils_response(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
34856
+ }
34736
34857
  const ree_public_key = webProtectData.client_cert.replace("pub.", "");
34737
- task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket}, ts_sign: ${ts_sign}, ec_privateKey: ${ec_privateKey}, certificate: ${certificate}, ree_public_key: ${ree_public_key}`);
34738
- const bdTicketGuardClientData = getBdV2({
34739
- ticket,
34740
- ts_sign: ts_sign,
34741
- ec_privateKey: ec_privateKey,
34742
- certificate: certificate,
34743
- bd_ticket_guard_ree_public_key: ree_public_key
34744
- });
34745
- task.logger.info("bdTicketGuardClientData", {
34746
- bdTicketGuardClientData
34747
- });
34858
+ task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket?.substring(0, 20)}..., ts_sign: ${ts_sign}, ree_public_key: ${ree_public_key?.substring(0, 20)}...`);
34859
+ let bdTicketGuardClientData;
34860
+ try {
34861
+ bdTicketGuardClientData = getBdV2({
34862
+ ticket,
34863
+ ts_sign: ts_sign,
34864
+ ec_privateKey: ec_privateKey,
34865
+ certificate: certificate,
34866
+ bd_ticket_guard_ree_public_key: ree_public_key
34867
+ });
34868
+ if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
34869
+ task.logger.error(`bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
34870
+ return utils_response(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
34871
+ }
34872
+ } catch (error) {
34873
+ task.logger.error(`生成 bdTicketGuardClientData 失败: ${error}`);
34874
+ return utils_response(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
34875
+ }
34876
+ task.logger.info("bdTicketGuardClientData 生成成功");
34748
34877
  const publishQuery = {
34749
34878
  ...publishParams,
34750
34879
  a_bogus: ""
34751
34880
  };
34752
34881
  const queryString = new URLSearchParams(publishQuery).toString();
34753
- const aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
34882
+ let aBogus;
34883
+ try {
34884
+ aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
34885
+ if (!aBogus || aBogus.length < 10) {
34886
+ task.logger.error(`a_bogus 生成异常,长度过短: ${aBogus}`);
34887
+ return utils_response(414, "安全参数 a_bogus 生成失败,请重试", "");
34888
+ }
34889
+ task.logger.info(`a_bogus 生成成功: ${aBogus.substring(0, 20)}...`);
34890
+ } catch (error) {
34891
+ task.logger.error(`生成 a_bogus 失败: ${error}`);
34892
+ return utils_response(414, "安全参数 a_bogus 生成异常,请重试", "");
34893
+ }
34754
34894
  publishQuery.a_bogus = aBogus;
34755
34895
  const publishQueryParams = new URLSearchParams(publishQuery).toString();
34756
- const csrfToken = mock_generateCsrfTokenAdvanced({
34757
- cookies: params.cookies,
34758
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
34759
- method: "POST",
34760
- userAgent
34761
- });
34762
- const sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
34896
+ let csrfToken;
34897
+ try {
34898
+ csrfToken = mock_generateCsrfTokenAdvanced({
34899
+ cookies: params.cookies,
34900
+ url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
34901
+ method: "POST",
34902
+ userAgent
34903
+ });
34904
+ if (!csrfToken || csrfToken.length < 10) {
34905
+ task.logger.error(`csrfToken 生成异常,长度过短: ${csrfToken}`);
34906
+ return utils_response(414, "安全参数 csrfToken 生成失败,请重试", "");
34907
+ }
34908
+ task.logger.info(`csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
34909
+ } catch (error) {
34910
+ task.logger.error(`生成 csrfToken 失败: ${error}`);
34911
+ return utils_response(414, "安全参数 csrfToken 生成异常,请重试", "");
34912
+ }
34913
+ let sessionDtrait;
34914
+ try {
34915
+ sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
34916
+ task.logger.info(`sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
34917
+ } catch (error) {
34918
+ task.logger.error(`生成 sessionDtrait 失败: ${error}`);
34919
+ return utils_response(414, "安全参数 sessionDtrait 生成异常,请重试", "");
34920
+ }
34763
34921
  task.logger.info("发布数据", {
34764
34922
  data: JSON.stringify(publishData)
34765
34923
  });
@@ -34804,19 +34962,28 @@ var __webpack_exports__ = {};
34804
34962
  task.logger.info("========== api调用完成 ==========");
34805
34963
  task.logger.info(`decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
34806
34964
  if (needsVerification(decision)) {
34965
+ const details = [
34966
+ publishResult.status_msg,
34967
+ decision?.verify_title,
34968
+ decision?.verify_desc
34969
+ ].filter(Boolean).join(" ");
34970
+ const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
34807
34971
  task.logger.warn(`TaskId:${task.taskId},检测到需要验证,准备返回验证信息`);
34808
- await updateTaskState?.({
34809
- state: types_TaskState.SUCCESS,
34972
+ let decisionObj = {};
34973
+ if (decision) decisionObj = decision;
34974
+ const mockData = {
34975
+ state: types_TaskState.FAILED,
34976
+ error: message,
34810
34977
  result: {
34811
- response: decision
34978
+ ...decisionObj,
34979
+ data: decision,
34980
+ uploadedImgList: JSON.stringify(publishData.item.common.images)
34812
34981
  }
34813
- });
34814
- task.logger.info("返回验证响应: code=0, message=操作成功");
34982
+ };
34983
+ await updateTaskState?.(mockData);
34815
34984
  return {
34816
34985
  code: 0,
34817
- data: {
34818
- result: decision
34819
- },
34986
+ data: mockData,
34820
34987
  message: "操作成功"
34821
34988
  };
34822
34989
  }
@@ -34838,10 +35005,13 @@ var __webpack_exports__ = {};
34838
35005
  const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
34839
35006
  const data = isSuccess ? publishResult.item_id || "" : "";
34840
35007
  if (!isSuccess) {
35008
+ let decisionObj = {};
35009
+ if (decision) decisionObj = decision;
34841
35010
  await updateTaskState?.({
34842
35011
  state: types_TaskState.FAILED,
34843
35012
  error: message,
34844
35013
  result: {
35014
+ ...decisionObj,
34845
35015
  data: decision,
34846
35016
  uploadedImgList: JSON.stringify(publishData.item.common.images)
34847
35017
  }
@@ -35516,15 +35686,41 @@ var __webpack_exports__ = {};
35516
35686
  }
35517
35687
  task.logger?.info("准备发布...");
35518
35688
  await page.waitForTimeout(1000);
35519
- const response = await new Promise((resolve, reject)=>{
35689
+ const result = await new Promise((resolve, reject)=>{
35520
35690
  const handleResponse = async (res)=>{
35521
35691
  if (res.url().includes("/web/api/media/aweme/create_v2")) {
35522
35692
  task.logger?.info("匹配到发布接口响应");
35693
+ let decision = null;
35694
+ try {
35695
+ const headers = await res.allHeaders();
35696
+ decision = parseVerifyPassportDecision(headers["x-tt-verify-passport-decision"]);
35697
+ } catch (error) {
35698
+ task.logger?.warn(`解析验证决策头失败: ${error}`);
35699
+ }
35523
35700
  const jsonResponse = await res.json();
35524
35701
  task.logger?.info(`发布接口响应数据: ${JSON.stringify(jsonResponse)}`);
35525
35702
  page.off("response", handleResponse);
35526
- if (jsonResponse?.status_code === 0) resolve(jsonResponse?.data?.item_id || jsonResponse?.item_id || "");
35527
- else reject(new Error(jsonResponse?.status_msg || "发布失败"));
35703
+ if (needsVerification(decision)) {
35704
+ task.logger?.warn("检测到需要二次验证,文章未真正发布");
35705
+ resolve({
35706
+ itemId: "",
35707
+ decision
35708
+ });
35709
+ return;
35710
+ }
35711
+ if (jsonResponse?.status_code !== 0) {
35712
+ reject(new Error(jsonResponse?.status_msg || "发布失败"));
35713
+ return;
35714
+ }
35715
+ const itemId = jsonResponse?.data?.item_id || jsonResponse?.item_id || "";
35716
+ if (!itemId) {
35717
+ reject(new Error(jsonResponse?.status_msg || "发布异常:未返回作品ID,文章可能未真正发布"));
35718
+ return;
35719
+ }
35720
+ resolve({
35721
+ itemId,
35722
+ decision: null
35723
+ });
35528
35724
  }
35529
35725
  };
35530
35726
  page.on("response", handleResponse);
@@ -35546,20 +35742,42 @@ var __webpack_exports__ = {};
35546
35742
  await page.close();
35547
35743
  return null;
35548
35744
  });
35549
- if (!response && "" !== response) return {
35745
+ if (!result) return {
35550
35746
  code: 414,
35551
35747
  message: "发布失败",
35552
35748
  data: ""
35553
35749
  };
35554
- task.logger?.info(`✓ 发布成功,item_id: ${response}`);
35750
+ if (needsVerification(result.decision)) {
35751
+ const decision = result.decision;
35752
+ const details = [
35753
+ decision?.verify_title,
35754
+ decision?.verify_desc
35755
+ ].filter(Boolean).join(" ");
35756
+ const message = `发布失败,需要二次验证${details ? `:${details}` : ""}`;
35757
+ task.logger?.warn(message);
35758
+ await updateTaskState?.({
35759
+ state: types_TaskState.FAILED,
35760
+ error: message,
35761
+ result: {
35762
+ data: decision
35763
+ }
35764
+ });
35765
+ await page.close();
35766
+ return {
35767
+ code: 414,
35768
+ message,
35769
+ data: ""
35770
+ };
35771
+ }
35772
+ task.logger?.info(`✓ 发布成功,item_id: ${result.itemId}`);
35555
35773
  await updateTaskState?.({
35556
35774
  state: types_TaskState.SUCCESS,
35557
35775
  result: {
35558
- response
35776
+ response: result.itemId
35559
35777
  }
35560
35778
  });
35561
35779
  await page.close();
35562
- return success(response);
35780
+ return success(result.itemId);
35563
35781
  };
35564
35782
  const DouyinPublishParamsSchema = ActionCommonParamsSchema.extend({
35565
35783
  title: classic_schemas_string(),
@@ -36339,26 +36557,26 @@ var __webpack_exports__ = {};
36339
36557
  const http = new Http({
36340
36558
  headers: {
36341
36559
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
36342
- referer: "https://mp.toutiao.com/profile_v4/graphic/publish"
36560
+ referer: "https://mp.toutiao.com/profile_v4/graphic/publish",
36561
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
36562
+ }
36563
+ });
36564
+ const totalData = await http.api({
36565
+ method: "get",
36566
+ url: "https://mp.toutiao.com/mp/fe_api/home/merge_v2",
36567
+ params: {
36568
+ app_id: 1231
36569
+ }
36570
+ });
36571
+ await new Promise((r)=>setTimeout(r, 1000));
36572
+ const contentDataYesterday = await http.api({
36573
+ method: "get",
36574
+ url: "https://mp.toutiao.com/mp/agw/statistic/v2/content_stat",
36575
+ params: {
36576
+ type: 0,
36577
+ app_id: 1231
36343
36578
  }
36344
36579
  });
36345
- const [totalData, contentDataYesterday] = await Promise.all([
36346
- http.api({
36347
- method: "get",
36348
- url: "https://mp.toutiao.com/mp/fe_api/home/merge_v2",
36349
- params: {
36350
- app_id: 1231
36351
- }
36352
- }),
36353
- http.api({
36354
- method: "get",
36355
- url: "https://mp.toutiao.com/mp/agw/statistic/v2/content_stat",
36356
- params: {
36357
- type: 0,
36358
- app_id: 1231
36359
- }
36360
- })
36361
- ]);
36362
36580
  const isSuccess = !!(totalData?.data?.statistic && contentDataYesterday?.author_stat);
36363
36581
  if (!isSuccess || !totalData?.data || !contentDataYesterday?.author_stat) return types_errorResponse(totalData?.message || contentDataYesterday?.message || "头条号数据获取失败,请检查Cookie是否有效", 414);
36364
36582
  const ttData = {
@@ -40535,8 +40753,10 @@ var __webpack_exports__ = {};
40535
40753
  tuwen_wtt_trans_flag: params.settingInfo?.toutiaoTransWtt ? "2" : "0",
40536
40754
  info_source: sourceData,
40537
40755
  ...location ? {
40538
- city: location.label,
40539
- city_code: location.value
40756
+ manual_selected_city: JSON.stringify({
40757
+ city: location.label,
40758
+ city_code: location.value
40759
+ })
40540
40760
  } : null,
40541
40761
  ...params.settingInfo?.toutiaoCollectionId ? {
40542
40762
  want_join_collection_id: params.settingInfo.toutiaoCollectionId
@@ -40586,6 +40806,12 @@ var __webpack_exports__ = {};
40586
40806
  claim_exclusive: toutiaoExclusive ? toutiaoExclusive : toutiaoOriginal?.includes("exclusive") ? 1 : 0
40587
40807
  };
40588
40808
  task._timerRecord.PrePublish = Date.now();
40809
+ task.logger.info(`[toutiaoPublish] ${"draft" === params.saveType ? "同步草稿" : "发布文章"}参数`, {
40810
+ saveType: params.saveType,
40811
+ title: params.title,
40812
+ extra: extraData,
40813
+ publishData
40814
+ });
40589
40815
  const msToken = params.cookies.find((it)=>"msToken" === it.name)?.value;
40590
40816
  let publishOption = {};
40591
40817
  if (msToken) {
@@ -41781,8 +42007,8 @@ var __webpack_exports__ = {};
41781
42007
  headers
41782
42008
  });
41783
42009
  const proxyHttp = new Http(...args);
41784
- proxyHttp.addResponseInterceptor((response)=>{
41785
- const responseData = response.data;
42010
+ const baseRespFinder = (response)=>{
42011
+ const responseData = response?.data;
41786
42012
  const msgType = "draft" === params.saveType ? "同步" : "发布";
41787
42013
  if (response && responseData?.base_resp && 0 !== responseData.base_resp.ret && !ignoreErrno.includes(responseData.base_resp.ret)) {
41788
42014
  const errmsg = weixinPublish_mock_errnoMap[responseData.base_resp.ret] || response.config.defaultErrorMsg || responseData.base_resp.err_msg || `文章${msgType}异常,请稍后重试。`;
@@ -41792,7 +42018,9 @@ var __webpack_exports__ = {};
41792
42018
  data: responseData
41793
42019
  };
41794
42020
  }
41795
- });
42021
+ };
42022
+ http.addResponseInterceptor(baseRespFinder);
42023
+ proxyHttp.addResponseInterceptor(baseRespFinder);
41796
42024
  await http.api({
41797
42025
  method: "get",
41798
42026
  url: "https://mp.weixin.qq.com/cgi-bin/appmsgpublish",