@iflyrpa/actions 4.0.0-beta.8 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bundle.js CHANGED
@@ -8733,8 +8733,12 @@ var __webpack_exports__ = {};
8733
8733
  navigator: ()=>_navigator,
8734
8734
  origin: ()=>utils_origin
8735
8735
  });
8736
- var package_namespaceObject = JSON.parse('{"i8":"1.0.0-beta.0"}');
8737
- var package_namespaceObject_0 = JSON.parse('{"i8":"4.0.0-beta.7"}');
8736
+ var package_namespaceObject = {
8737
+ i8: "0.1.2"
8738
+ };
8739
+ var package_namespaceObject_0 = {
8740
+ i8: "4.0.1"
8741
+ };
8738
8742
  const external_node_fs_namespaceObject = require("node:fs");
8739
8743
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
8740
8744
  const external_node_http_namespaceObject = require("node:http");
@@ -23366,7 +23370,8 @@ var __webpack_exports__ = {};
23366
23370
  url: error.config?.url,
23367
23371
  isProxyRequest: !!(error.config && (error.config.httpAgent || error.config.httpsAgent)),
23368
23372
  params: error.config?.params,
23369
- data: error.config?.data
23373
+ data: error.config?.data,
23374
+ serverDate: error.response?.headers?.date
23370
23375
  }
23371
23376
  };
23372
23377
  if (foundError) Object.assign(errorResponse, foundError);
