@iflyrpa/actions 4.0.0-beta.6 → 4.0.0

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
@@ -5489,7 +5489,9 @@ var __webpack_exports__ = {};
5489
5489
  });
5490
5490
  const package_json_namespaceObject = require("@iflyrpa/share/package.json");
5491
5491
  var package_json_default = /*#__PURE__*/ __webpack_require__.n(package_json_namespaceObject);
5492
- var package_namespaceObject = JSON.parse('{"i8":"4.0.0-beta.5"}');
5492
+ var package_namespaceObject = {
5493
+ i8: "3.1.1"
5494
+ };
5493
5495
  const share_namespaceObject = require("@iflyrpa/share");
5494
5496
  const external_node_fs_namespaceObject = require("node:fs");
5495
5497
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
@@ -5590,7 +5592,8 @@ var __webpack_exports__ = {};
5590
5592
  url: error.config?.url,
5591
5593
  isProxyRequest: !!(error.config && (error.config.httpAgent || error.config.httpsAgent)),
5592
5594
  params: error.config?.params,
5593
- data: error.config?.data
5595
+ data: error.config?.data,
5596
+ serverDate: error.response?.headers?.date
5594
5597
  }
5595
5598
  };
5596
5599
  if (foundError) Object.assign(errorResponse, foundError);
