@iflyrpa/actions 4.1.0-beta.6 → 4.1.1-beta.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/bundle.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*! For license information please see bundle.js.LICENSE.txt */
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ed6f9fc8-db66-5df4-be7c-d5593224a8b2")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fb6eb3b8-9fcc-53e7-9e60-cd649507d5fa")}catch(e){}}();
4
4
  var __webpack_modules__ = {
5
5
  "../../node_modules/.pnpm/agent-base@7.1.4/node_modules/agent-base/dist/helpers.js": function(__unused_webpack_module, exports1, __webpack_require__) {
6
6
  "use strict";
@@ -12491,9 +12491,9 @@ var __webpack_exports__ = {};
12491
12491
  origin: ()=>utils_origin
12492
12492
  });
12493
12493
  var package_namespaceObject = {
12494
- i8: "0.1.2"
12494
+ i8: "0.2.0"
12495
12495
  };
12496
- var package_namespaceObject_0 = JSON.parse('{"i8":"4.1.0-beta.6"}');
12496
+ var package_namespaceObject_0 = JSON.parse('{"i8":"4.1.1-beta.0"}');
12497
12497
  const external_node_fs_namespaceObject = require("node:fs");
12498
12498
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
12499
12499
  const external_node_http_namespaceObject = require("node:http");
@@ -12584,7 +12584,7 @@ var __webpack_exports__ = {};
12584
12584
  fileStream.on("error", (err)=>{
12585
12585
  reject({
12586
12586
  code: 500,
12587
- message: `图片Buffer写入失败: ${err.message}`
12587
+ message: "图片写入失败,请检查磁盘空间"
12588
12588
  });
12589
12589
  });
12590
12590
  } else {
@@ -27073,6 +27073,11 @@ var __webpack_exports__ = {};
27073
27073
  const RPA_ERROR_WEBHOOK_URL = "https://open.xfchat.iflytek.com/open-apis/bot/v2/hook/d202c0dc-5af5-40bc-83ed-abc677caa4a5";
27074
27074
  const ALARM_THROTTLE_MS = 60000;
27075
27075
  const lastSentAt = new Map();
27076
+ const THROTTLE_MAP_MAX_KEYS = 500;
27077
+ const pruneThrottleMap = (now)=>{
27078
+ if (lastSentAt.size < THROTTLE_MAP_MAX_KEYS) return;
27079
+ for (const [key, at] of lastSentAt)if (now - at >= ALARM_THROTTLE_MS) lastSentAt.delete(key);
27080
+ };
27076
27081
  const postFeishuWebhook = (webhookUrl, payload)=>lib_axios.post(webhookUrl, payload, {
27077
27082
  headers: {
27078
27083
  "Content-Type": "application/json"
@@ -27150,10 +27155,11 @@ var __webpack_exports__ = {};
27150
27155
  };
27151
27156
  const reportFeishuAlarm = (report)=>{
27152
27157
  try {
27153
- const key = `${report.platform}|${report.source}|${report.errorType}|${report.code ?? ""}`;
27158
+ const key = `${report.platform}|${report.source}|${report.stage}|${report.errorType}|${report.code ?? ""}`;
27154
27159
  const now = Date.now();
27155
27160
  const last = lastSentAt.get(key);
27156
27161
  if (last && now - last < ALARM_THROTTLE_MS) return;
27162
+ pruneThrottleMap(now);
27157
27163
  lastSentAt.set(key, now);
27158
27164
  postFeishuWebhook(RPA_ERROR_WEBHOOK_URL, buildFeishuPostMessage(report)).catch(()=>{});
27159
27165
  } catch {}
@@ -27300,6 +27306,19 @@ var __webpack_exports__ = {};
27300
27306
  461,
27301
27307
  471
27302
27308
  ]);
27309
+ function isLocalAddress(url) {
27310
+ let hostname;
27311
+ try {
27312
+ hostname = new URL(url).hostname.toLowerCase();
27313
+ } catch {
27314
+ return false;
27315
+ }
27316
+ if ("localhost" === hostname || "::1" === hostname || "[::1]" === hostname) return true;
27317
+ if (hostname.endsWith(".localhost") || hostname.endsWith(".local")) return true;
27318
+ if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname)) return true;
27319
+ if ("0.0.0.0" === hostname) return true;
27320
+ return false;
27321
+ }
27303
27322
  const HTTP_STATUS_MESSAGE = {
27304
27323
  400: "请求参数错误,请检查参数格式是否正确!",
27305
27324
  401: "登录状态已失效,请重新登录后重试!",
@@ -27336,7 +27355,14 @@ var __webpack_exports__ = {};
27336
27355
  };
27337
27356
  class Http {
27338
27357
  static handleApiError(error) {
27339
- if (error && "object" == typeof error && "code" in error && "message" in error) return error;
27358
+ if (error && "object" == typeof error && "code" in error && "message" in error) {
27359
+ const resp = error;
27360
+ if ("string" != typeof resp.message || !resp.message.trim()) return {
27361
+ ...resp,
27362
+ message: USER_MESSAGE.SYSTEM_ERROR
27363
+ };
27364
+ return resp;
27365
+ }
27340
27366
  return {
27341
27367
  code: 500,
27342
27368
  message: USER_MESSAGE.SYSTEM_ERROR,
@@ -27474,21 +27500,51 @@ var __webpack_exports__ = {};
27474
27500
  errorResponse.message = message;
27475
27501
  }
27476
27502
  if (error.message.includes("Proxy connection ended")) errorResponse.message = "所在区域代理连接超时,请更换区域或稍后重试!";
27477
- const status = error.response?.status;
27478
- reportFeishuAlarm({
27479
- level: status && ALARM_STATUS.has(status) ? "alarm" : "warning",
27480
- platform: this.platform || "unknown",
27481
- source: "http",
27482
- stage: `${(error.config?.method || "get").toUpperCase()} ${error.config?.url || "-"}`,
27483
- errorType: status ? `HTTP_${status}` : error.code || "NETWORK_ERROR",
27484
- code: errorResponse.code,
27485
- msg: errorResponse.message,
27486
- url: error.config?.url,
27487
- title: "RPA接口异常"
27488
- });
27503
+ errorResponse.extra = {
27504
+ ...errorResponse.extra,
27505
+ alarmStatus: error.response?.status,
27506
+ alarmErrorCode: error.code
27507
+ };
27489
27508
  throw errorResponse;
27490
27509
  });