@@ -23444,7 +23449,7 @@ var __webpack_exports__ = {};
23444
23449
  try {
23445
23450
  this.proxyInfo = agent ? `${agent.ip}:${agent.port}` : void 0;
23446
23451
  const controller = new AbortController();
23447
- const timeoutId = setTimeout(()=>controller.abort(), reqTimeout);
23452
+ const timeoutId = setTimeout(()=>controller.abort(), reqTimeout + 500);
23448
23453
  const response = await this.apiClient({
23449
23454
  ...config,
23450
23455
  timeout: reqTimeout,
@@ -23468,7 +23473,7 @@ var __webpack_exports__ = {};
23468
23473
  599
23469
23474
  ].includes(handledError.code);
23470
23475
  if (Rtimes < retries && isRetry) {
23471
- this.logger?.info(`进入第${Rtimes + 1}次重试!`);
23476
+ this.logger?.info(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}`);
23472
23477
  await new Promise((resolve)=>setTimeout(resolve, retryDelay));
23473
23478
  return sessionRt(Rtimes + 1);
23474
23479
  }
@@ -28653,23 +28658,26 @@ var __webpack_exports__ = {};
28653
28658
  };
28654
28659
  }
28655
28660
  case types_ExecutionState.SUCCESS:
28656
- await updateTaskState?.({
28657
- state: types_TaskState.SUCCESS,
28658
- result: {
28659
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
28660
- token,
28661
- userInfo: userInfo
28662
- }
28663
- });
28664
- return {
28665
- code: 0,
28666
- message: "成功",
28667
- data: {
28668
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
28669
- token,
28670
- userInfo
28671
- }
28672
- };
28661
+ {
28662
+ const cookie = JSON.stringify(await task.steelBrowserContext?.cookies());
28663
+ await updateTaskState?.({
28664
+ state: types_TaskState.SUCCESS,
28665
+ result: {
28666
+ cookie,
28667
+ token,
28668
+ userInfo: userInfo
28669
+ }
28670
+ });
28671
+ return {
28672
+ code: 0,
28673
+ message: "成功",
28674
+ data: {
28675
+ cookie,
28676
+ token,
28677
+ userInfo
28678
+ }
28679
+ };
28680
+ }
28673
28681
  default:
28674
28682
  return {
28675
28683
  code: 500,
@@ -28843,6 +28851,16 @@ var __webpack_exports__ = {};
28843
28851
  const images = _images.filter((url)=>!!url && "" !== url.trim());
28844
28852
  return await Promise.all(images.map(async (url)=>{
28845
28853
  const fileName = getFilenameFromUrl(url);
28854
+ const ext = external_node_path_default().extname(fileName).toLowerCase();
28855
+ if (![
28856
+ ".jpg",
28857
+ ".jpeg",
28858
+ ".png"
28859
+ ].includes(ext)) throw {
28860
+ code: 414,
28861
+ message: `图片格式不支持:${fileName}。百家号仅支持 jpg、png 格式,请转换后重试。`,
28862
+ data: ""
28863
+ };
28846
28864
  const image = await downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
28847
28865
  const formData = new (form_data_default())();
28848
28866
  formData.append("org_file_name", fileName);
@@ -29026,20 +29044,11 @@ var __webpack_exports__ = {};
29026
29044
  };
29027
29045
  const rpa_rpaAction = async (task, params)=>{
29028
29046
  const tmpCachePath = task.getTmpPath();
29029
- const commonCookies = {
29030
- path: "/",
29031
- secure: true,
29032
- domain: "baijiahao.baidu.com",
29033
- url: "https://baijiahao.baidu.com",
29034
- httpOnly: true
29035
- };
29047
+ const validCookies = (params.cookies || []).filter((it)=>it.name && it.value && "undefined" !== it.value);
29036
29048
  const page = await task.createPage({
29037
29049
  show: task.debug,
29038
29050
  url: params.url || "https://baijiahao.baidu.com/builder/rc/edit?type=news&is_from_cms=1",
29039
- cookies: params.cookies?.map((it)=>({
29040
- ...it,
29041
- ...commonCookies
29042
- })) || []
29051
+ cookies: validCookies
29043
29052
  });
29044
29053
  page.setDefaultTimeout(60000);
29045
29054
  page.setDefaultNavigationTimeout(60000);
@@ -29444,6 +29453,7 @@ var __webpack_exports__ = {};
29444
29453
  })
29445
29454
  });
29446
29455
  const baijiahaoPublish = async (task, params)=>{
29456
+ task.logger.info(`baijiahaoPublish actionType: ${params.actionType}`);
29447
29457
  params.content = formatSectionHtml(params.content);
29448
29458
  if ("rpa" === params.actionType) return rpa_rpaAction(task, params);
29449
29459
  if ("mockApi" === params.actionType) return mockAction(task, params);
@@ -30572,6 +30582,8 @@ var __webpack_exports__ = {};
30572
30582
  }
30573
30583
  new Xhshow();
30574
30584
  const sessionCheck_xsEncrypt = new Xhshow();
30585
+ let lastEnvLogTime = 0;
30586
+ const ENV_LOG_INTERVAL_MS = 5000;
30575
30587
  const SessionCheckResultSchema = classic_schemas_object({
30576
30588
  isValidSession: classic_schemas_boolean()
30577
30589
  });
@@ -30636,35 +30648,33 @@ var __webpack_exports__ = {};
30636
30648
  }, "微信账号有效性检测完成!");
30637
30649
  };
30638
30650
  const XhsSessionCheck = async (_task, params)=>{
30639
- const logger = _task.logger;
30640
- const startedAt = Date.now();
30651
+ const now = Date.now();
30652
+ const shouldLogEnv = now - lastEnvLogTime >= ENV_LOG_INTERVAL_MS;
30653
+ if (shouldLogEnv) {
30654
+ lastEnvLogTime = now;
30655
+ _task.logger?.debug("[XhsSessionCheck] 环境信息", {
30656
+ processType: process.type,
30657
+ pid: process.pid,
30658
+ nodeVersion: process.version,
30659
+ platform: process.platform,
30660
+ memoryUsage: {
30661
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
30662
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
30663
+ },
30664
+ accountId: params.accountId,
30665
+ hasProxy: !!(params.proxyLoc || params.localIP)
30666
+ });
30667
+ }
30641
30668
  const check = {
30642
30669
  isValidSession: false,
30643
30670
  isValidWebSession: false
30644
30671
  };
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
- });
30656
30672
  const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
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
- }
30673
+ if (!a1Cookie) return {
30674
+ code: 414,
30675
+ message: "账号数据异常,请重新绑定账号后重试。",
30676
+ data: check
30677
+ };
30668
30678
  const headers = {
30669
30679
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
30670
30680
  referer: "https://creator.xiaohongshu.com/new/home?source=official"
@@ -30691,7 +30701,31 @@ var __webpack_exports__ = {};
30691
30701
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
30692
30702
  return acc;
30693
30703
  }, {});
30694
- const loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
30704
+ let loginBaseXsHeader;
30705
+ try {
30706
+ loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
30707
+ } catch (signError) {
30708
+ _task.logger?.error("[XhsSessionCheck] 签名生成失败 - 环境快照", {
30709
+ accountId: params.accountId,
30710
+ error: signError instanceof Error ? signError.message : String(signError),
30711
+ stack: _task.debug ? signError instanceof Error ? signError.stack : void 0 : void 0,
30712
+ hasA1: !!recordCookie.a1,
30713
+ env: {
30714
+ processType: process.type,
30715
+ memoryUsage: {
30716
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
30717
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
30718
+ },
30719
+ hasProxy: !!(params.proxyLoc || params.localIP),
30720
+ timeSinceLastLog: Date.now() - lastEnvLogTime
30721
+ }
30722
+ });
30723
+ return {
30724
+ code: 500,
30725
+ message: "账号签名生成失败,请稍后重试。",
30726
+ data: check
30727
+ };
30728
+ }
30695
30729
  const baseInfoStart = Date.now();
30696
30730
  const _baseInfo = http.api({
30697
30731
  method: "get",
@@ -30701,75 +30735,44 @@ var __webpack_exports__ = {};
30701
30735
  }, {
30702
30736
  retries: 3,
30703
30737
  retryDelay: 20,
30704
- timeout: 3000
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;
30738
+ timeout: 5000
30714
30739
  }).catch((e)=>{
30715
- logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
30740
+ const clientTimestamp = Date.now();
30741
+ const serverDate = e?.extra?.serverDate;
30742
+ const serverTimestamp = serverDate ? new Date(serverDate).getTime() : null;
30743
+ const timeDriftMs = serverTimestamp ? clientTimestamp - serverTimestamp : null;
30744
+ _task.logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
30716
30745
  accountId: params.accountId,
30717
30746
  duration: Date.now() - baseInfoStart,
30718
30747
  code: e?.code,
30719
30748
  message: e?.message,
30720
30749
  data: e?.data,
30721
30750
  extra: e?.extra,
30722
- proxyInfo: http.proxyInfo
30751
+ proxyInfo: http.proxyInfo,
30752
+ clientTimestamp,
30753
+ serverDate,
30754
+ serverTimestamp,
30755
+ timeDriftMs,
30756
+ isLikelyClockDrift: null !== timeDriftMs && Math.abs(timeDriftMs) > 300000
30723
30757
  });
30724
30758
  return e.data;
30725
30759
  });
30726
- const webSessionStart = Date.now();
30727
30760
  const _web_session = http.api({
30728
30761
  method: "get",
30729
30762
  url: "https://edith.xiaohongshu.com/api/sns/web/unread_count"
30730
30763
  }, {
30731
30764
  retries: 3,
30732
30765
  retryDelay: 20,
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;
30766
+ timeout: 5000
30754
30767
  });
30755
30768
  const [baseInfo, web_session] = await Promise.all([
30756
30769
  _baseInfo,
30757
30770
  _web_session
30758
30771
  ]);
30759
30772
  if (baseInfo?.code === 0) check.isValidSession = true;
30760
- if (0 === web_session.code) check.isValidWebSession = true;
30761
- const _isSuccess = baseInfo?.code === web_session.code;
30773
+ if (web_session?.code === 0) check.isValidWebSession = true;
30774
+ baseInfo?.code, web_session?.code;
30762
30775
  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
- });
30773
30776
  return success(check, message);
30774
30777
  };
30775
30778
  const BjhSessionCheck = async (_task, params)=>{
@@ -34704,9 +34707,7 @@ var __webpack_exports__ = {};
34704
34707
  msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
34705
34708
  a_bogus: ""
34706
34709
  };
34707
- task.logger.warn("publishParams", {
34708
- publishParams
34709
- });
34710
+ task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
34710
34711
  const publishData = {
34711
34712
  item: {
34712
34713
  common: {
@@ -34782,21 +34783,21 @@ var __webpack_exports__ = {};
34782
34783
  }
34783
34784
  publishData.item.common.creation_id = generateRandomString(8) + Date.now();
34784
34785
  let decision = null;
34785
- task.logger.info(`proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
34786
+ task.logger.info(`[douyinPublish] proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
34786
34787
  proxyHttp.addResponseInterceptor((response)=>{
34787
34788
  console.log("拦截器收到响应:", JSON.stringify(response.data));
34788
- task.logger.info(`拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
34789
- task.logger.info(`拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
34789
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
34790
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
34790
34791
  decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
34791
34792
  if (needsVerification(decision)) {
34792
- task.logger.info(`需要验证: ${JSON.stringify(decision)}`);
34793
+ task.logger.warn(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
34793
34794
  return;
34794
34795
  }
34795
34796
  if (!response || !response.data) return;
34796
34797
  const responseData = response.data;
34797
34798
  if (response && responseData?.status_code && 0 !== responseData.status_code) {
34798
34799
  const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
34799
- if (4 === responseData.status_code) task.logger.warn(`抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
34800
+ if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
34800
34801
  return {
34801
34802
  code: errorCode,
34802
34803
  message: responseData.status_msg || "文章发布异常,请稍后重试。",
@@ -34816,42 +34817,120 @@ var __webpack_exports__ = {};
34816
34817
  });
34817
34818
  return utils_response(0, message, data);
34818
34819
  }
34819
- const webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
34820
- const ticket = webProtectData.ticket;
34821
- const ts_sign = webProtectData.ts_sign;
34822
- const ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
34823
- const certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
34820
+ let webProtectData;
34821
+ try {
34822
+ webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
34823
+ if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
34824
+ task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
34825
+ return utils_response(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
34826
+ }
34827
+ } catch (error) {
34828
+ task.logger.error(`解析 webProtectData 失败: ${error}`);
34829
+ return utils_response(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
34830
+ }
34831
+ let ticket = webProtectData.ticket;
34832
+ let ts_sign = webProtectData.ts_sign;
34833
+ const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
34834
+ if (serverDataCookie) try {
34835
+ const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
34836
+ if (decoded.ticket && decoded.ts_sign) {
34837
+ if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
34838
+ ticket = decoded.ticket;
34839
+ ts_sign = decoded.ts_sign;
34840
+ }
34841
+ } catch (error) {
34842
+ task.logger.warn(`解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
34843
+ }
34844
+ let ec_privateKey;
34845
+ try {
34846
+ ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
34847
+ if (!ec_privateKey) {
34848
+ task.logger.error("ec_privateKey 为空");
34849
+ return utils_response(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
34850
+ }
34851
+ } catch (error) {
34852
+ task.logger.error(`解析 ec_privateKey 失败: ${error}`);
34853
+ return utils_response(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
34854
+ }
34855
+ let certificate;
34856
+ try {
34857
+ certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
34858
+ if (!certificate) {
34859
+ task.logger.error("certificate 为空");
34860
+ return utils_response(414, "安全参数 certificate 缺失,请重新获取后重试", "");
34861
+ }
34862
+ } catch (error) {
34863
+ task.logger.error(`解析 certificate 失败: ${error}`);
34864
+ return utils_response(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
34865
+ }
34824
34866
  const ree_public_key = webProtectData.client_cert.replace("pub.", "");
34825
- task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket}, ts_sign: ${ts_sign}, ec_privateKey: ${ec_privateKey}, certificate: ${certificate}, ree_public_key: ${ree_public_key}`);
34826
- const bdTicketGuardClientData = getBdV2({
34827
- ticket,
34828
- ts_sign: ts_sign,
34829
- ec_privateKey: ec_privateKey,
34830
- certificate: certificate,
34831
- bd_ticket_guard_ree_public_key: ree_public_key
34832
- });
34833
- task.logger.info("bdTicketGuardClientData", {
34834
- bdTicketGuardClientData
34835
- });
34867
+ task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket?.substring(0, 20)}..., ts_sign: ${ts_sign}, ree_public_key: ${ree_public_key?.substring(0, 20)}...`);
34868
+ let bdTicketGuardClientData;
34869
+ try {
34870
+ bdTicketGuardClientData = getBdV2({
34871
+ ticket,
34872
+ ts_sign: ts_sign,
34873
+ ec_privateKey: ec_privateKey,
34874
+ certificate: certificate,
34875
+ bd_ticket_guard_ree_public_key: ree_public_key
34876
+ });
34877
+ if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
34878
+ task.logger.error(`bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
34879
+ return utils_response(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
34880
+ }
34881
+ } catch (error) {
34882
+ task.logger.error(`生成 bdTicketGuardClientData 失败: ${error}`);
34883
+ return utils_response(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
34884
+ }
34885
+ task.logger.info("bdTicketGuardClientData 生成成功");
34836
34886
  const publishQuery = {
34837
34887
  ...publishParams,
34838
34888
  a_bogus: ""
34839
34889
  };
34840
34890
  const queryString = new URLSearchParams(publishQuery).toString();
34841
- const aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
34891
+ let aBogus;
34892
+ try {
34893
+ aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
34894
+ if (!aBogus || aBogus.length < 10) {
34895
+ task.logger.error(`a_bogus 生成异常,长度过短: ${aBogus}`);
34896
+ return utils_response(414, "安全参数 a_bogus 生成失败,请重试", "");
34897
+ }
34898
+ task.logger.info(`a_bogus 生成成功: ${aBogus.substring(0, 20)}...`);
34899
+ } catch (error) {
34900
+ task.logger.error(`生成 a_bogus 失败: ${error}`);
34901
+ return utils_response(414, "安全参数 a_bogus 生成异常,请重试", "");
34902
+ }
34842
34903
  publishQuery.a_bogus = aBogus;
34843
34904
  const publishQueryParams = new URLSearchParams(publishQuery).toString();
34844
- const csrfToken = mock_generateCsrfTokenAdvanced({
34845
- cookies: params.cookies,
34846
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
34847
- method: "POST",
34848
- userAgent
34849
- });
34850
- const sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
34851
- task.logger.info("发布数据", {
34905
+ let csrfToken;
34906
+ try {
34907
+ csrfToken = mock_generateCsrfTokenAdvanced({
34908
+ cookies: params.cookies,
34909
+ url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
34910
+ method: "POST",
34911
+ userAgent
34912
+ });
34913
+ if (!csrfToken || csrfToken.length < 10) {
34914
+ task.logger.error(`csrfToken 生成异常,长度过短: ${csrfToken}`);
34915
+ return utils_response(414, "安全参数 csrfToken 生成失败,请重试", "");
34916
+ }
34917
+ task.logger.info(`csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
34918
+ } catch (error) {
34919
+ task.logger.error(`生成 csrfToken 失败: ${error}`);
34920
+ return utils_response(414, "安全参数 csrfToken 生成异常,请重试", "");
34921
+ }
34922
+ let sessionDtrait;
34923
+ try {
34924
+ sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
34925
+ task.logger.info(`sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
34926
+ } catch (error) {
34927
+ task.logger.error(`生成 sessionDtrait 失败: ${error}`);
34928
+ return utils_response(414, "安全参数 sessionDtrait 生成异常,请重试", "");
34929
+ }
34930
+ task.logger.info("[douyinPublish] 发布数据", {
34852
34931
  data: JSON.stringify(publishData)
34853
34932
  });
34854
- task.logger.info(`headers: ${JSON.stringify({
34933
+ task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
34855
34934
  ...headers,
34856
34935
  Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
34857
34936
  "Content-Type": "application/json",
@@ -34864,8 +34943,7 @@ var __webpack_exports__ = {};
34864
34943
  "x-secsdk-csrf-token": csrfToken,
34865
34944
  "x-tt-session-dtrait": sessionDtrait || ""
34866
34945
  })}`);
34867
- task.logger.info(`publishData: ${JSON.stringify(publishData)}`);
34868
- task.logger.info(`url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
34946
+ task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
34869
34947
  const publishResult = await proxyHttp.api({
34870
34948
  method: "post",
34871
34949
  url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
@@ -34889,8 +34967,7 @@ var __webpack_exports__ = {};
34889
34967
  retries: 3,
34890
34968
  retryDelay: 2000
34891
34969
  });
34892
- task.logger.info("========== api调用完成 ==========");
34893
- task.logger.info(`decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
34970
+ task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
34894
34971
  if (needsVerification(decision)) {
34895
34972
  const details = [
34896
34973
  publishResult.status_msg,
@@ -34898,7 +34975,6 @@ var __webpack_exports__ = {};
34898
34975
  decision?.verify_desc
34899
34976
  ].filter(Boolean).join(" ");
34900
34977
  const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
34901
- task.logger.warn(`TaskId:${task.taskId},检测到需要验证,准备返回验证信息`);
34902
34978
  let decisionObj = {};
34903
34979
  if (decision) decisionObj = decision;
34904
34980
  const mockData = {
@@ -34917,7 +34993,6 @@ var __webpack_exports__ = {};
34917
34993
  message: "操作成功"
34918
34994
  };
34919
34995
  }
34920
- task.logger.info("不需要验证,继续正常流程");
34921
34996
  reportLogger({
34922
34997
  token: params.huiwenToken || "",
34923
34998
  enverionment: task.enverionment || "development",
@@ -34929,8 +35004,7 @@ var __webpack_exports__ = {};
34929
35004
  platform: "douyin",
34930
35005
  publishParams: publishData
34931
35006
  });
34932
- task.logger.warn("发布结果");
34933
- task.logger.warn(JSON.stringify(publishResult));
35007
+ task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
34934
35008
  const isSuccess = 0 === publishResult.status_code;
34935
35009
  const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
34936
35010
  const data = isSuccess ? publishResult.item_id || "" : "";
@@ -35771,6 +35845,7 @@ var __webpack_exports__ = {};
35771
35845
  uploadedImgList: classic_schemas_string().optional()
35772
35846
  });
35773
35847
  const douyinPublish = async (task, params)=>{
35848
+ task.logger.info(`douyinPublish actionType: ${params.actionType}`);
35774
35849
  if ("rpa" === params.actionType) return douyinPublish_rpa_rpaAction(task, params);
35775
35850
  if ("mockApi" === params.actionType) return mock_mockAction(task, params);
35776
35851
  if ("server" === params.actionType) return rpaAction_Server(task, params);
@@ -40060,7 +40135,7 @@ var __webpack_exports__ = {};
40060
40135
  ]).optional()
40061
40136
  });
40062
40137
  const shipinhaoPublish = async (task, params)=>{
40063
- console.log("shipinhaoPublish params:", params);
40138
+ task.logger.info(`shipinhaoPublish actionType: ${params.actionType}`);
40064
40139
  if ("rpa" === params.actionType) return shipinhaoPublish_rpa_rpaAction(task, params);
40065
40140
  if ("mockApi" === params.actionType) return shipinhaoPublish_mock_mockAction(task, params);
40066
40141
  if ("server" === params.actionType) return rpa_server_rpaAction_Server(task, params);
@@ -41118,6 +41193,7 @@ var __webpack_exports__ = {};
41118
41193
  };
41119
41194
  const getAddTypeValue = (toutiaoAd)=>"yes" === toutiaoAd ? 3 : 2;
41120
41195
  const toutiaoPublish = async (task, params)=>{
41196
+ task.logger.info(`toutiaoPublish actionType: ${params.actionType}`);
41121
41197
  params.content = formatSectionHtml(params.content);
41122
41198
  if ("rpa" === params.actionType) return toutiaoPublish_rpa_rpaAction(task, params);
41123
41199
  if ("mockApi" === params.actionType) return toutiaoPublish_mock_mockAction(task, params);
@@ -43454,6 +43530,33 @@ var __webpack_exports__ = {};
43454
43530
  const encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
43455
43531
  const xiaohongshuLogin_rpa_server_scanRetryMaxCount = 60;
43456
43532
  const xiaohongshuLogin_rpa_server_waitQrcodeResultMaxTime = 2000 * xiaohongshuLogin_rpa_server_scanRetryMaxCount;
43533
+ async function collectCookiesWithA1(task) {
43534
+ const hasA1 = (cookies)=>cookies.some((c)=>"a1" === c.name && !!c.value);
43535
+ let cookies = await task.steelBrowserContext?.cookies() ?? [];
43536
+ if (hasA1(cookies)) return cookies;
43537
+ task.logger?.warn("[XhsLogin] 首次抓取缺失 a1,尝试补救……");
43538
+ try {
43539
+ const page = task.steelBrowserContext?.pages?.()[0];
43540
+ if (page) {
43541
+ await page.goto("https://www.xiaohongshu.com", {
43542
+ waitUntil: "domcontentloaded",
43543
+ timeout: 15000
43544
+ });
43545
+ for(let i = 0; i < 10; i++){
43546
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
43547
+ if (hasA1(cookies)) {
43548
+ task.logger?.info(`[XhsLogin] a1 补救成功,第 ${i + 1} 次轮询命中`);
43549
+ return cookies;
43550
+ }
43551
+ await new Promise((resolve)=>setTimeout(resolve, 500));
43552
+ }
43553
+ }
43554
+ } catch (err) {
43555
+ task.logger?.warn("[XhsLogin] a1 补救访问主站失败", err);
43556
+ }
43557
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
43558
+ return cookies;
43559
+ }
43457
43560
  const xiaohongshuLogin_rpa_server_rpaServer = async (task, params)=>{
43458
43561
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
43459
43562
  const reporter = task.reportService?.reportLoginStatus ?? (()=>Promise.resolve());
@@ -43654,21 +43757,29 @@ var __webpack_exports__ = {};
43654
43757
  };
43655
43758
  }
43656
43759
  case types_ExecutionState.SUCCESS:
43657
- await updateTaskState?.({
43658
- state: types_TaskState.SUCCESS,
43659
- result: {
43660
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
43661
- userInfo: userInfo
43662
- }
43663
- });
43664
- return {
43665
- code: 0,
43666
- message: "成功",
43667
- data: {
43668
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
43669
- userInfo
43670
- }
43671
- };
43760
+ {
43761
+ const cookies = await collectCookiesWithA1(task);
43762
+ const hasA1 = cookies.some((c)=>"a1" === c.name && !!c.value);
43763
+ if (!hasA1) task.logger?.warn("[XhsLogin] 登录成功但缺失关键 cookie a1,后续检测可能失败", {
43764
+ cookieNames: cookies.map((c)=>c.name)
43765
+ });
43766
+ const cookieStr = JSON.stringify(cookies);
43767
+ await updateTaskState?.({
43768
+ state: types_TaskState.SUCCESS,
43769
+ result: {
43770
+ cookie: cookieStr,
43771
+ userInfo: userInfo
43772
+ }
43773
+ });
43774
+ return {
43775
+ code: 0,
43776
+ message: "成功",
43777
+ data: {
43778
+ cookie: cookieStr,
43779
+ userInfo
43780
+ }
43781
+ };
43782
+ }
43672
43783
  default:
43673
43784
  return {
43674
43785
  code: 500,
@@ -43869,6 +43980,24 @@ var __webpack_exports__ = {};
43869
43980
  const fileName = getFilenameFromUrl(url);
43870
43981
  const localUrl = await downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
43871
43982
  const fileBuffer = external_node_fs_default().readFileSync(localUrl);
43983
+ let width = 0;
43984
+ let height = 0;
43985
+ try {
43986
+ const dimensions = imageSize(fileBuffer);
43987
+ width = dimensions.width ?? 0;
43988
+ height = dimensions.height ?? 0;
43989
+ const orientation = dimensions.orientation ?? 1;
43990
+ if ([
43991
+ 5,
43992
+ 6,
43993
+ 7,
43994
+ 8
43995
+ ].includes(orientation)) [width, height] = [
43996
+ height,
43997
+ width
43998
+ ];
43999
+ } catch {}
44000
+ const originSize = fileBuffer.byteLength / 1024;
43872
44001
  const MAX_RETRIES = uploadInfos.length;
43873
44002
  let attempt = 0;
43874
44003
  while(attempt < MAX_RETRIES){
@@ -43890,7 +44019,10 @@ var __webpack_exports__ = {};
43890
44019
  });
43891
44020
  return {
43892
44021
  ossFileId,
43893
- ossToken
44022
+ ossToken,
44023
+ width,
44024
+ height,
44025
+ originSize
43894
44026
  };
43895
44027
  } catch (error) {
43896
44028
  attempt++;
@@ -43898,7 +44030,10 @@ var __webpack_exports__ = {};
43898
44030
  }
43899
44031
  return {
43900
44032
  ossFileId: "",
43901
- ossToken: ""
44033
+ ossToken: "",
44034
+ width,
44035
+ height,
44036
+ originSize
43902
44037
  };
43903
44038
  };
43904
44039
  const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
@@ -43963,8 +44098,16 @@ var __webpack_exports__ = {};
43963
44098
  },