@@ -5668,7 +5671,7 @@ var __webpack_exports__ = {};
5668
5671
  try {
5669
5672
  this.proxyInfo = agent ? `${agent.ip}:${agent.port}` : void 0;
5670
5673
  const controller = new AbortController();
5671
- const timeoutId = setTimeout(()=>controller.abort(), reqTimeout);
5674
+ const timeoutId = setTimeout(()=>controller.abort(), reqTimeout + 500);
5672
5675
  const response = await this.apiClient({
5673
5676
  ...config,
5674
5677
  timeout: reqTimeout,
@@ -5692,7 +5695,7 @@ var __webpack_exports__ = {};
5692
5695
  599
5693
5696
  ].includes(handledError.code);
5694
5697
  if (Rtimes < retries && isRetry) {
5695
- this.logger?.info(`进入第${Rtimes + 1}次重试!`);
5698
+ this.logger?.info(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}`);
5696
5699
  await new Promise((resolve)=>setTimeout(resolve, retryDelay));
5697
5700
  return sessionRt(Rtimes + 1);
5698
5701
  }
@@ -9909,23 +9912,26 @@ var __webpack_exports__ = {};
9909
9912
  };
9910
9913
  }
9911
9914
  case types_ExecutionState.SUCCESS:
9912
- await updateTaskState?.({
9913
- state: share_namespaceObject.TaskState.SUCCESS,
9914
- result: {
9915
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
9916
- token,
9917
- userInfo: userInfo
9918
- }
9919
- });
9920
- return {
9921
- code: 0,
9922
- message: "成功",
9923
- data: {
9924
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
9925
- token,
9926
- userInfo
9927
- }
9928
- };
9915
+ {
9916
+ const cookie = JSON.stringify(await task.steelBrowserContext?.cookies());
9917
+ await updateTaskState?.({
9918
+ state: share_namespaceObject.TaskState.SUCCESS,
9919
+ result: {
9920
+ cookie,
9921
+ token,
9922
+ userInfo: userInfo
9923
+ }
9924
+ });
9925
+ return {
9926
+ code: 0,
9927
+ message: "成功",
9928
+ data: {
9929
+ cookie,
9930
+ token,
9931
+ userInfo
9932
+ }
9933
+ };
9934
+ }
9929
9935
  default:
9930
9936
  return {
9931
9937
  code: 500,
@@ -10101,6 +10107,16 @@ var __webpack_exports__ = {};
10101
10107
  const images = _images.filter((url)=>!!url && "" !== url.trim());
10102
10108
  return await Promise.all(images.map(async (url)=>{
10103
10109
  const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
10110
+ const ext = external_node_path_default().extname(fileName).toLowerCase();
10111
+ if (![
10112
+ ".jpg",
10113
+ ".jpeg",
10114
+ ".png"
10115
+ ].includes(ext)) throw {
10116
+ code: 414,
10117
+ message: `图片格式不支持:${fileName}。百家号仅支持 jpg、png 格式,请转换后重试。`,
10118
+ data: ""
10119
+ };
10104
10120
  const image = await (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
10105
10121
  const formData = new (external_form_data_default())();
10106
10122
  formData.append("org_file_name", fileName);
@@ -10284,20 +10300,11 @@ var __webpack_exports__ = {};
10284
10300
  };
10285
10301
  const rpa_rpaAction = async (task, params)=>{
10286
10302
  const tmpCachePath = task.getTmpPath();
10287
- const commonCookies = {
10288
- path: "/",
10289
- secure: true,
10290
- domain: "baijiahao.baidu.com",
10291
- url: "https://baijiahao.baidu.com",
10292
- httpOnly: true
10293
- };
10303
+ const validCookies = (params.cookies || []).filter((it)=>it.name && it.value && "undefined" !== it.value);
10294
10304
  const page = await task.createPage({
10295
10305
  show: task.debug,
10296
10306
  url: params.url || "https://baijiahao.baidu.com/builder/rc/edit?type=news&is_from_cms=1",
10297
- cookies: params.cookies?.map((it)=>({
10298
- ...it,
10299
- ...commonCookies
10300
- })) || []
10307
+ cookies: validCookies
10301
10308
  });
10302
10309
  page.setDefaultTimeout(60000);
10303
10310
  page.setDefaultNavigationTimeout(60000);
@@ -10702,6 +10709,7 @@ var __webpack_exports__ = {};
10702
10709
  })
10703
10710
  });
10704
10711
  const baijiahaoPublish = async (task, params)=>{
10712
+ task.logger.info(`baijiahaoPublish actionType: ${params.actionType}`);
10705
10713
  params.content = formatSectionHtml(params.content);
10706
10714
  if ("rpa" === params.actionType) return rpa_rpaAction(task, params);
10707
10715
  if ("mockApi" === params.actionType) return mockAction(task, params);
@@ -11832,6 +11840,8 @@ var __webpack_exports__ = {};
11832
11840
  }
11833
11841
  new Xhshow();
11834
11842
  const sessionCheck_xsEncrypt = new Xhshow();
11843
+ let lastEnvLogTime = 0;
11844
+ const ENV_LOG_INTERVAL_MS = 5000;
11835
11845
  const SessionCheckResultSchema = schemas_object({
11836
11846
  isValidSession: schemas_boolean()
11837
11847
  });
@@ -11896,6 +11906,23 @@ var __webpack_exports__ = {};
11896
11906
  }, "微信账号有效性检测完成!");
11897
11907
  };
11898
11908
  const XhsSessionCheck = async (_task, params)=>{
11909
+ const now = Date.now();
11910
+ const shouldLogEnv = now - lastEnvLogTime >= ENV_LOG_INTERVAL_MS;
11911
+ if (shouldLogEnv) {
11912
+ lastEnvLogTime = now;
11913
+ _task.logger?.debug("[XhsSessionCheck] 环境信息", {
11914
+ processType: process.type,
11915
+ pid: process.pid,
11916
+ nodeVersion: process.version,
11917
+ platform: process.platform,
11918
+ memoryUsage: {
11919
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
11920
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
11921
+ },
11922
+ accountId: params.accountId,
11923
+ hasProxy: !!(params.proxyLoc || params.localIP)
11924
+ });
11925
+ }
11899
11926
  const check = {
11900
11927
  isValidSession: false,
11901
11928
  isValidWebSession: false
@@ -11932,7 +11959,32 @@ var __webpack_exports__ = {};
11932
11959
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
11933
11960
  return acc;
11934
11961
  }, {});
11935
- const loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
11962
+ let loginBaseXsHeader;
11963
+ try {
11964
+ loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
11965
+ } catch (signError) {
11966
+ _task.logger?.error("[XhsSessionCheck] 签名生成失败 - 环境快照", {
11967
+ accountId: params.accountId,
11968
+ error: signError instanceof Error ? signError.message : String(signError),
11969
+ stack: _task.debug ? signError instanceof Error ? signError.stack : void 0 : void 0,
11970
+ hasA1: !!recordCookie.a1,
11971
+ env: {
11972
+ processType: process.type,
11973
+ memoryUsage: {
11974
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
11975
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
11976
+ },
11977
+ hasProxy: !!(params.proxyLoc || params.localIP),
11978
+ timeSinceLastLog: Date.now() - lastEnvLogTime
11979
+ }
11980
+ });
11981
+ return {
11982
+ code: 500,
11983
+ message: "账号签名生成失败,请稍后重试。",
11984
+ data: check
11985
+ };
11986
+ }
11987
+ const baseInfoStart = Date.now();
11936
11988
  const _baseInfo = http.api({
11937
11989
  method: "get",
11938
11990
  baseURL: "https://creator.xiaohongshu.com",
@@ -11941,23 +11993,43 @@ var __webpack_exports__ = {};
11941
11993
  }, {
11942
11994
  retries: 3,
11943
11995
  retryDelay: 20,
11944
- timeout: 3000
11945
- }).catch((e)=>e.data);
11996
+ timeout: 5000
11997
+ }).catch((e)=>{
11998
+ const clientTimestamp = Date.now();
11999
+ const serverDate = e?.extra?.serverDate;
12000
+ const serverTimestamp = serverDate ? new Date(serverDate).getTime() : null;
12001
+ const timeDriftMs = serverTimestamp ? clientTimestamp - serverTimestamp : null;
12002
+ _task.logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
12003
+ accountId: params.accountId,
12004
+ duration: Date.now() - baseInfoStart,
12005
+ code: e?.code,
12006
+ message: e?.message,
12007
+ data: e?.data,
12008
+ extra: e?.extra,
12009
+ proxyInfo: http.proxyInfo,
12010
+ clientTimestamp,
12011
+ serverDate,
12012
+ serverTimestamp,
12013
+ timeDriftMs,
12014
+ isLikelyClockDrift: null !== timeDriftMs && Math.abs(timeDriftMs) > 300000
12015
+ });
12016
+ return e.data;
12017
+ });
11946
12018
  const _web_session = http.api({
11947
12019
  method: "get",
11948
12020
  url: "https://edith.xiaohongshu.com/api/sns/web/unread_count"
11949
12021
  }, {
11950
12022
  retries: 3,
11951
12023
  retryDelay: 20,
11952
- timeout: 3000
12024
+ timeout: 5000
11953
12025
  });
11954
12026
  const [baseInfo, web_session] = await Promise.all([
11955
12027
  _baseInfo,
11956
12028
  _web_session
11957
12029
  ]);
11958
12030
  if (baseInfo?.code === 0) check.isValidSession = true;
11959
- if (0 === web_session.code) check.isValidWebSession = true;
11960
- baseInfo?.code, web_session.code;
12031
+ if (web_session?.code === 0) check.isValidWebSession = true;
12032
+ baseInfo?.code, web_session?.code;
11961
12033
  const message = `小红书账号有效性检测成功${_task.debug ? ` ${http.proxyInfo}` : ""}`;
11962
12034
  return (0, share_namespaceObject.success)(check, message);
11963
12035
  };
@@ -14407,9 +14479,7 @@ var __webpack_exports__ = {};
14407
14479
  msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
14408
14480
  a_bogus: ""
14409
14481
  };
14410
- task.logger.warn("publishParams", {
14411
- publishParams
14412
- });
14482
+ task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
14413
14483
  const publishData = {
14414
14484
  item: {
14415
14485
  common: {
@@ -14485,21 +14555,21 @@ var __webpack_exports__ = {};
14485
14555
  }
14486
14556
  publishData.item.common.creation_id = generateRandomString(8) + Date.now();
14487
14557
  let decision = null;
14488
- task.logger.info(`proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
14558
+ task.logger.info(`[douyinPublish] proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
14489
14559
  proxyHttp.addResponseInterceptor((response)=>{
14490
14560
  console.log("拦截器收到响应:", JSON.stringify(response.data));
14491
- task.logger.info(`拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
14492
- task.logger.info(`拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
14561
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
14562
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
14493
14563
  decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
14494
14564
  if (needsVerification(decision)) {
14495
- task.logger.info(`需要验证: ${JSON.stringify(decision)}`);
14565
+ task.logger.warn(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
14496
14566
  return;
14497
14567
  }
14498
14568
  if (!response || !response.data) return;
14499
14569
  const responseData = response.data;
14500
14570
  if (response && responseData?.status_code && 0 !== responseData.status_code) {
14501
14571
  const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
14502
- if (4 === responseData.status_code) task.logger.warn(`抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
14572
+ if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
14503
14573
  return {
14504
14574
  code: errorCode,
14505
14575
  message: responseData.status_msg || "文章发布异常,请稍后重试。",
@@ -14519,42 +14589,120 @@ var __webpack_exports__ = {};
14519
14589
  });
14520
14590
  return (0, share_namespaceObject.response)(0, message, data);
14521
14591
  }
14522
- const webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
14523
- const ticket = webProtectData.ticket;
14524
- const ts_sign = webProtectData.ts_sign;
14525
- const ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
14526
- const certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
14592
+ let webProtectData;
14593
+ try {
14594
+ webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
14595
+ if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
14596
+ task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
14597
+ return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
14598
+ }
14599
+ } catch (error) {
14600
+ task.logger.error(`解析 webProtectData 失败: ${error}`);
14601
+ return (0, share_namespaceObject.response)(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
14602
+ }
14603
+ let ticket = webProtectData.ticket;
14604
+ let ts_sign = webProtectData.ts_sign;
14605
+ const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
14606
+ if (serverDataCookie) try {
14607
+ const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
14608
+ if (decoded.ticket && decoded.ts_sign) {
14609
+ if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
14610
+ ticket = decoded.ticket;
14611
+ ts_sign = decoded.ts_sign;
14612
+ }
14613
+ } catch (error) {
14614
+ task.logger.warn(`解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
14615
+ }
14616
+ let ec_privateKey;
14617
+ try {
14618
+ ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
14619
+ if (!ec_privateKey) {
14620
+ task.logger.error("ec_privateKey 为空");
14621
+ return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
14622
+ }
14623
+ } catch (error) {
14624
+ task.logger.error(`解析 ec_privateKey 失败: ${error}`);
14625
+ return (0, share_namespaceObject.response)(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
14626
+ }
14627
+ let certificate;
14628
+ try {
14629
+ certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
14630
+ if (!certificate) {
14631
+ task.logger.error("certificate 为空");
14632
+ return (0, share_namespaceObject.response)(414, "安全参数 certificate 缺失,请重新获取后重试", "");
14633
+ }
14634
+ } catch (error) {
14635
+ task.logger.error(`解析 certificate 失败: ${error}`);
14636
+ return (0, share_namespaceObject.response)(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
14637
+ }
14527
14638
  const ree_public_key = webProtectData.client_cert.replace("pub.", "");
14528
- task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket}, ts_sign: ${ts_sign}, ec_privateKey: ${ec_privateKey}, certificate: ${certificate}, ree_public_key: ${ree_public_key}`);
14529
- const bdTicketGuardClientData = getBdV2({
14530
- ticket,
14531
- ts_sign: ts_sign,
14532
- ec_privateKey: ec_privateKey,
14533
- certificate: certificate,
14534
- bd_ticket_guard_ree_public_key: ree_public_key
14535
- });
14536
- task.logger.info("bdTicketGuardClientData", {
14537
- bdTicketGuardClientData
14538
- });
14639
+ task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket?.substring(0, 20)}..., ts_sign: ${ts_sign}, ree_public_key: ${ree_public_key?.substring(0, 20)}...`);
14640
+ let bdTicketGuardClientData;
14641
+ try {
14642
+ bdTicketGuardClientData = getBdV2({
14643
+ ticket,
14644
+ ts_sign: ts_sign,
14645
+ ec_privateKey: ec_privateKey,
14646
+ certificate: certificate,
14647
+ bd_ticket_guard_ree_public_key: ree_public_key
14648
+ });
14649
+ if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
14650
+ task.logger.error(`bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
14651
+ return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
14652
+ }
14653
+ } catch (error) {
14654
+ task.logger.error(`生成 bdTicketGuardClientData 失败: ${error}`);
14655
+ return (0, share_namespaceObject.response)(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
14656
+ }
14657
+ task.logger.info("bdTicketGuardClientData 生成成功");
14539
14658
  const publishQuery = {
14540
14659
  ...publishParams,
14541
14660
  a_bogus: ""
14542
14661
  };
14543
14662
  const queryString = new URLSearchParams(publishQuery).toString();
14544
- const aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
14663
+ let aBogus;
14664
+ try {
14665
+ aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
14666
+ if (!aBogus || aBogus.length < 10) {
14667
+ task.logger.error(`a_bogus 生成异常,长度过短: ${aBogus}`);
14668
+ return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成失败,请重试", "");
14669
+ }
14670
+ task.logger.info(`a_bogus 生成成功: ${aBogus.substring(0, 20)}...`);
14671
+ } catch (error) {
14672
+ task.logger.error(`生成 a_bogus 失败: ${error}`);
14673
+ return (0, share_namespaceObject.response)(414, "安全参数 a_bogus 生成异常,请重试", "");
14674
+ }
14545
14675
  publishQuery.a_bogus = aBogus;
14546
14676
  const publishQueryParams = new URLSearchParams(publishQuery).toString();
14547
- const csrfToken = mock_generateCsrfTokenAdvanced({
14548
- cookies: params.cookies,
14549
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
14550
- method: "POST",
14551
- userAgent
14552
- });
14553
- const sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
14554
- task.logger.info("发布数据", {
14677
+ let csrfToken;
14678
+ try {
14679
+ csrfToken = mock_generateCsrfTokenAdvanced({
14680
+ cookies: params.cookies,
14681
+ url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
14682
+ method: "POST",
14683
+ userAgent
14684
+ });
14685
+ if (!csrfToken || csrfToken.length < 10) {
14686
+ task.logger.error(`csrfToken 生成异常,长度过短: ${csrfToken}`);
14687
+ return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成失败,请重试", "");
14688
+ }
14689
+ task.logger.info(`csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
14690
+ } catch (error) {
14691
+ task.logger.error(`生成 csrfToken 失败: ${error}`);
14692
+ return (0, share_namespaceObject.response)(414, "安全参数 csrfToken 生成异常,请重试", "");
14693
+ }
14694
+ let sessionDtrait;
14695
+ try {
14696
+ sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
14697
+ task.logger.info(`sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
14698
+ } catch (error) {
14699
+ task.logger.error(`生成 sessionDtrait 失败: ${error}`);
14700
+ return (0, share_namespaceObject.response)(414, "安全参数 sessionDtrait 生成异常,请重试", "");
14701
+ }
14702
+ task.logger.info("[douyinPublish] 发布数据", {
14555
14703
  data: JSON.stringify(publishData)
14556
14704
  });
14557
- task.logger.info(`headers: ${JSON.stringify({
14705
+ task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
14558
14706
  ...headers,
14559
14707
  Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
14560
14708
  "Content-Type": "application/json",
@@ -14567,8 +14715,7 @@ var __webpack_exports__ = {};
14567
14715
  "x-secsdk-csrf-token": csrfToken,
14568
14716
  "x-tt-session-dtrait": sessionDtrait || ""
14569
14717
  })}`);
14570
- task.logger.info(`publishData: ${JSON.stringify(publishData)}`);
14571
- task.logger.info(`url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
14718
+ task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
14572
14719
  const publishResult = await proxyHttp.api({
14573
14720
  method: "post",
14574
14721
  url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
@@ -14592,8 +14739,7 @@ var __webpack_exports__ = {};
14592
14739
  retries: 3,
14593
14740
  retryDelay: 2000
14594
14741
  });
14595
- task.logger.info("========== api调用完成 ==========");
14596
- task.logger.info(`decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
14742
+ task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
14597
14743
  if (needsVerification(decision)) {
14598
14744
  const details = [
14599
14745
  publishResult.status_msg,
@@ -14601,7 +14747,6 @@ var __webpack_exports__ = {};
14601
14747
  decision?.verify_desc
14602
14748
  ].filter(Boolean).join(" ");
14603
14749
  const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
14604
- task.logger.warn(`TaskId:${task.taskId},检测到需要验证,准备返回验证信息`);
14605
14750
  let decisionObj = {};
14606
14751
  if (decision) decisionObj = decision;
14607
14752
  const mockData = {
@@ -14620,7 +14765,6 @@ var __webpack_exports__ = {};
14620
14765
  message: "操作成功"
14621
14766
  };
14622
14767
  }
14623
- task.logger.info("不需要验证,继续正常流程");
14624
14768
  reportLogger({
14625
14769
  token: params.huiwenToken || "",
14626
14770
  enverionment: task.enverionment || "development",
@@ -14632,8 +14776,7 @@ var __webpack_exports__ = {};
14632
14776
  platform: "douyin",
14633
14777
  publishParams: publishData
14634
14778
  });
14635
- task.logger.warn("发布结果");
14636
- task.logger.warn(JSON.stringify(publishResult));
14779
+ task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
14637
14780
  const isSuccess = 0 === publishResult.status_code;
14638
14781
  const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
14639
14782
  const data = isSuccess ? publishResult.item_id || "" : "";
@@ -15474,6 +15617,7 @@ var __webpack_exports__ = {};
15474
15617
  uploadedImgList: schemas_string().optional()
15475
15618
  });
15476
15619
  const douyinPublish = async (task, params)=>{
15620
+ task.logger.info(`douyinPublish actionType: ${params.actionType}`);
15477
15621
  if ("rpa" === params.actionType) return douyinPublish_rpa_rpaAction(task, params);
15478
15622
  if ("mockApi" === params.actionType) return mock_mockAction(task, params);
15479
15623
  if ("server" === params.actionType) return rpaAction_Server(task, params);
@@ -19763,7 +19907,7 @@ var __webpack_exports__ = {};
19763
19907
  ]).optional()
19764
19908
  });
19765
19909
  const shipinhaoPublish = async (task, params)=>{
19766
- console.log("shipinhaoPublish params:", params);
19910
+ task.logger.info(`shipinhaoPublish actionType: ${params.actionType}`);
19767
19911
  if ("rpa" === params.actionType) return shipinhaoPublish_rpa_rpaAction(task, params);
19768
19912
  if ("mockApi" === params.actionType) return shipinhaoPublish_mock_mockAction(task, params);
19769
19913
  if ("server" === params.actionType) return rpa_server_rpaAction_Server(task, params);
@@ -20821,6 +20965,7 @@ var __webpack_exports__ = {};
20821
20965
  };
20822
20966
  const getAddTypeValue = (toutiaoAd)=>"yes" === toutiaoAd ? 3 : 2;
20823
20967
  const toutiaoPublish = async (task, params)=>{
20968
+ task.logger.info(`toutiaoPublish actionType: ${params.actionType}`);
20824
20969
  params.content = formatSectionHtml(params.content);
20825
20970
  if ("rpa" === params.actionType) return toutiaoPublish_rpa_rpaAction(task, params);
20826
20971
  if ("mockApi" === params.actionType) return toutiaoPublish_mock_mockAction(task, params);
@@ -23157,6 +23302,33 @@ var __webpack_exports__ = {};
23157
23302
  const encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
23158
23303
  const xiaohongshuLogin_rpa_server_scanRetryMaxCount = 60;
23159
23304
  const xiaohongshuLogin_rpa_server_waitQrcodeResultMaxTime = 2000 * xiaohongshuLogin_rpa_server_scanRetryMaxCount;
23305
+ async function collectCookiesWithA1(task) {
23306
+ const hasA1 = (cookies)=>cookies.some((c)=>"a1" === c.name && !!c.value);
23307
+ let cookies = await task.steelBrowserContext?.cookies() ?? [];
23308
+ if (hasA1(cookies)) return cookies;
23309
+ task.logger?.warn("[XhsLogin] 首次抓取缺失 a1,尝试补救……");
23310
+ try {
23311
+ const page = task.steelBrowserContext?.pages?.()[0];
23312
+ if (page) {
23313
+ await page.goto("https://www.xiaohongshu.com", {
23314
+ waitUntil: "domcontentloaded",
23315
+ timeout: 15000
23316
+ });
23317
+ for(let i = 0; i < 10; i++){
23318
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
23319
+ if (hasA1(cookies)) {
23320
+ task.logger?.info(`[XhsLogin] a1 补救成功,第 ${i + 1} 次轮询命中`);
23321
+ return cookies;
23322
+ }
23323
+ await new Promise((resolve)=>setTimeout(resolve, 500));
23324
+ }
23325
+ }
23326
+ } catch (err) {
23327
+ task.logger?.warn("[XhsLogin] a1 补救访问主站失败", err);
23328
+ }
23329
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
23330
+ return cookies;
23331
+ }
23160
23332
  const xiaohongshuLogin_rpa_server_rpaServer = async (task, params)=>{
23161
23333
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23162
23334
  const reporter = task.reportService?.reportLoginStatus ?? (()=>Promise.resolve());
@@ -23357,21 +23529,29 @@ var __webpack_exports__ = {};
23357
23529
  };
23358
23530
  }
23359
23531
  case types_ExecutionState.SUCCESS:
23360
- await updateTaskState?.({
23361
- state: share_namespaceObject.TaskState.SUCCESS,
23362
- result: {
23363
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
23364
- userInfo: userInfo
23365
- }
23366
- });
23367
- return {
23368
- code: 0,
23369
- message: "成功",
23370
- data: {
23371
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
23372
- userInfo
23373
- }
23374
- };
23532
+ {
23533
+ const cookies = await collectCookiesWithA1(task);
23534
+ const hasA1 = cookies.some((c)=>"a1" === c.name && !!c.value);
23535
+ if (!hasA1) task.logger?.warn("[XhsLogin] 登录成功但缺失关键 cookie a1,后续检测可能失败", {
23536
+ cookieNames: cookies.map((c)=>c.name)
23537
+ });
23538
+ const cookieStr = JSON.stringify(cookies);
23539
+ await updateTaskState?.({
23540
+ state: share_namespaceObject.TaskState.SUCCESS,
23541
+ result: {
23542
+ cookie: cookieStr,
23543
+ userInfo: userInfo
23544
+ }
23545
+ });
23546
+ return {
23547
+ code: 0,
23548
+ message: "成功",
23549
+ data: {
23550
+ cookie: cookieStr,
23551
+ userInfo
23552
+ }
23553
+ };
23554
+ }
23375
23555
  default:
23376
23556
  return {
23377
23557
  code: 500,
@@ -23572,6 +23752,24 @@ var __webpack_exports__ = {};
23572
23752
  const fileName = (0, share_namespaceObject.getFilenameFromUrl)(url);
23573
23753
  const localUrl = await (0, share_namespaceObject.downloadImage)(url, external_node_path_default().join(tmpCachePath, fileName));
23574
23754
  const fileBuffer = external_node_fs_default().readFileSync(localUrl);
23755
+ let width = 0;
23756
+ let height = 0;
23757
+ try {
23758
+ const dimensions = external_image_size_default()(fileBuffer);
23759
+ width = dimensions.width ?? 0;
23760
+ height = dimensions.height ?? 0;
23761
+ const orientation = dimensions.orientation ?? 1;
23762
+ if ([
23763
+ 5,
23764
+ 6,
23765
+ 7,
23766
+ 8
23767
+ ].includes(orientation)) [width, height] = [
23768
+ height,
23769
+ width
23770
+ ];
23771
+ } catch {}
23772
+ const originSize = fileBuffer.byteLength / 1024;
23575
23773
  const MAX_RETRIES = uploadInfos.length;
23576
23774
  let attempt = 0;
23577
23775
  while(attempt < MAX_RETRIES){
@@ -23593,7 +23791,10 @@ var __webpack_exports__ = {};
23593
23791
  });
23594
23792
  return {
23595
23793
  ossFileId,
23596
- ossToken
23794
+ ossToken,
23795
+ width,
23796
+ height,
23797
+ originSize
23597
23798
  };
23598
23799
  } catch (error) {
23599
23800
  attempt++;
@@ -23601,7 +23802,10 @@ var __webpack_exports__ = {};
23601
23802
  }
