@iflyrpa/actions 4.0.0-beta.8 → 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.mjs CHANGED
@@ -5434,7 +5434,9 @@ function __webpack_require__(moduleId) {
5434
5434
  return module;
5435
5435
  };
5436
5436
  })();
5437
- var package_namespaceObject = JSON.parse('{"i8":"4.0.0-beta.7"}');
5437
+ var package_namespaceObject = {
5438
+ i8: "3.1.1"
5439
+ };
5438
5440
  var dist = __webpack_require__("../../node_modules/.pnpm/https-proxy-agent@7.0.6/node_modules/https-proxy-agent/dist/index.js");
5439
5441
  async function ProxyAgent(task, ip, adr, accountId, refresh) {
5440
5442
  const http = new Http({
@@ -5520,7 +5522,8 @@ class Http {
5520
5522
  url: error.config?.url,
5521
5523
  isProxyRequest: !!(error.config && (error.config.httpAgent || error.config.httpsAgent)),
5522
5524
  params: error.config?.params,
5523
- data: error.config?.data
5525
+ data: error.config?.data,
5526
+ serverDate: error.response?.headers?.date
5524
5527
  }
5525
5528
  };
5526
5529
  if (foundError) Object.assign(errorResponse, foundError);
@@ -5598,7 +5601,7 @@ class Http {
5598
5601
  try {
5599
5602
  this.proxyInfo = agent ? `${agent.ip}:${agent.port}` : void 0;
5600
5603
  const controller = new AbortController();
5601
- const timeoutId = setTimeout(()=>controller.abort(), reqTimeout);
5604
+ const timeoutId = setTimeout(()=>controller.abort(), reqTimeout + 500);
5602
5605
  const response = await this.apiClient({
5603
5606
  ...config,
5604
5607
  timeout: reqTimeout,
@@ -5622,7 +5625,7 @@ class Http {
5622
5625
  599
5623
5626
  ].includes(handledError.code);
5624
5627
  if (Rtimes < retries && isRetry) {
5625
- this.logger?.info(`进入第${Rtimes + 1}次重试!`);
5628
+ this.logger?.info(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}`);
5626
5629
  await new Promise((resolve)=>setTimeout(resolve, retryDelay));
5627
5630
  return sessionRt(Rtimes + 1);
5628
5631
  }
@@ -9837,23 +9840,26 @@ const rpaServer = async (task, params)=>{
9837
9840
  };
9838
9841
  }
9839
9842
  case types_ExecutionState.SUCCESS:
9840
- await updateTaskState?.({
9841
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
9842
- result: {
9843
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
9844
- token,
9845
- userInfo: userInfo
9846
- }
9847
- });
9848
- return {
9849
- code: 0,
9850
- message: "成功",
9851
- data: {
9852
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()).replace(/\\"/g, ""),
9853
- token,
9854
- userInfo
9855
- }
9856
- };
9843
+ {
9844
+ const cookie = JSON.stringify(await task.steelBrowserContext?.cookies());
9845
+ await updateTaskState?.({
9846
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
9847
+ result: {
9848
+ cookie,
9849
+ token,
9850
+ userInfo: userInfo
9851
+ }
9852
+ });
9853
+ return {
9854
+ code: 0,
9855
+ message: "成功",
9856
+ data: {
9857
+ cookie,
9858
+ token,
9859
+ userInfo
9860
+ }
9861
+ };
9862
+ }
9857
9863
  default:
9858
9864
  return {
9859
9865
  code: 500,
@@ -10027,6 +10033,16 @@ const mockAction = async (task, params)=>{
10027
10033
  const images = _images.filter((url)=>!!url && "" !== url.trim());
10028
10034
  return await Promise.all(images.map(async (url)=>{
10029
10035
  const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
10036
+ const ext = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].extname(fileName).toLowerCase();
10037
+ if (![
10038
+ ".jpg",
10039
+ ".jpeg",
10040
+ ".png"
10041
+ ].includes(ext)) throw {
10042
+ code: 414,
10043
+ message: `图片格式不支持:${fileName}。百家号仅支持 jpg、png 格式,请转换后重试。`,
10044
+ data: ""
10045
+ };
10030
10046
  const image = await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
10031
10047
  const formData = new __WEBPACK_EXTERNAL_MODULE_form_data_cf000082__["default"]();
10032
10048
  formData.append("org_file_name", fileName);
@@ -10210,20 +10226,11 @@ const mockAction = async (task, params)=>{
10210
10226
  };
10211
10227
  const rpa_rpaAction = async (task, params)=>{
10212
10228
  const tmpCachePath = task.getTmpPath();
10213
- const commonCookies = {
10214
- path: "/",
10215
- secure: true,
10216
- domain: "baijiahao.baidu.com",
10217
- url: "https://baijiahao.baidu.com",
10218
- httpOnly: true
10219
- };
10229
+ const validCookies = (params.cookies || []).filter((it)=>it.name && it.value && "undefined" !== it.value);
10220
10230
  const page = await task.createPage({
10221
10231
  show: task.debug,
10222
10232
  url: params.url || "https://baijiahao.baidu.com/builder/rc/edit?type=news&is_from_cms=1",
10223
- cookies: params.cookies?.map((it)=>({
10224
- ...it,
10225
- ...commonCookies
10226
- })) || []
10233
+ cookies: validCookies
10227
10234
  });
10228
10235
  page.setDefaultTimeout(60000);
10229
10236
  page.setDefaultNavigationTimeout(60000);
@@ -10628,6 +10635,7 @@ const BaijiahaoPublishParamsSchema = ActionCommonParamsSchema.extend({
10628
10635
  })
10629
10636
  });
10630
10637
  const baijiahaoPublish = async (task, params)=>{
10638
+ task.logger.info(`baijiahaoPublish actionType: ${params.actionType}`);
10631
10639
  params.content = formatSectionHtml(params.content);
10632
10640
  if ("rpa" === params.actionType) return rpa_rpaAction(task, params);
10633
10641
  if ("mockApi" === params.actionType) return mockAction(task, params);
@@ -11756,6 +11764,8 @@ class Xhshow {
11756
11764
  }
11757
11765
  new Xhshow();
11758
11766
  const sessionCheck_xsEncrypt = new Xhshow();
11767
+ let lastEnvLogTime = 0;
11768
+ const ENV_LOG_INTERVAL_MS = 5000;
11759
11769
  const SessionCheckResultSchema = schemas_object({
11760
11770
  isValidSession: schemas_boolean()
11761
11771
  });
@@ -11820,35 +11830,33 @@ const WxSessionCheck = async (_task, params)=>{
11820
11830
  }, "微信账号有效性检测完成!");
11821
11831
  };
11822
11832
  const XhsSessionCheck = async (_task, params)=>{
11823
- const logger = _task.logger;
11824
- const startedAt = Date.now();
11833
+ const now = Date.now();
11834
+ const shouldLogEnv = now - lastEnvLogTime >= ENV_LOG_INTERVAL_MS;
11835
+ if (shouldLogEnv) {
11836
+ lastEnvLogTime = now;
11837
+ _task.logger?.debug("[XhsSessionCheck] 环境信息", {
11838
+ processType: process.type,
11839
+ pid: process.pid,
11840
+ nodeVersion: process.version,
11841
+ platform: process.platform,
11842
+ memoryUsage: {
11843
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
11844
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
11845
+ },
11846
+ accountId: params.accountId,
11847
+ hasProxy: !!(params.proxyLoc || params.localIP)
11848
+ });
11849
+ }
11825
11850
  const check = {
11826
11851
  isValidSession: false,
11827
11852
  isValidWebSession: false
11828
11853
  };
11829
- const cookieNames = params.cookies.map((it)=>it.name);
11830
- logger?.info("[XhsSessionCheck] 开始执行小红书账号有效性检测", {
11831
- accountId: params.accountId,
11832
- proxyLoc: params.proxyLoc,
11833
- localIP: params.localIP,
11834
- willUseProxyAgent: !!params.localIP,
11835
- cookieCount: params.cookies.length,
11836
- cookieNames,
11837
- hasA1: cookieNames.includes("a1"),
11838
- hasWebSession: cookieNames.includes("web_session")
11839
- });
11840
11854
  const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
11841
- if (!a1Cookie) {
11842
- logger?.warn("[XhsSessionCheck] 缺失关键 cookie a1,提前返回", {
11843
- accountId: params.accountId,
11844
- cookieNames
11845
- });
11846
- return {
11847
- code: 414,
11848
- message: "账号数据异常,请重新绑定账号后重试。",
11849
- data: check
11850
- };
11851
- }
11855
+ if (!a1Cookie) return {
11856
+ code: 414,
11857
+ message: "账号数据异常,请重新绑定账号后重试。",
11858
+ data: check
11859
+ };
11852
11860
  const headers = {
11853
11861
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
11854
11862
  referer: "https://creator.xiaohongshu.com/new/home?source=official"
@@ -11875,7 +11883,31 @@ const XhsSessionCheck = async (_task, params)=>{
11875
11883
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
11876
11884
  return acc;
11877
11885
  }, {});
11878
- const loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
11886
+ let loginBaseXsHeader;
11887
+ try {
11888
+ loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
11889
+ } catch (signError) {
11890
+ _task.logger?.error("[XhsSessionCheck] 签名生成失败 - 环境快照", {
11891
+ accountId: params.accountId,
11892
+ error: signError instanceof Error ? signError.message : String(signError),
11893
+ stack: _task.debug ? signError instanceof Error ? signError.stack : void 0 : void 0,
11894
+ hasA1: !!recordCookie.a1,
11895
+ env: {
11896
+ processType: process.type,
11897
+ memoryUsage: {
11898
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
11899
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
11900
+ },
11901
+ hasProxy: !!(params.proxyLoc || params.localIP),
11902
+ timeSinceLastLog: Date.now() - lastEnvLogTime
11903
+ }
11904
+ });
11905
+ return {
11906
+ code: 500,
11907
+ message: "账号签名生成失败,请稍后重试。",
11908
+ data: check
11909
+ };
11910
+ }
11879
11911
  const baseInfoStart = Date.now();
11880
11912
  const _baseInfo = http.api({
11881
11913
  method: "get",
@@ -11885,75 +11917,44 @@ const XhsSessionCheck = async (_task, params)=>{
11885
11917
  }, {
11886
11918
  retries: 3,
11887
11919
  retryDelay: 20,
11888
- timeout: 3000
11889
- }).then((res)=>{
11890
- logger?.info("[XhsSessionCheck] creator base 接口请求成功", {
11891
- accountId: params.accountId,
11892
- duration: Date.now() - baseInfoStart,
11893
- code: res?.code,
11894
- msg: res?.msg,
11895
- proxyInfo: http.proxyInfo
11896
- });
11897
- return res;
11920
+ timeout: 5000
11898
11921
  }).catch((e)=>{
11899
- logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
11922
+ const clientTimestamp = Date.now();
11923
+ const serverDate = e?.extra?.serverDate;
11924
+ const serverTimestamp = serverDate ? new Date(serverDate).getTime() : null;
11925
+ const timeDriftMs = serverTimestamp ? clientTimestamp - serverTimestamp : null;
11926
+ _task.logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
11900
11927
  accountId: params.accountId,
11901
11928
  duration: Date.now() - baseInfoStart,
11902
11929
  code: e?.code,
11903
11930
  message: e?.message,
11904
11931
  data: e?.data,
11905
11932
  extra: e?.extra,
11906
- proxyInfo: http.proxyInfo
11933
+ proxyInfo: http.proxyInfo,
11934
+ clientTimestamp,
11935
+ serverDate,
11936
+ serverTimestamp,
11937
+ timeDriftMs,
11938
+ isLikelyClockDrift: null !== timeDriftMs && Math.abs(timeDriftMs) > 300000
11907
11939
  });
11908
11940
  return e.data;
11909
11941
  });
11910
- const webSessionStart = Date.now();
11911
11942
  const _web_session = http.api({
11912
11943
  method: "get",
11913
11944
  url: "https://edith.xiaohongshu.com/api/sns/web/unread_count"
11914
11945
  }, {
11915
11946
  retries: 3,
11916
11947
  retryDelay: 20,
11917
- timeout: 3000
11918
- }).then((res)=>{
11919
- logger?.info("[XhsSessionCheck] edith unread_count 接口请求成功", {
11920
- accountId: params.accountId,
11921
- duration: Date.now() - webSessionStart,
11922
- code: res?.code,
11923
- msg: res?.msg,
11924
- proxyInfo: http.proxyInfo
11925
- });
11926
- return res;
11927
- }).catch((e)=>{
11928
- logger?.warn("[XhsSessionCheck] edith unread_count 接口请求失败", {
11929
- accountId: params.accountId,
11930
- duration: Date.now() - webSessionStart,
11931
- code: e?.code,
11932
- message: e?.message,
11933
- data: e?.data,
11934
- extra: e?.extra,
11935
- proxyInfo: http.proxyInfo
11936
- });
11937
- throw e;
11948
+ timeout: 5000
11938
11949
  });
11939
11950
  const [baseInfo, web_session] = await Promise.all([
11940
11951
  _baseInfo,
11941
11952
  _web_session
11942
11953
  ]);
11943
11954
  if (baseInfo?.code === 0) check.isValidSession = true;
11944
- if (0 === web_session.code) check.isValidWebSession = true;
11945
- const _isSuccess = baseInfo?.code === web_session.code;
11955
+ if (web_session?.code === 0) check.isValidWebSession = true;
11956
+ baseInfo?.code, web_session?.code;
11946
11957
  const message = `小红书账号有效性检测成功${_task.debug ? ` ${http.proxyInfo}` : ""}`;
11947
- logger?.info("[XhsSessionCheck] 检测完成", {
11948
- accountId: params.accountId,
11949
- totalDuration: Date.now() - startedAt,
11950
- baseInfoCode: baseInfo?.code,
11951
- webSessionCode: web_session?.code,
11952
- isValidSession: check.isValidSession,
11953
- isValidWebSession: check.isValidWebSession,
11954
- codeAligned: _isSuccess,
11955
- proxyInfo: http.proxyInfo
11956
- });
11957
11958
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(check, message);
11958
11959
  };
11959
11960
  const BjhSessionCheck = async (_task, params)=>{
@@ -14397,9 +14398,7 @@ const mock_mockAction = async (task, params)=>{
14397
14398
  msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
14398
14399
  a_bogus: ""
14399
14400
  };
14400
- task.logger.warn("publishParams", {
14401
- publishParams
14402
- });
14401
+ task.logger.info(`[douyinPublish] publishParams ${JSON.stringify(publishParams)}`);
14403
14402
  const publishData = {
14404
14403
  item: {
14405
14404
  common: {
@@ -14475,21 +14474,21 @@ const mock_mockAction = async (task, params)=>{
14475
14474
  }
14476
14475
  publishData.item.common.creation_id = generateRandomString(8) + Date.now();
14477
14476
  let decision = null;
14478
- task.logger.info(`proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
14477
+ task.logger.info(`[douyinPublish] proxyHttp 代理信息: ${proxyHttp.proxyInfo} `);
14479
14478
  proxyHttp.addResponseInterceptor((response)=>{
14480
14479
  console.log("拦截器收到响应:", JSON.stringify(response.data));
14481
- task.logger.info(`拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
14482
- task.logger.info(`拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
14480
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.headers: ${JSON.stringify(response.headers)} `);
14481
+ task.logger.warn(`[douyinPublish] 拦截器收到响应response.data: ${JSON.stringify(response.data)} `);
14483
14482
  decision = parseVerifyPassportDecision(response.headers["x-tt-verify-passport-decision"]);
14484
14483
  if (needsVerification(decision)) {
14485
- task.logger.info(`需要验证: ${JSON.stringify(decision)}`);
14484
+ task.logger.warn(`[douyinPublish] 检测到需要验证: ${JSON.stringify(decision)}`);
14486
14485
  return;
14487
14486
  }
14488
14487
  if (!response || !response.data) return;
14489
14488
  const responseData = response.data;
14490
14489
  if (response && responseData?.status_code && 0 !== responseData.status_code) {
14491
14490
  const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
14492
- if (4 === responseData.status_code) task.logger.warn(`抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
14491
+ if (4 === responseData.status_code) task.logger.warn(`[douyinPublish] 抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
14493
14492
  return {
14494
14493
  code: errorCode,
14495
14494
  message: responseData.status_msg || "文章发布异常,请稍后重试。",
@@ -14509,42 +14508,120 @@ const mock_mockAction = async (task, params)=>{
14509
14508
  });
14510
14509
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(0, message, data);
14511
14510
  }
14512
- const webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
14513
- const ticket = webProtectData.ticket;
14514
- const ts_sign = webProtectData.ts_sign;
14515
- const ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
14516
- const certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
14511
+ let webProtectData;
14512
+ try {
14513
+ webProtectData = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"] || "{}").data || "{}");
14514
+ if (!webProtectData.ticket || !webProtectData.ts_sign || !webProtectData.client_cert) {
14515
+ task.logger.error(`webProtectData 关键字段缺失: ${JSON.stringify(webProtectData)}`);
14516
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 webProtectData 不完整,请重新获取后重试", "");
14517
+ }
14518
+ } catch (error) {
14519
+ task.logger.error(`解析 webProtectData 失败: ${error}`);
14520
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 webProtectData 解析失败,请重新获取后重试", "");
14521
+ }
14522
+ let ticket = webProtectData.ticket;
14523
+ let ts_sign = webProtectData.ts_sign;
14524
+ const serverDataCookie = params.cookies.find((it)=>"bd_ticket_guard_server_data" === it.name)?.value;
14525
+ if (serverDataCookie) try {
14526
+ const decoded = JSON.parse(Buffer.from(decodeURIComponent(serverDataCookie), "base64").toString("utf8"));
14527
+ if (decoded.ticket && decoded.ts_sign) {
14528
+ if (decoded.ticket !== ticket) task.logger.info("[douyinPublish] 使用 cookie 中的最新 ticket(web_protect 已过期)");
14529
+ ticket = decoded.ticket;
14530
+ ts_sign = decoded.ts_sign;
14531
+ }
14532
+ } catch (error) {
14533
+ task.logger.warn(`解析 bd_ticket_guard_server_data 失败,回退到 web_protect: ${error}`);
14534
+ }
14535
+ let ec_privateKey;
14536
+ try {
14537
+ ec_privateKey = JSON.parse(JSON.parse(params.extraParam["security-sdk/s_sdk_crypt_sdk"] || "{}").data || "{}").ec_privateKey;
14538
+ if (!ec_privateKey) {
14539
+ task.logger.error("ec_privateKey 为空");
14540
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 ec_privateKey 缺失,请重新获取后重试", "");
14541
+ }
14542
+ } catch (error) {
14543
+ task.logger.error(`解析 ec_privateKey 失败: ${error}`);
14544
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 ec_privateKey 解析失败,请重新获取后重试", "");
14545
+ }
14546
+ let certificate;
14547
+ try {
14548
+ certificate = JSON.parse(params.extraParam["security-sdk/s_sdk_server_cert_key"] || "{}").cert;
14549
+ if (!certificate) {
14550
+ task.logger.error("certificate 为空");
14551
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 certificate 缺失,请重新获取后重试", "");
14552
+ }
14553
+ } catch (error) {
14554
+ task.logger.error(`解析 certificate 失败: ${error}`);
14555
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 certificate 解析失败,请重新获取后重试", "");
14556
+ }
14517
14557
  const ree_public_key = webProtectData.client_cert.replace("pub.", "");
14518
- task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket}, ts_sign: ${ts_sign}, ec_privateKey: ${ec_privateKey}, certificate: ${certificate}, ree_public_key: ${ree_public_key}`);
14519
- const bdTicketGuardClientData = getBdV2({
14520
- ticket,
14521
- ts_sign: ts_sign,
14522
- ec_privateKey: ec_privateKey,
14523
- certificate: certificate,
14524
- bd_ticket_guard_ree_public_key: ree_public_key
14525
- });
14526
- task.logger.info("bdTicketGuardClientData", {
14527
- bdTicketGuardClientData
14528
- });
14558
+ task.logger.info(`生成 bdTicketGuardClientData 的参数: ticket: ${ticket?.substring(0, 20)}..., ts_sign: ${ts_sign}, ree_public_key: ${ree_public_key?.substring(0, 20)}...`);
14559
+ let bdTicketGuardClientData;
14560
+ try {
14561
+ bdTicketGuardClientData = getBdV2({
14562
+ ticket,
14563
+ ts_sign: ts_sign,
14564
+ ec_privateKey: ec_privateKey,
14565
+ certificate: certificate,
14566
+ bd_ticket_guard_ree_public_key: ree_public_key
14567
+ });
14568
+ if (!bdTicketGuardClientData || !bdTicketGuardClientData["headers_bd_ticket_guard_client_data"]) {
14569
+ task.logger.error(`bdTicketGuardClientData 生成失败或不完整: ${JSON.stringify(bdTicketGuardClientData)}`);
14570
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 bdTicketGuardClientData 生成失败,请重新获取后重试", "");
14571
+ }
14572
+ } catch (error) {
14573
+ task.logger.error(`生成 bdTicketGuardClientData 失败: ${error}`);
14574
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 bdTicketGuardClientData 生成异常,请重新获取后重试", "");
14575
+ }
14576
+ task.logger.info("bdTicketGuardClientData 生成成功");
14529
14577
  const publishQuery = {
14530
14578
  ...publishParams,
14531
14579
  a_bogus: ""
14532
14580
  };
14533
14581
  const queryString = new URLSearchParams(publishQuery).toString();
14534
- const aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
14582
+ let aBogus;
14583
+ try {
14584
+ aBogus = mock_getABogus(`https://creator.douyin.com/web/api/media/aweme/create_v2/?${queryString}`, publishData, userAgent);
14585
+ if (!aBogus || aBogus.length < 10) {
14586
+ task.logger.error(`a_bogus 生成异常,长度过短: ${aBogus}`);
14587
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 a_bogus 生成失败,请重试", "");
14588
+ }
14589
+ task.logger.info(`a_bogus 生成成功: ${aBogus.substring(0, 20)}...`);
14590
+ } catch (error) {
14591
+ task.logger.error(`生成 a_bogus 失败: ${error}`);
14592
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 a_bogus 生成异常,请重试", "");
14593
+ }
14535
14594
  publishQuery.a_bogus = aBogus;
14536
14595
  const publishQueryParams = new URLSearchParams(publishQuery).toString();
14537
- const csrfToken = mock_generateCsrfTokenAdvanced({
14538
- cookies: params.cookies,
14539
- url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
14540
- method: "POST",
14541
- userAgent
14542
- });
14543
- const sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
14544
- task.logger.info("发布数据", {
14596
+ let csrfToken;
14597
+ try {
14598
+ csrfToken = mock_generateCsrfTokenAdvanced({
14599
+ cookies: params.cookies,
14600
+ url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
14601
+ method: "POST",
14602
+ userAgent
14603
+ });
14604
+ if (!csrfToken || csrfToken.length < 10) {
14605
+ task.logger.error(`csrfToken 生成异常,长度过短: ${csrfToken}`);
14606
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 csrfToken 生成失败,请重试", "");
14607
+ }
14608
+ task.logger.info(`csrfToken 生成成功: ${csrfToken.substring(0, 20)}...`);
14609
+ } catch (error) {
14610
+ task.logger.error(`生成 csrfToken 失败: ${error}`);
14611
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 csrfToken 生成异常,请重试", "");
14612
+ }
14613
+ let sessionDtrait;
14614
+ try {
14615
+ sessionDtrait = mock_generateDtrait("/web/api/media/aweme/create_v2/");
14616
+ task.logger.info(`sessionDtrait 生成成功: ${sessionDtrait || "(空)"}`);
14617
+ } catch (error) {
14618
+ task.logger.error(`生成 sessionDtrait 失败: ${error}`);
14619
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "安全参数 sessionDtrait 生成异常,请重试", "");
14620
+ }
14621
+ task.logger.info("[douyinPublish] 发布数据", {
14545
14622
  data: JSON.stringify(publishData)
14546
14623
  });
14547
- task.logger.info(`headers: ${JSON.stringify({
14624
+ task.logger.info(`[douyinPublish] headers: ${JSON.stringify({
14548
14625
  ...headers,
14549
14626
  Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
14550
14627
  "Content-Type": "application/json",
@@ -14557,8 +14634,7 @@ const mock_mockAction = async (task, params)=>{
14557
14634
  "x-secsdk-csrf-token": csrfToken,
14558
14635
  "x-tt-session-dtrait": sessionDtrait || ""
14559
14636
  })}`);
14560
- task.logger.info(`publishData: ${JSON.stringify(publishData)}`);
14561
- task.logger.info(`url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
14637
+ task.logger.info(`[douyinPublish] url: https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`);
14562
14638
  const publishResult = await proxyHttp.api({
14563
14639
  method: "post",
14564
14640
  url: `https://creator.douyin.com/web/api/media/aweme/create_v2/?${publishQueryParams}`,
@@ -14582,8 +14658,7 @@ const mock_mockAction = async (task, params)=>{
14582
14658
  retries: 3,
14583
14659
  retryDelay: 2000
14584
14660
  });
14585
- task.logger.info("========== api调用完成 ==========");
14586
- task.logger.info(`decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
14661
+ task.logger.info(`[douyinPublish] decision值: ${JSON.stringify(decision)}, needsVerification(decision): ${needsVerification(decision)}`);
14587
14662
  if (needsVerification(decision)) {
14588
14663
  const details = [
14589
14664
  publishResult.status_msg,
@@ -14591,7 +14666,6 @@ const mock_mockAction = async (task, params)=>{
14591
14666
  decision?.verify_desc
14592
14667
  ].filter(Boolean).join(" ");
14593
14668
  const message = `图文发布失败,原因:${details}${task.debug ? ` ${http.proxyInfo}` : ""}`;
14594
- task.logger.warn(`TaskId:${task.taskId},检测到需要验证,准备返回验证信息`);
14595
14669
  let decisionObj = {};
14596
14670
  if (decision) decisionObj = decision;
14597
14671
  const mockData = {
@@ -14610,7 +14684,6 @@ const mock_mockAction = async (task, params)=>{
14610
14684
  message: "操作成功"
14611
14685
  };
14612
14686
  }
14613
- task.logger.info("不需要验证,继续正常流程");
14614
14687
  reportLogger({
14615
14688
  token: params.huiwenToken || "",
14616
14689
  enverionment: task.enverionment || "development",
@@ -14622,8 +14695,7 @@ const mock_mockAction = async (task, params)=>{
14622
14695
  platform: "douyin",
14623
14696
  publishParams: publishData
14624
14697
  });
14625
- task.logger.warn("发布结果");
14626
- task.logger.warn(JSON.stringify(publishResult));
14698
+ task.logger.info(`[douyinPublish] 发布结果 ${JSON.stringify(publishResult)}`);
14627
14699
  const isSuccess = 0 === publishResult.status_code;
14628
14700
  const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
14629
14701
  const data = isSuccess ? publishResult.item_id || "" : "";
@@ -15464,6 +15536,7 @@ const DouyinPublishParamsSchema = ActionCommonParamsSchema.extend({
15464
15536
  uploadedImgList: schemas_string().optional()
15465
15537
  });
15466
15538
  const douyinPublish = async (task, params)=>{
15539
+ task.logger.info(`douyinPublish actionType: ${params.actionType}`);
15467
15540
  if ("rpa" === params.actionType) return douyinPublish_rpa_rpaAction(task, params);
15468
15541
  if ("mockApi" === params.actionType) return mock_mockAction(task, params);
15469
15542
  if ("server" === params.actionType) return rpaAction_Server(task, params);
@@ -19749,7 +19822,7 @@ const ShipinhaoPublishParamsSchema = ActionCommonParamsSchema.extend({
19749
19822
  ]).optional()
19750
19823
  });
19751
19824
  const shipinhaoPublish = async (task, params)=>{
19752
- console.log("shipinhaoPublish params:", params);
19825
+ task.logger.info(`shipinhaoPublish actionType: ${params.actionType}`);
19753
19826
  if ("rpa" === params.actionType) return shipinhaoPublish_rpa_rpaAction(task, params);
19754
19827
  if ("mockApi" === params.actionType) return shipinhaoPublish_mock_mockAction(task, params);
19755
19828
  if ("server" === params.actionType) return rpa_server_rpaAction_Server(task, params);
@@ -20807,6 +20880,7 @@ const COVER_TYPE = {
20807
20880
  };
20808
20881
  const getAddTypeValue = (toutiaoAd)=>"yes" === toutiaoAd ? 3 : 2;
20809
20882
  const toutiaoPublish = async (task, params)=>{
20883
+ task.logger.info(`toutiaoPublish actionType: ${params.actionType}`);
20810
20884
  params.content = formatSectionHtml(params.content);
20811
20885
  if ("rpa" === params.actionType) return toutiaoPublish_rpa_rpaAction(task, params);
20812
20886
  if ("mockApi" === params.actionType) return toutiaoPublish_mock_mockAction(task, params);
@@ -23143,6 +23217,33 @@ const xiaohongshuLogin_rpa_rpaAction = async (task, _params)=>{
23143
23217
  const encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
23144
23218
  const xiaohongshuLogin_rpa_server_scanRetryMaxCount = 60;
23145
23219
  const xiaohongshuLogin_rpa_server_waitQrcodeResultMaxTime = 2000 * xiaohongshuLogin_rpa_server_scanRetryMaxCount;
23220
+ async function collectCookiesWithA1(task) {
23221
+ const hasA1 = (cookies)=>cookies.some((c)=>"a1" === c.name && !!c.value);
23222
+ let cookies = await task.steelBrowserContext?.cookies() ?? [];
23223
+ if (hasA1(cookies)) return cookies;
23224
+ task.logger?.warn("[XhsLogin] 首次抓取缺失 a1,尝试补救……");
23225
+ try {
23226
+ const page = task.steelBrowserContext?.pages?.()[0];
23227
+ if (page) {
23228
+ await page.goto("https://www.xiaohongshu.com", {
23229
+ waitUntil: "domcontentloaded",
23230
+ timeout: 15000
23231
+ });
23232
+ for(let i = 0; i < 10; i++){
23233
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
23234
+ if (hasA1(cookies)) {
23235
+ task.logger?.info(`[XhsLogin] a1 补救成功,第 ${i + 1} 次轮询命中`);
23236
+ return cookies;
23237
+ }
23238
+ await new Promise((resolve)=>setTimeout(resolve, 500));
23239
+ }
23240
+ }
23241
+ } catch (err) {
23242
+ task.logger?.warn("[XhsLogin] a1 补救访问主站失败", err);
23243
+ }
23244
+ cookies = await task.steelBrowserContext?.cookies() ?? [];
23245
+ return cookies;
23246
+ }
23146
23247
  const xiaohongshuLogin_rpa_server_rpaServer = async (task, params)=>{
23147
23248
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23148
23249
  const reporter = task.reportService?.reportLoginStatus ?? (()=>Promise.resolve());
@@ -23343,21 +23444,29 @@ const xiaohongshuLogin_rpa_server_rpaServer = async (task, params)=>{
23343
23444
  };
23344
23445
  }
23345
23446
  case types_ExecutionState.SUCCESS:
23346
- await updateTaskState?.({
23347
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
23348
- result: {
23349
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
23350
- userInfo: userInfo
23351
- }
23352
- });
23353
- return {
23354
- code: 0,
23355
- message: "成功",
23356
- data: {
23357
- cookie: JSON.stringify(await task.steelBrowserContext?.cookies()),
23358
- userInfo
23359
- }
23360
- };
23447
+ {
23448
+ const cookies = await collectCookiesWithA1(task);
23449
+ const hasA1 = cookies.some((c)=>"a1" === c.name && !!c.value);
23450
+ if (!hasA1) task.logger?.warn("[XhsLogin] 登录成功但缺失关键 cookie a1,后续检测可能失败", {
23451
+ cookieNames: cookies.map((c)=>c.name)
23452
+ });
23453
+ const cookieStr = JSON.stringify(cookies);
23454
+ await updateTaskState?.({
23455
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
23456
+ result: {
23457
+ cookie: cookieStr,
23458
+ userInfo: userInfo
23459
+ }
23460
+ });
23461
+ return {
23462
+ code: 0,
23463
+ message: "成功",
23464
+ data: {
23465
+ cookie: cookieStr,
23466
+ userInfo
23467
+ }
23468
+ };
23469
+ }
23361
23470
  default:
23362
23471
  return {
23363
23472
  code: 500,
@@ -23558,6 +23667,24 @@ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23558
23667
  const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
23559
23668
  const localUrl = await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
23560
23669
  const fileBuffer = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(localUrl);
23670
+ let width = 0;
23671
+ let height = 0;
23672
+ try {
23673
+ const dimensions = (0, __WEBPACK_EXTERNAL_MODULE_image_size_bc738ffb__["default"])(fileBuffer);
23674
+ width = dimensions.width ?? 0;
23675
+ height = dimensions.height ?? 0;
23676
+ const orientation = dimensions.orientation ?? 1;
23677
+ if ([
23678
+ 5,
23679
+ 6,
23680
+ 7,
23681
+ 8
23682
+ ].includes(orientation)) [width, height] = [
23683
+ height,
23684
+ width
23685
+ ];
23686
+ } catch {}
23687
+ const originSize = fileBuffer.byteLength / 1024;
23561
23688
  const MAX_RETRIES = uploadInfos.length;
23562
23689
  let attempt = 0;
23563
23690
  while(attempt < MAX_RETRIES){
@@ -23579,7 +23706,10 @@ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23579
23706
  });
23580
23707
  return {
23581
23708
  ossFileId,
23582
- ossToken
23709
+ ossToken,
23710
+ width,
23711
+ height,
23712
+ originSize
23583
23713
  };
23584
23714
  } catch (error) {
23585
23715
  attempt++;
@@ -23587,7 +23717,10 @@ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23587
23717
  }
23588
23718
  return {
23589
23719
  ossFileId: "",
23590
- ossToken: ""
23720
+ ossToken: "",
23721
+ width,
23722
+ height,
23723
+ originSize
23591
23724
  };
23592
23725
  };
23593
23726
  const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
@@ -23652,8 +23785,16 @@ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23652
23785
  },
23653
23786
  image_info: {
23654
23787
  images: coverInfos.map((it)=>({
23655
- extra_info_json: '{"mimeType":"image/png"}',
23788
+ extra_info_json: JSON.stringify({
23789
+ mimeType: "image/png",
23790
+ image_metadata: {
23791
+ bg_color: "",
23792
+ origin_size: it.originSize
23793
+ }
23794
+ }),
23656
23795
  file_id: it.ossFileId,
23796
+ width: it.width,
23797
+ height: it.height,
23657
23798
  metadata: {
23658
23799
  source: -1
23659
23800
  },
@@ -23760,6 +23901,7 @@ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23760
23901
  });
23761
23902
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
23762
23903
  }
23904
+ task.logger.info(`[xiaohongshuPublish] publishData: ${JSON.stringify(publishData)} `);
23763
23905
  const publishResult = await proxyHttp.api({
23764
23906
  method: "post",
23765
23907
  url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
@@ -24869,6 +25011,7 @@ const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
24869
25011
  originalBind: schemas_boolean().optional()
24870
25012
  });
24871
25013
  const xiaohongshuPublish = async (task, params)=>{
25014
+ task.logger.info(`xiaohongshuPublish actionType: ${params.actionType}`);
24872
25015
  if (DisabledReq) return {
24873
25016
  code: 414,
24874
25017
  data: "",