43964
44099
  image_info: {
43965
44100
  images: coverInfos.map((it)=>({
43966
- extra_info_json: '{"mimeType":"image/png"}',
44101
+ extra_info_json: JSON.stringify({
44102
+ mimeType: "image/png",
44103
+ image_metadata: {
44104
+ bg_color: "",
44105
+ origin_size: it.originSize
44106
+ }
44107
+ }),
43967
44108
  file_id: it.ossFileId,
44109
+ width: it.width,
44110
+ height: it.height,
43968
44111
  metadata: {
43969
44112
  source: -1
43970
44113
  },
@@ -44071,6 +44214,7 @@ var __webpack_exports__ = {};
44071
44214
  });
44072
44215
  return success(data, message);
44073
44216
  }
44217
+ task.logger.info(`[xiaohongshuPublish] publishData: ${JSON.stringify(publishData)} `);
44074
44218
  const publishResult = await proxyHttp.api({
44075
44219
  method: "post",
44076
44220
  url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
@@ -45180,6 +45324,7 @@ var __webpack_exports__ = {};
45180
45324
  originalBind: classic_schemas_boolean().optional()
45181
45325
  });
45182
45326
  const xiaohongshuPublish = async (task, params)=>{
45327
+ task.logger.info(`xiaohongshuPublish actionType: ${params.actionType}`);
45183
45328
  if (DisabledReq) return {
45184
45329
  code: 414,
45185
45330
  data: "",