27491
27510
  }
27511
+ reportRequestFailure(config, error, attempts) {
27512
+ const status = error.extra?.alarmStatus;
27513
+ const axiosCode = error.extra?.alarmErrorCode;
27514
+ const method = (config.method || "get").toUpperCase();
27515
+ const baseURL = config.baseURL || this.apiClient.defaults.baseURL || "";
27516
+ const fullUrl = config.url ? /^https?:\/\//.test(config.url) ? config.url : `${baseURL.replace(/\/$/, "")}${config.url}` : baseURL;
27517
+ if (!fullUrl) {
27518
+ this.logger?.debug(`[告警跳过] 请求失败但无 URL,不上报: ${error.message}`);
27519
+ return;
27520
+ }
27521
+ if (isLocalAddress(fullUrl)) {
27522
+ this.logger?.debug(`[告警跳过] 本机地址不上报: ${fullUrl}`);
27523
+ return;
27524
+ }
27525
+ if (attempts < 3) {
27526
+ const isAuthExpired = 401 === status;
27527
+ const isTimeoutCanceled = "ERR_CANCELED" === axiosCode;
27528
+ if (isAuthExpired || isTimeoutCanceled) {
27529
+ this.logger?.debug(`[告警跳过] 低重试次数(${attempts})的常见错误不上报: status=${status}, code=${error.code}, axiosCode=${axiosCode}, url=${fullUrl}`);
27530
+ return;
27531
+ }
27532
+ }
27533
+ const rawMsg = "string" == typeof error.message && error.message.trim() ? error.message : "";
27534
+ const baseMsg = rawMsg || `请求失败(无错误文案,code=${error.code ?? "unknown"})`;
27535
+ const retriedSuffix = attempts > 0 ? `(已重试${attempts}次仍失败)` : "";
27536
+ reportFeishuAlarm({
27537
+ level: status && ALARM_STATUS.has(status) ? "alarm" : "warning",
27538
+ platform: "@iflyrpa/playwright",
27539
+ source: "http",
27540
+ stage: `${method} ${fullUrl}`,
27541
+ errorType: status ? `HTTP_${status}` : axiosCode || "NETWORK_ERROR",
27542
+ code: error.code,
27543
+ msg: `${baseMsg}${retriedSuffix}`,
27544
+ url: fullUrl,
27545
+ title: "RPA接口异常"
27546
+ });
27547
+ }
27492
27548
  async api(config, options) {
27493
27549
  const retries = options?.retries ?? 0;
27494
27550
  const retryDelay = options?.retryDelay ?? 500;
@@ -27533,10 +27589,12 @@ var __webpack_exports__ = {};
27533
27589
  ].includes(handledError.code);