23602
23803
  return {
23603
23804
  ossFileId: "",
23604
- ossToken: ""
23805
+ ossToken: "",
23806
+ width,
23807
+ height,
23808
+ originSize
23605
23809
  };
23606
23810
  };
23607
23811
  const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
@@ -23666,8 +23870,16 @@ var __webpack_exports__ = {};
23666
23870
  },
23667
23871
  image_info: {
23668
23872
  images: coverInfos.map((it)=>({
23669
- extra_info_json: '{"mimeType":"image/png"}',
23873
+ extra_info_json: JSON.stringify({
23874
+ mimeType: "image/png",
23875
+ image_metadata: {
23876
+ bg_color: "",
23877
+ origin_size: it.originSize
23878
+ }
23879
+ }),
23670
23880
  file_id: it.ossFileId,
23881
+ width: it.width,
23882
+ height: it.height,
23671
23883
  metadata: {
23672
23884
  source: -1
23673
23885
  },
@@ -23774,6 +23986,7 @@ var __webpack_exports__ = {};
23774
23986
  });
23775
23987
  return (0, share_namespaceObject.success)(data, message);
23776
23988
  }
23989
+ task.logger.info(`[xiaohongshuPublish] publishData: ${JSON.stringify(publishData)} `);
23777
23990
  const publishResult = await proxyHttp.api({
23778
23991
  method: "post",
23779
23992
  url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
@@ -24883,6 +25096,7 @@ var __webpack_exports__ = {};
24883
25096
  originalBind: schemas_boolean().optional()
24884
25097
  });
24885
25098
  const xiaohongshuPublish = async (task, params)=>{
25099
+ task.logger.info(`xiaohongshuPublish actionType: ${params.actionType}`);
24886
25100
  if (DisabledReq) return {
24887
25101
  code: 414,
24888
25102
  data: "",