27534
27590
  if (Rtimes < retries && isRetry) {
27535
27591
  const url = config.url || "";
27536
- this.logger?.warn(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}, 请求地址: ${url}`);
27537
- await new Promise((resolve)=>setTimeout(resolve, retryDelay));
27592
+ const backoff = Math.min(retryDelay * 2 ** Rtimes, 5000);
27593
+ this.logger?.warn(`进入第${Rtimes + 1}次重试!错误码: ${handledError.code}, 等待: ${backoff}ms, 请求地址: ${url}`);
27594
+ await new Promise((resolve)=>setTimeout(resolve, backoff));
27538
27595
  return sessionRt(Rtimes + 1);
27539
27596
  }
27597
+ this.reportRequestFailure(config, handledError, Rtimes);
27540
27598
  return Promise.reject(handledError);
27541
27599
  }
27542
27600
  };
@@ -32927,7 +32985,7 @@ var __webpack_exports__ = {};
32927
32985
  ".png"
32928
32986
  ].includes(ext)) throw {
32929
32987
  code: 414,
32930
- message: `图片格式不支持:${fileName}。百家号仅支持 jpg、png 格式,请转换后重试。`,
32988
+ message: "图片格式不支持,百家号仅支持 jpg、png 格式,请转换后重试。",
32931
32989
  data: ""
32932
32990
  };
32933
32991
  const image = await downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
@@ -33608,7 +33666,8 @@ var __webpack_exports__ = {};
33608
33666
  },
33609
33667
  _task.logger,
33610
33668
  params.proxyLoc,
33611
- params.accountId
33669
+ params.accountId,
33670
+ "xiaohongshu"
33612
33671
  ];
33613
33672
  const http = new Http(...args);
33614
33673
  const fans = {
@@ -33622,8 +33681,8 @@ var __webpack_exports__ = {};
33622
33681
  url: "https://creator.xiaohongshu.com/api/galaxy/creator/home/personal_info"
33623
33682
  }, {
33624
33683
  retries: 3,
33625
- retryDelay: 20,
33626
- timeout: 3000
33684
+ retryDelay: 300,
33685
+ timeout: 30000
33627
33686
  });
33628
33687
  fans.fans_count = Number(res.data.fans_count);
33629
33688
  fans.digg_count = Number(res.data.faved_count);
@@ -34760,7 +34819,8 @@ var __webpack_exports__ = {};
34760
34819
  },
34761
34820
  _task.logger,
34762
34821
  params.proxyLoc,
34763
- params.accountId
34822
+ params.accountId,
34823
+ "xiaohongshu"
34764
34824
  ];
34765
34825
  const http = new Http(...args);
34766
34826
  http.addResponseInterceptor((response)=>{
@@ -34770,52 +34830,26 @@ var __webpack_exports__ = {};
34770
34830
  data: response.data.data
34771
34831
  };
34772
34832
  });
34773
- const loginBasePath = "/api/galaxy/v2/creator/datacenter/account/base";
34833
+ const loginBasePath = "/api/galaxy/creator/home/personal_info";
34774
34834
  const recordCookie = params.cookies.reduce((acc, cookie)=>{
34775
34835
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
34776
34836
  return acc;
34777
34837
  }, {});
34778
- let loginBaseXsHeader;
34779
- try {
34780
- loginBaseXsHeader = sessionCheck_xsEncrypt.signHeadersGet(loginBasePath, recordCookie, "xhs-pc-web", null);
34781
- } catch (signError) {
34782
- _task.logger?.error("[XhsSessionCheck] 签名生成失败 - 环境快照", {
34783
- accountId: params.accountId,
34784
- error: signError instanceof Error ? signError.message : String(signError),
34785
- stack: _task.debug ? signError instanceof Error ? signError.stack : void 0 : void 0,
34786
- hasA1: !!recordCookie.a1,
34787
- env: {
34788
- processType: process.type,
34789
- memoryUsage: {
34790
- heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
34791
- heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
34792
- },
34793
- hasProxy: !!params.proxyLoc,
34794
- timeSinceLastLog: Date.now() - lastEnvLogTime
34795
- }
34796
- });
34797
- return {
34798
- code: 500,
34799
- message: "账号签名生成失败,请稍后重试。",
34800
- data: check
34801
- };
34802
- }
34803
34838
  const baseInfoStart = Date.now();
34804
34839
  const _baseInfo = http.api({
34805
34840
  method: "get",
34806
34841
  baseURL: "https://creator.xiaohongshu.com",
34807
- url: loginBasePath,
34808
- headers: loginBaseXsHeader
34842
+ url: loginBasePath
34809
34843
  }, {
34810
34844
  retries: 3,
34811
- retryDelay: 20,
34812
- timeout: 5000
34845
+ retryDelay: 300,
34846
+ timeout: 30000
34813
34847
  }).catch((e)=>{
34814
34848
  const clientTimestamp = Date.now();
34815
34849
  const serverDate = e?.extra?.serverDate;
34816
34850
  const serverTimestamp = serverDate ? new Date(serverDate).getTime() : null;
34817
34851
  const timeDriftMs = serverTimestamp ? clientTimestamp - serverTimestamp : null;
34818
- _task.logger?.warn("[XhsSessionCheck] creator base 接口请求失败", {
34852
+ _task.logger?.warn("[XhsSessionCheck] creator personal_info 接口请求失败", {
34819
34853
  accountId: params.accountId,
34820
34854
  duration: Date.now() - baseInfoStart,
34821
34855
  code: e?.code,
@@ -34833,7 +34867,31 @@ var __webpack_exports__ = {};
34833
34867
  });
34834
34868
  const webSessionPath = "/api/sns/web/unread_count";
34835
34869
  const webSessionData = {};
34836
- const webSessionXsHeader = sessionCheck_xsEncrypt.signHeadersPost(webSessionPath, recordCookie, "xhs-pc-web", webSessionData);
34870
+ let webSessionXsHeader;
34871
+ try {
34872
+ webSessionXsHeader = sessionCheck_xsEncrypt.signHeadersPost(webSessionPath, recordCookie, "xhs-pc-web", webSessionData);
34873
+ } catch (signError) {
34874
+ _task.logger?.error("[XhsSessionCheck] 签名生成失败 - 环境快照", {
34875
+ accountId: params.accountId,
34876
+ error: signError instanceof Error ? signError.message : String(signError),
34877
+ stack: _task.debug ? signError instanceof Error ? signError.stack : void 0 : void 0,
34878
+ hasA1: !!recordCookie.a1,
34879
+ env: {
34880
+ processType: process.type,
34881
+ memoryUsage: {
34882
+ heapUsed: `${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB`,
34883
+ heapTotal: `${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)} MB`
34884
+ },
34885
+ hasProxy: !!params.proxyLoc,
34886
+ timeSinceLastLog: Date.now() - lastEnvLogTime
34887
+ }
34888
+ });
34889
+ return {
34890
+ code: 500,
34891
+ message: "账号签名生成失败,请稍后重试。",
34892
+ data: check
34893
+ };
34894
+ }
34837
34895
  const _web_session = http.api({
34838
34896
  method: "GET",
34839
34897
  url: "https://edith.xiaohongshu.com/api/sns/web/unread_count",
@@ -34841,8 +34899,8 @@ var __webpack_exports__ = {};
34841
34899
  headers: webSessionXsHeader
34842
34900
  }, {
34843
34901
  retries: 3,
34844
- retryDelay: 20,
34845
- timeout: 5000
34902
+ retryDelay: 300,
34903
+ timeout: 30000
34846
34904
  });
34847
34905
  const [baseInfo, web_session] = await Promise.all([
34848
34906
  _baseInfo,
@@ -34934,6 +34992,10 @@ var __webpack_exports__ = {};
34934
34992
  };
34935
34993
  return success(data, message);
34936
34994
  };
34995
+ const extractEncFileKey = (downloadUrl)=>{
34996
+ if (!downloadUrl) return "";
34997
+ return downloadUrl.split("encfilekey=")[1]?.split("&")[0] || "";
34998
+ };
34937
34999
  const rid = ()=>`${Math.floor(Date.now() / 1e3).toString(16)}-${[
34938
35000
  ...Array(8)
34939
35001
  ].map(()=>Math.floor(16 * Math.random()).toString(16)).join("")}`;
@@ -40579,7 +40641,8 @@ var __webpack_exports__ = {};
40579
40641
  },
40580
40642
  _task.logger,
40581
40643
  params.proxyLoc,
40582
- params.accountId
40644
+ params.accountId,
40645
+ "xiaohongshu"
40583
40646
  ];
40584
40647
  const http = new Http(...args);
40585
40648
  let unreadCount = {
@@ -40608,8 +40671,8 @@ var __webpack_exports__ = {};
40608
40671
  headers: xsHeader
40609
40672
  }, {
40610
40673
  retries: 3,
40611
- retryDelay: 20,
40612
- timeout: 3000
40674
+ retryDelay: 300,
40675
+ timeout: 30000
40613
40676
  });
40614
40677
  const isSuccess = 0 === res.code;
40615
40678
  if (isSuccess) unreadCount = res.data;
@@ -41022,7 +41085,8 @@ var __webpack_exports__ = {};
41022
41085
  },
41023
41086
  _task.logger,
41024
41087
  params.proxyLoc,
41025
- params.accountId
41088
+ params.accountId,
41089
+ "xiaohongshu"
41026
41090
  ];
41027
41091
  const http = new Http(...args);
41028
41092
  const xsEncrypt = new Xhshow();
@@ -41038,8 +41102,8 @@ var __webpack_exports__ = {};
41038
41102
  url: "https://creator.xiaohongshu.com/api/galaxy/creator/home/personal_info"
41039
41103
  }, {
41040
41104
  retries: 3,
41041
- retryDelay: 20,
41042
- timeout: 3000
41105
+ retryDelay: 300,
41106
+ timeout: 30000
41043
41107
  }),
41044
41108
  http.api({
41045
41109
  method: "get",
@@ -41048,8 +41112,8 @@ var __webpack_exports__ = {};
41048
41112
  headers: sevenDataXsHeader
41049
41113
  }, {
41050
41114
  retries: 3,
41051
- retryDelay: 20,
41052
- timeout: 3000
41115
+ retryDelay: 300,
41116
+ timeout: 30000
41053
41117
  })
41054
41118
  ]);
41055
41119
  const xhsData = {
@@ -41956,9 +42020,10 @@ var __webpack_exports__ = {};
41956
42020
  timeout: 3000
41957
42021
  });
41958
42022
  }
42023
+ const isPublished = (note)=>!note.schedule_post_time;
41959
42024
  const articleInfo = await fetchArticles(pageNum, onlySuccess);
41960
42025
  let hasNextpage = -1 !== articleInfo.data.page;
41961
- const filtered = articleInfo.data.notes;
42026
+ const filtered = articleInfo.data.notes.filter(isPublished);
41962
42027
  let currentPage = pageNum + 1;
41963
42028
  const usedPages = new Set();
41964
42029
  while(filtered.length < pageSize && hasNextpage){
@@ -41968,7 +42033,7 @@ var __webpack_exports__ = {};
41968
42033
  }
41969
42034
  const res = await fetchArticles(currentPage, onlySuccess);
41970
42035
  usedPages.add(currentPage);
41971
- const validItems = res.data.notes;
42036
+ const validItems = res.data.notes.filter(isPublished);
41972
42037
  filtered.push(...validItems);
41973
42038
  currentPage++;
41974
42039
  hasNextpage = -1 !== res.data.page;
@@ -43911,7 +43976,7 @@ var __webpack_exports__ = {};
43911
43976
  name: params.music.name,
43912
43977
  artist: params.music.authorName,
43913
43978
  mediaStreamingUrl: params.music.url,
43914
- docType: params.music.raw.playableInfo.type
43979
+ docType: 2 === params.music.raw.bgmSource ? 0 : 1
43915
43980
  },
43916
43981
  groupId: params.music.id,
43917
43982
  hasBgm: 1,
@@ -44088,7 +44153,7 @@ var __webpack_exports__ = {};
44088
44153
  const resultMsg = publishResult.data?.baseResp?.errmsg ?? publishResult.errMsg;
44089
44154
  if (0 === resultCode) {
44090
44155
  task.logger.info("[shipinhaoPublish] 发布成功");
44091
- const publishId = uploadedImages[0]?.thumbUrl?.split("encfilekey=")[1]?.split("&")[0] || "";
44156
+ const publishId = extractEncFileKey(uploadedImages[0]?.thumbUrl);
44092
44157
  await updateTaskState?.({
44093
44158
  state: types_TaskState.SUCCESS,
44094
44159
  result: {
@@ -44983,8 +45048,7 @@ var __webpack_exports__ = {};
44983
45048
  const partTimeout = tuning?.partTimeout ?? DEFAULT_TUNING.partTimeout;
44984
45049
  const partRetries = tuning?.partRetries ?? DEFAULT_TUNING.partRetries;
44985
45050
  const completeTimeout = tuning?.completeTimeout ?? DEFAULT_TUNING.completeTimeout;
44986
- logger?.info(`开始上传: ${fileName} (${fileSize} B, filetype=${fileType})`);
44987
- logger?.info(`上传超时策略: 单片 ${partTimeout / 1000}s(重试 ${partRetries} 次)、合并 ${completeTimeout / 1000}s`);
45051
+ logger?.info(`[shipinhaoPublishVideo] 开始上传: ${fileName} (${fileSize} B, filetype=${fileType})`);
44988
45052
  const fileMd5 = await computeFileMd5(filePath);
44989
45053
  const taskId = generateTaskId(fileName, fileSize, fileMd5);
44990
45054
  const baseUrl = "https://finderassistancea.video.qq.com";
@@ -44995,7 +45059,7 @@ var __webpack_exports__ = {};
44995
45059
  const chunkCount = Math.ceil(fileSize / CHUNK_SIZE);
44996
45060
  const blockPartLength = [];
44997
45061
  for(let i = 0; i < chunkCount; i++)blockPartLength.push(Math.min((i + 1) * CHUNK_SIZE, fileSize));
44998
- logger?.info(`申请 UploadID: ${chunkCount} 片`);
45062
+ logger?.info(`[shipinhaoPublishVideo] 视频分片: ${chunkCount} 片`);
44999
45063
  const applyRes = await http.api({
45000
45064
  method: "PUT",
45001
45065
  url: `${baseUrl}/applyuploaddfs`,
@@ -45016,7 +45080,6 @@ var __webpack_exports__ = {};
45016
45080
  let uploadId = applyRes.UploadID;
45017
45081
  const uploadedParts = new Set();
45018
45082
  if (applyRes.ListPartsResult) {
45019
- logger?.info("检测到已上传分片,执行续传");
45020
45083
  const parts = Array.isArray(applyRes.ListPartsResult.Part) ? applyRes.ListPartsResult.Part : applyRes.ListPartsResult.Part ? [
45021
45084
  applyRes.ListPartsResult.Part
45022
45085
  ] : [];
@@ -45052,7 +45115,6 @@ var __webpack_exports__ = {};
45052
45115
  PartNumber: partNumber,
45053
45116
  ETag: existing.ETag
45054
45117
  });
45055
- logger?.info(`分片 ${partNumber}/${chunkCount} 已存在,跳过`);
45056
45118
  continue;
45057
45119
  }
45058
45120
  }
@@ -45077,18 +45139,15 @@ var __webpack_exports__ = {};
45077
45139
  retries: partRetries,
45078
45140
  retryDelay: 2000
45079
45141
  });
45080
- const partElapsed = Date.now() - partStart;
45081
- const throughput = Math.round(chunkSize / (partElapsed / 1000));
45142
+ Date.now();
45082
45143
  partInfo.push({
45083
45144
  PartNumber: partNumber,
45084
45145
  ETag: `"${chunkMd5}"`
45085
45146
  });
45086
- logger?.info(`分片 ${partNumber}/${chunkCount} 完成 (${chunkSize} B, ${partElapsed}ms, ${Math.round(throughput / 1024)}KB/s)`);
45087
45147
  }
45088
45148
  } finally{
45089
45149
  external_node_fs_default().closeSync(fd);
45090
45150
  }
45091
- logger?.info("合并分片...");
45092
45151
  const completeRes = await http.api({
45093
45152
  method: "POST",
45094
45153
  url: `${baseUrl}/completepartuploaddfs?UploadID=${encodeURIComponent(uploadId)}`,
@@ -45106,7 +45165,7 @@ var __webpack_exports__ = {};
45106
45165
  retryDelay: 3000
45107
45166
  });
45108
45167
  if (!completeRes.DownloadURL) throw new Error("合并分片失败: " + JSON.stringify(completeRes));
45109
- logger?.info("上传成功");
45168
+ logger?.info(`[shipinhaoPublishVideo] ${fileName} 上传成功`);
45110
45169
  return {
45111
45170
  downloadUrl: completeRes.DownloadURL,
45112
45171
  md5: fileMd5,
@@ -45424,6 +45483,7 @@ var __webpack_exports__ = {};
45424
45483
  "avc3"
45425
45484
  ];
45426
45485
  const MIN_TITLE_LENGTH = 6;
45486
+ const MAX_TITLE_LENGTH = 16;
45427
45487
  function formatFileSize(bytes) {
45428
45488
  if (bytes < 1048576) return `${(bytes / 1024).toFixed(2)} KB`;
45429
45489
  if (bytes < 1073741824) return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
@@ -45450,10 +45510,11 @@ var __webpack_exports__ = {};
45450
45510
  function validateShipinhaoTitle(title) {
45451
45511
  if (void 0 === title) return null;
45452
45512
  const trimmed = title.trim();
45513
+ if ("" === trimmed) return null;
45453
45514
  const length = [
45454
45515
  ...trimmed
45455
45516
  ].length;
45456
- if (length < MIN_TITLE_LENGTH) return `视频号标题至少需要 ${MIN_TITLE_LENGTH} 个字符,请补充后重试。`;
45517
+ if (length < MIN_TITLE_LENGTH || length > MAX_TITLE_LENGTH) return `视频号标题需要在 ${MIN_TITLE_LENGTH}-${MAX_TITLE_LENGTH} 个字符之间,当前 ${length} 个字符,请调整后重试。`;
45457
45518
  return null;
45458
45519
  }
45459
45520
  const POST_CREATE_PAGE_URL = "https://channels.weixin.qq.com/micro/content/post/create";
@@ -45498,7 +45559,6 @@ var __webpack_exports__ = {};
45498
45559
  };
45499
45560
  }
45500
45561
  async function getTraceKey(auth, client, http, logger) {
45501
- logger.info("[getTraceKey] 开始获取 traceKey...");
45502
45562
  const res = await http.api({
45503
45563
  method: "POST",
45504
45564
  url: `${MICRO_CONTENT_BASE}/post/get-finder-post-trace-key`,
@@ -45513,11 +45573,9 @@ var __webpack_exports__ = {};
45513
45573
  logger.error("[getTraceKey] 获取失败:", JSON.stringify(res));
45514
45574
  throw new Error(`获取 traceKey 失败: ${JSON.stringify(res)}`);
45515
45575
  }
45516
- logger.info(`[getTraceKey] 获取成功: ${res.data.traceKey}`);
45517
45576
  return res.data.traceKey;
45518
45577
  }
45519
45578
  async function getObjectTagKey(auth, client, http, logger) {
45520
- logger.info("[getObjectTagKey] 获取内容声明 tagKey...");
45521
45579
  try {
45522
45580
  const res = await http.api({
45523
45581
  method: "POST",
@@ -45533,7 +45591,6 @@ var __webpack_exports__ = {};
45533
45591
  logger.warn(`[getObjectTagKey] 未取到 tagKey: ${JSON.stringify(res)}`);
45534
45592
  return null;
45535
45593
  }
45536
- logger.info(`[getObjectTagKey] tagKey: ${res.data.tagKey}`);
45537
45594
  return res.data.tagKey;
45538
45595
  } catch (error) {
45539
45596
  logger.warn(`[getObjectTagKey] 获取 tagKey 异常: ${stringifyError(error)}`);
@@ -45542,7 +45599,6 @@ var __webpack_exports__ = {};
45542
45599
  }
45543
45600
  async function submitAndPollTranscode(opts) {
45544
45601
  const { videoUrl, videoMeta, traceKey, uploadStartTime, uploadEndTime, finderUsername, client, http, logger } = opts;
45545
- logger.info("[submitAndPollTranscode] 开始提交转码任务...");
45546
45602
  const finderUrl = videoUrl.includes("wxapp.tc.qq.com") ? `https://finder.video.qq.com${videoUrl.split("qq.com")[1]}` : videoUrl;
45547
45603
  logger.info(`[submitAndPollTranscode] 视频尺寸: ${videoMeta.width}x${videoMeta.height}, 时长: ${videoMeta.duration}s`);
45548
45604
  const submitRes = await http.api({
@@ -45581,12 +45637,10 @@ var __webpack_exports__ = {};
45581
45637
  throw new Error(`提交转码失败: ${JSON.stringify(submitRes)}`);
45582
45638
  }
45583
45639
  const { clipKey, draftId } = submitRes.data;
45584
- logger.info(`[submitAndPollTranscode] 转码任务已提交,clipKey: ${clipKey}, draftId: ${draftId}`);
45585
45640
  const pollInterval = 5000;
45586
45641
  const pollBudget = Math.min(1800000, 300000 + 1000 * Math.ceil(1.5 * videoMeta.duration));
45587
45642
  const maxPolls = Math.ceil(pollBudget / pollInterval);
45588
45643
  let pollCount = 0;
45589
- logger.info(`[submitAndPollTranscode] 开始轮询转码结果,最多 ${maxPolls} 次(${Math.round(pollBudget / 1000)}s),间隔 ${pollInterval / 1000}s`);
45590
45644
  while(pollCount < maxPolls){
45591
45645
  await mock_sleep(pollInterval);
45592
45646
  pollCount++;
@@ -45610,14 +45664,12 @@ var __webpack_exports__ = {};
45610
45664
  throw new Error(`转码轮询失败 (poll ${pollCount}): ${JSON.stringify(pollRes)}`);
45611
45665
  }
45612
45666
  const { flag, url, width, height, duration, md5, fileSize } = pollRes.data || {};
45613
- logger.info(`[submitAndPollTranscode] 轮询第 ${pollCount} 次,flag=${flag}`);
45614
45667
  if (1 === flag) {
45615
45668
  if (!url || !width || !height || !duration || !md5 || !fileSize) {
45616
45669
  logger.error("[submitAndPollTranscode] 转码完成但返回数据不完整:", JSON.stringify(pollRes.data));
45617
45670
  throw new Error(`转码完成但返回数据不完整: ${JSON.stringify(pollRes.data)}`);
45618
45671
  }
45619
45672
  logger.info(`[submitAndPollTranscode] 转码完成! 用时: ${pollCount * pollInterval / 1000}s`);
45620
- logger.info(`[submitAndPollTranscode] 视频信息: ${width}x${height}, 时长: ${duration}s, 大小: ${fileSize}`);
45621
45673
  return {
45622
45674
  clipKey,
45623
45675
  url,
@@ -45628,7 +45680,7 @@ var __webpack_exports__ = {};
45628
45680
  fileSize
45629
45681
  };
45630
45682
  }
45631
- if (2 === flag) logger.info(`[submitAndPollTranscode] 转码中... (${pollCount}/${maxPolls})`);
45683
+ if (2 === flag) ;
45632
45684
  else {
45633
45685
  logger.error(`[submitAndPollTranscode] 转码失败,未知 flag=${flag}:`, JSON.stringify(pollRes.data));
45634
45686
  throw new Error(`转码失败,未知 flag=${flag}: ${JSON.stringify(pollRes.data)}`);
@@ -45639,16 +45691,11 @@ var __webpack_exports__ = {};
45639
45691
  }
45640
45692
  async function publishVideo(opts) {
45641
45693
  const { params, auth, client, clipResult, videoUpload, coverUpload, verticalCoverUpload, videoMeta, traceKey, tagKey, uploadStartTime, uploadEndTime, proxyHttp, logger } = opts;
45642
- logger.info("[publishVideo] 开始构建发布请求...");
45643
45694
  const toFinderUrl = (url)=>url.includes("wxapp.tc.qq.com") ? `https://finder.video.qq.com${url.split("qq.com")[1]}` : url;
45644
45695
  const thumbFinderUrl = toFinderUrl(coverUpload.downloadUrl);
45645
45696
  const coverFinderUrl = toFinderUrl(verticalCoverUpload.downloadUrl);
45646
45697
  const md5sumUuid = external_node_crypto_default().randomUUID();
45647
45698
  const description = params.description;
45648
- logger.info("[publishVideo] 发布参数:");
45649
- logger.info(` - 短标题: ${params.title || "(无)"}`);
45650
- logger.info(` - 描述: ${description.substring(0, 50)}${description.length > 50 ? "..." : ""}`);
45651
- logger.info(` - 定时发布: ${params.scheduledTime ? new Date(1000 * params.scheduledTime).toLocaleString() : "立即发布"}`);
45652
45699
  const objectDesc = {
45653
45700
  mpTitle: "",
45654
45701
  description,
@@ -45722,7 +45769,6 @@ var __webpack_exports__ = {};
45722
45769
  };
45723
45770
  if (params.scheduledTime) publishData.effectiveTime = params.scheduledTime;
45724
45771
  if (params.tagInfo && tagKey) publishData.tagInfo = buildTagInfo(params.tagInfo, tagKey);
45725
- logger.info("[publishVideo] 开始发布视频,全部参数:" + JSON.stringify(publishData));
45726
45772
  const publishRes = await proxyHttp.api({
45727
45773
  method: "POST",
45728
45774
  url: `${MICRO_CONTENT_BASE}/post/post_create`,
@@ -45730,7 +45776,7 @@ var __webpack_exports__ = {};
45730
45776
  data: publishData,
45731
45777
  defaultErrorMsg: "发布视频失败"
45732
45778
  });
45733
- logger.info(`[publishVideo] 发布响应: errCode=${publishRes.errCode}, baseResp.errcode=${publishRes.data?.baseResp?.errcode}`);
45779
+ logger.info(`[publishVideo] 发布结果: errCode=${publishRes.errCode}, baseResp.errcode=${publishRes.data?.baseResp?.errcode}`);
45734
45780
  return publishRes;
45735
45781
  }
45736
45782
  function mock_sleep(ms) {
@@ -45744,11 +45790,9 @@ var __webpack_exports__ = {};
45744
45790
  return savePath;
45745
45791
  }
45746
45792
  const shipinhaoPublishVideo_mock_mockAction = async (task, params)=>{
45747
- task.logger.info("[shipinhaoPublishVideo] 开始执行视频号视频发布 - Mock API 方式");
45748
45793
  const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
45749
45794
  let currentStep = "初始化";
45750
45795
  try {
45751
- task.logger.info(`[shipinhaoPublishVideo] 发布方式: ${params.scheduledTime ? `定时 ${new Date(1000 * params.scheduledTime).toLocaleString()}` : "立即发布"}`);
45752
45796
  currentStep = "解析认证信息";
45753
45797
  const cookieString = params.cookies.map((c)=>`${c.name}=${c.value}`).join("; ");
45754
45798
  const http = new Http({
@@ -45760,11 +45804,8 @@ var __webpack_exports__ = {};
45760
45804
  if (!params.videoPath) return utils_response(414, "视频文件路径不能为空", "");
45761
45805
  if (!params.coverPath) return utils_response(414, "横屏封面图片路径不能为空", "");
45762
45806
  currentStep = "获取上传认证";
45763
- task.logger.info("[shipinhaoPublishVideo] 获取上传认证...");
45764
45807
  const auth = await getShipinhaoUploadAuth(cookieString, http);
45765
45808
  const client = resolveClientContext(params, auth.uin);
45766
- if (!client.aId) task.logger.warn("[shipinhaoPublishVideo] extraParam.aId 缺失,query 将不带 _aid");
45767
- if (!client.fingerPrintDeviceId) task.logger.warn("[shipinhaoPublishVideo] extraParam.fingerPrintDeviceId 缺失,请求将不带 finger-print-device-id");
45768
45809
  const publishHeaders = buildPublishHeaders(cookieString, client);
45769
45810
  const microHttp = new Http({
45770
45811
  headers: publishHeaders
@@ -45780,25 +45821,20 @@ var __webpack_exports__ = {};
45780
45821
  ];
45781
45822
  const proxyHttp = new Http(...args);
45782
45823
  currentStep = "组装视频元数据";
45783
- task.logger.info("[shipinhaoPublishVideo] 组装视频元数据...");
45784
45824
  const videoMeta = buildVideoMetaFromParams(params.videoPath, params.videoMetadata);
45785
45825
  task.logger.info(`[shipinhaoPublishVideo] 视频: ${videoMeta.width}×${videoMeta.height}, ${videoMeta.duration.toFixed(2)}s, ${(videoMeta.fileSize / 1024 / 1024).toFixed(2)}MB, codec=${videoMeta.codec || "unknown"}`);
45786
- if (!videoMeta.codec) task.logger.warn("[shipinhaoPublishVideo] 未能读取视频编码格式,跳过 H.264 预检,交由服务端判断");
45787
45826
  currentStep = "校验视频限制";
45788
45827
  const validationError = validateShipinhaoVideo(params.videoPath, videoMeta);
45789
45828
  if (validationError) {
45790
- task.logger.error(`[shipinhaoPublishVideo] 视频校验未通过: ${validationError}`);
45791
45829
  await updateTaskState?.({
45792
45830
  state: types_TaskState.FAILED,
45793
45831
  error: validationError
45794
45832
  });
45795
45833
  return utils_response(414, validationError, "");
45796
45834
  }
45797
- task.logger.info("[shipinhaoPublishVideo] 视频校验通过");
45798
45835
  currentStep = "校验标题";
45799
45836
  const titleError = validateShipinhaoTitle(params.title);
45800
45837
  if (titleError) {
45801
- task.logger.error(`[shipinhaoPublishVideo] 标题校验未通过: ${titleError}`);
45802
45838
  await updateTaskState?.({
45803
45839
  state: types_TaskState.FAILED,
45804
45840
  error: titleError
@@ -45806,7 +45842,6 @@ var __webpack_exports__ = {};
45806
45842
  return utils_response(414, titleError, "");
45807
45843
  }
45808
45844
  currentStep = "获取 traceKey";
45809
- task.logger.info("[shipinhaoPublishVideo] 获取 traceKey...");
45810
45845
  const traceKey = await getTraceKey(auth, client, microHttp, task.logger);
45811
45846
  let tagKey = null;
45812
45847
  if (params.tagInfo) {
@@ -45814,11 +45849,7 @@ var __webpack_exports__ = {};
45814
45849
  tagKey = await getObjectTagKey(auth, client, microHttp, task.logger);
45815
45850
  }
45816
45851
  const uploadStartTime = Math.floor(Date.now() / 1000);
45817
- task.logger.info(`[shipinhaoPublishVideo] 上传开始时间: ${uploadStartTime}`);
45818
45852
  currentStep = "上传视频";
45819
- task.logger.info("[shipinhaoPublishVideo] 上传视频...");
45820
- task.logger.info(`[shipinhaoPublishVideo] 视频路径: ${params.videoPath}`);
45821
- task.logger.info(`[shipinhaoPublishVideo] 视频文件类型: ${auth.videoFileType}`);
45822
45853
  const videoUpload = await uploader_uploadFile({
45823
45854
  filePath: params.videoPath,
45824
45855
  fileType: auth.videoFileType,
@@ -45827,12 +45858,10 @@ var __webpack_exports__ = {};
45827
45858
  http,
45828
45859
  logger: task.logger
45829
45860
  });
45830
- task.logger.info("[shipinhaoPublishVideo] 视频上传完成");
45831
45861
  const uploadEndTime = Math.floor(Date.now() / 1000);
45832
- task.logger.info(`[shipinhaoPublishVideo] 上传结束时间: ${uploadEndTime}, 耗时: ${uploadEndTime - uploadStartTime}s`);
45862
+ task.logger.info(`[shipinhaoPublishVideo] 耗时: ${uploadEndTime - uploadStartTime}s`);
45833
45863
  currentStep = "上传横屏封面";
45834
45864
  const localCoverPath = await resolveLocalCoverPath(params.coverPath, "横屏封面", task.getTmpPath(), task.logger);
45835
- task.logger.info("[shipinhaoPublishVideo] 上传横屏封面...");
45836
45865
  const coverUpload = await uploader_uploadFile({
45837
45866
  filePath: localCoverPath,
45838
45867
  fileType: auth.pictureFileType,
@@ -45841,12 +45870,10 @@ var __webpack_exports__ = {};
45841
45870
  http,
45842
45871
  logger: task.logger
45843
45872
  });
45844
- task.logger.info("[shipinhaoPublishVideo] 横屏封面上传完成");
45845
45873
  let verticalCoverUpload = coverUpload;
45846
45874
  if (params.verticalCoverPath) {
45847
45875
  currentStep = "上传竖屏封面";
45848
45876
  const localVerticalPath = await resolveLocalCoverPath(params.verticalCoverPath, "竖屏封面", task.getTmpPath(), task.logger);
45849
- task.logger.info("[shipinhaoPublishVideo] 上传竖屏封面");
45850
45877
  verticalCoverUpload = await uploader_uploadFile({
45851
45878
  filePath: localVerticalPath,
45852
45879
  fileType: auth.pictureFileType,
@@ -45855,10 +45882,8 @@ var __webpack_exports__ = {};
45855
45882
  http,
45856
45883
  logger: task.logger
45857
45884
  });
45858
- task.logger.info("[shipinhaoPublishVideo] 竖屏封面上传完成");
45859
- } else task.logger.info("[shipinhaoPublishVideo] 未传竖屏封面,复用横屏封面");
45885
+ }
45860
45886
  currentStep = "提交转码";
45861
- task.logger.info("[shipinhaoPublishVideo] 提交转码...");
45862
45887
  const clipResult = await submitAndPollTranscode({
45863
45888
  videoUrl: videoUpload.downloadUrl,
45864
45889
  videoMeta,
@@ -45871,8 +45896,6 @@ var __webpack_exports__ = {};
45871
45896
  logger: task.logger
45872
45897
  });
45873
45898
  currentStep = "发布视频";
45874
- task.logger.info("[shipinhaoPublishVideo] 发布视频...");
45875
- task.logger.info(`[shipinhaoPublishVideo] clipKey: ${clipResult.clipKey}`);
45876
45899
  let publishResult;
45877
45900
  try {
45878
45901
  publishResult = await publishVideo({
@@ -45897,7 +45920,6 @@ var __webpack_exports__ = {};
45897
45920
  const classified = classifyPublishError(handledError);
45898
45921
  if (classified) {
45899
45922
  const message = `${classified.userMessage}${task.debug ? ` ${http.proxyInfo}` : ""}`;
45900
- task.logger.error(`[shipinhaoPublishVideo] ${classified.category},直接返回: ${handledError.message} (code=${handledError.code})`, stringifyError(handledError));
45901
45923
  await updateTaskState?.({
45902
45924
  state: types_TaskState.FAILED,
45903
45925
  error: message
@@ -45914,11 +45936,8 @@ var __webpack_exports__ = {};
45914
45936
  const resultCode = publishResult.data?.baseResp?.errcode ?? publishResult.errCode;
45915
45937
  const resultMsg = publishResult.data?.baseResp?.errmsg ?? (0 === resultCode ? "发布成功" : `发布失败(errCode=${resultCode})`);
45916
45938
  if (0 === resultCode) {
45917
- task.logger.info("[shipinhaoPublishVideo] 发布成功");
45918
- task.logger.info(`[shipinhaoPublishVideo] 作品ID: ${clipResult.clipKey}`);
45919
- task.logger.info(`[shipinhaoPublishVideo] 视频URL: ${clipResult.url}`);
45920
- task.logger.info(`[shipinhaoPublishVideo] 横屏封面URL: ${coverUpload.downloadUrl}`);
45921
- task.logger.info(`[shipinhaoPublishVideo] 竖屏封面URL: ${verticalCoverUpload.downloadUrl}`);
45939
+ const publishId = extractEncFileKey(verticalCoverUpload.downloadUrl);
45940
+ if (!publishId) task.logger.error(`[shipinhaoPublishVideo] 封面 DownloadURL 中未解析到 encfilekey,关联 id 为空: ${verticalCoverUpload.downloadUrl}`);
45922
45941
  await updateTaskState?.({
45923
45942
  state: types_TaskState.SUCCESS,
45924
45943
  result: {
@@ -45948,8 +45967,7 @@ var __webpack_exports__ = {};
45948
45967
  },
45949
45968
  platform: "shipinhao"
45950
45969
  });
45951
- task.logger.info("[shipinhaoPublishVideo] 日志上报完成");
45952
- return utils_response(0, "发布成功", clipResult.clipKey);
45970
+ return utils_response(0, "发布成功", publishId);
45953
45971
  }
45954
45972
  let errorMessage = resultMsg;
45955
45973
  if (-11224 === resultCode) errorMessage = "视频号管理员完成实名且绑定手机号后才可以发表";
@@ -45961,18 +45979,16 @@ var __webpack_exports__ = {};
45961
45979
  state: types_TaskState.FAILED,
45962
45980
  error: errorMessage
45963
45981
  });
45964
- return utils_response(resultCode || 414, errorMessage, "");
45982
+ return utils_response(414, errorMessage, "");
45965
45983
  } catch (error) {
45966
45984
  const handledError = Http.handleApiError(error);
45967
45985
  const errorMsg = handledError.message || "发布失败,请稍后重试";
45968
- const errorCode = handledError.code || 414;
45969
45986
  task.logger.error(`[shipinhaoPublishVideo] 发布流程异常 [${currentStep}]: ${errorMsg}`, stringifyError(error), handledError.extra);
45970
- task.logger.error(`[shipinhaoPublishVideo] 错误码: ${errorCode}, 当前步骤: ${currentStep}`);
45971
45987
  await updateTaskState?.({
45972
45988
  state: types_TaskState.FAILED,
45973
45989
  error: errorMsg
45974
45990
  });
45975
- return utils_response(errorCode, errorMsg, "");
45991
+ return utils_response(414, errorMsg, "");
45976
45992
  }
45977
45993
  };
45978
45994
  const shipinhaoPublishVideo_rpa_rpaAction = async (task, params)=>{
@@ -52544,4 +52560,4 @@ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_targe
52544
52560
  });
52545
52561
 
52546
52562
  //# sourceMappingURL=bundle.js.map
52547
- //# debugId=ed6f9fc8-db66-5df4-be7c-d5593224a8b2
52563
+ //# debugId=fb6eb3b8-9fcc-53e7-9e60-cd649507d5fa