@iflyrpa/actions 2.0.0-beta.7 → 2.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/bundle.js CHANGED
@@ -4938,7 +4938,7 @@ var __webpack_modules__ = {
4938
4938
  module.exports = GenXSCommon;
4939
4939
  },
4940
4940
  "./src/utils/douyin/csrfToken.js": function(module, __unused_webpack_exports, __webpack_require__) {
4941
- const crypto1 = __webpack_require__("crypto");
4941
+ const crypto = __webpack_require__("crypto");
4942
4942
  function generateCsrfToken(options = {}) {
4943
4943
  const { cookies = [], url = '', method = 'POST' } = options;
4944
4944
  const sessionid = getCookieValue(cookies, 'sessionid') || '';
@@ -4950,7 +4950,7 @@ var __webpack_modules__ = {
4950
4950
  const timestampHex = timestamp.toString(16).padStart(8, '0');
4951
4951
  const random = generateRandomHex(8);
4952
4952
  const signData = `${method}${url}${sessionid}${uid_tt}${msToken}${ttwid}${timestamp}`;
4953
- const hash = crypto1.createHash('md5').update(signData).digest('hex');
4953
+ const hash = crypto.createHash('md5').update(signData).digest('hex');
4954
4954
  const csrfToken = `0001${version}${timestampHex}${random}${hash}`;
4955
4955
  return csrfToken;
4956
4956
  }
@@ -4959,7 +4959,7 @@ var __webpack_modules__ = {
4959
4959
  return cookie ? cookie.value : '';
4960
4960
  }
4961
4961
  function generateRandomHex(length) {
4962
- const bytes = crypto1.randomBytes(Math.ceil(length / 2));
4962
+ const bytes = crypto.randomBytes(Math.ceil(length / 2));
4963
4963
  return bytes.toString('hex').slice(0, length);
4964
4964
  }
4965
4965
  function generateCsrfTokenAdvanced(options = {}) {
@@ -4992,8 +4992,8 @@ var __webpack_modules__ = {
4992
4992
  userAgent
4993
4993
  ].filter(Boolean);
4994
4994
  const signData = signParts.join('|');
4995
- const firstHash = crypto1.createHash('md5').update(signData).digest('hex');
4996
- const secondHash = crypto1.createHash('md5').update(firstHash + timestamp).digest('hex');
4995
+ const firstHash = crypto.createHash('md5').update(signData).digest('hex');
4996
+ const secondHash = crypto.createHash('md5').update(firstHash + timestamp).digest('hex');
4997
4997
  const timestampHex = timestampSec.toString(16).padStart(8, '0');
4998
4998
  const random = generateRandomHex(16);
4999
4999
  return `0001000${timestampHex.slice(0, 2)}${random}${secondHash}`;
@@ -5002,7 +5002,7 @@ var __webpack_modules__ = {
5002
5002
  const sessionid = getCookieValue(cookies, 'sessionid') || 'default_session';
5003
5003
  const timestamp = Math.floor(Date.now() / 1000);
5004
5004
  const random = generateRandomHex(32);
5005
- const hash = crypto1.createHash('md5').update(`${sessionid}${timestamp}${random}`).digest('hex');
5005
+ const hash = crypto.createHash('md5').update(`${sessionid}${timestamp}${random}`).digest('hex');
5006
5006
  const timestampHex = timestamp.toString(16).padStart(8, '0');
5007
5007
  return `0001000${timestampHex}${random}${hash}`.slice(0, 90);
5008
5008
  }
@@ -5401,7 +5401,7 @@ var __webpack_modules__ = {
5401
5401
  generateAuthorization: ()=>generateAuthorization,
5402
5402
  randomS: ()=>randomS
5403
5403
  });
5404
- const crypto1 = __webpack_require__("crypto");
5404
+ const crypto = __webpack_require__("crypto");
5405
5405
  const UNSIGNABLE_HEADERS = [
5406
5406
  'authorization',
5407
5407
  'content-type',
@@ -5412,10 +5412,10 @@ var __webpack_modules__ = {
5412
5412
  'x-amzn-trace-id'
5413
5413
  ];
5414
5414
  function sha256(data) {
5415
- return crypto1.createHash('sha256').update(data, 'utf8').digest('hex');
5415
+ return crypto.createHash('sha256').update(data, 'utf8').digest('hex');
5416
5416
  }
5417
5417
  function hmac(key, data) {
5418
- return crypto1.createHmac('sha256', key).update(data, 'utf8').digest();
5418
+ return crypto.createHmac('sha256', key).update(data, 'utf8').digest();
5419
5419
  }
5420
5420
  function getSigningKey(secretAccessKey, dateStamp, region, service) {
5421
5421
  const kDate = hmac('AWS4' + secretAccessKey, dateStamp);
@@ -5504,7 +5504,7 @@ var __webpack_modules__ = {
5504
5504
  canonicalRequestHash
5505
5505
  ].join('\n');
5506
5506
  const signingKey = getSigningKey(secretAccessKey, dateStamp, region, service);
5507
- const signature = crypto1.createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');
5507
+ const signature = crypto.createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');
5508
5508
  const authorization = `${algorithm} Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeadersStr}, Signature=${signature}`;
5509
5509
  return {
5510
5510
  authorization,
@@ -5537,19 +5537,19 @@ var __webpack_modules__ = {
5537
5537
  }
5538
5538
  },
5539
5539
  "./src/utils/douyin/reqSign.js.js": function(module, __unused_webpack_exports, __webpack_require__) {
5540
- const crypto1 = __webpack_require__("crypto");
5540
+ const crypto = __webpack_require__("crypto");
5541
5541
  function bufferToHex(buffer) {
5542
5542
  return buffer.toString('hex');
5543
5543
  }
5544
5544
  function generateReqSign(privateKeyPem, data) {
5545
5545
  try {
5546
- const privateKey = crypto1.createPrivateKey({
5546
+ const privateKey = crypto.createPrivateKey({
5547
5547
  key: privateKeyPem,
5548
5548
  format: 'pem',
5549
5549
  type: 'pkcs8'
5550
5550
  });
5551
5551
  const dataBuffer = Buffer.from(data, 'utf8');
5552
- const signature = crypto1.sign('sha256', dataBuffer, {
5552
+ const signature = crypto.sign('sha256', dataBuffer, {
5553
5553
  key: privateKey,
5554
5554
  dsaEncoding: 'der'
5555
5555
  });
@@ -9152,10 +9152,12 @@ var __webpack_exports__ = {};
9152
9152
  XhsWebSearchParamsSchema: ()=>XhsWebSearchParamsSchema,
9153
9153
  ttConfigDataSchema: ()=>ttConfigDataSchema,
9154
9154
  getFileState: ()=>getFileState,
9155
- DouyinPublishParamsSchema: ()=>DouyinPublishParamsSchema,
9156
9155
  DouyinGetMusicCategoryParamsSchema: ()=>DouyinGetMusicCategoryParamsSchema,
9156
+ DouyinPublishParamsSchema: ()=>DouyinPublishParamsSchema,
9157
9157
  xhsConfigDataSchema: ()=>xhsConfigDataSchema,
9158
9158
  SessionCheckResultSchema: ()=>SessionCheckResultSchema,
9159
+ DouyinGetCommentReplyListParamsSchema: ()=>DouyinGetCommentReplyListParamsSchema,
9160
+ DouyinCreateCommentReplyParamsSchema: ()=>DouyinCreateCommentReplyParamsSchema,
9159
9161
  DouyinGetHotParamsSchema: ()=>DouyinGetHotParamsSchema,
9160
9162
  DouyinGetMusicParamsSchema: ()=>DouyinGetMusicParamsSchema,
9161
9163
  FetchArticlesDataSchema: ()=>FetchArticlesDataSchema,
@@ -9169,6 +9171,7 @@ var __webpack_exports__ = {};
9169
9171
  DouyinGetCollectionParamsSchema: ()=>DouyinGetCollectionParamsSchema,
9170
9172
  ShipinhaoGetLocationParamsSchema: ()=>ShipinhaoGetLocationParamsSchema,
9171
9173
  DouyinGetTopicsParamsSchema: ()=>DouyinGetTopicsParamsSchema,
9174
+ DouyinGetCommentListParamsSchema: ()=>DouyinGetCommentListParamsSchema,
9172
9175
  UnreadCountSchema: ()=>UnreadCountSchema,
9173
9176
  ShipinhaoCheckLinkValidateParamsSchema: ()=>ShipinhaoCheckLinkValidateParamsSchema,
9174
9177
  ActionCommonParamsSchema: ()=>ActionCommonParamsSchema,
@@ -9179,6 +9182,7 @@ var __webpack_exports__ = {};
9179
9182
  BetaFlag: ()=>BetaFlag,
9180
9183
  bjhConfigDataSchema: ()=>bjhConfigDataSchema,
9181
9184
  BaijiahaoPublishParamsSchema: ()=>BaijiahaoPublishParamsSchema,
9185
+ DouyinGetWorkListParamsSchema: ()=>DouyinGetWorkListParamsSchema,
9182
9186
  version: ()=>package_namespaceObject_0.i8,
9183
9187
  Action: ()=>Action,
9184
9188
  ProxyAgent: ()=>ProxyAgent
@@ -9192,8 +9196,10 @@ var __webpack_exports__ = {};
9192
9196
  navigator: ()=>_navigator,
9193
9197
  origin: ()=>utils_origin
9194
9198
  });
9195
- var package_namespaceObject = JSON.parse('{"i8":"0.0.18-beta.0"}');
9196
- var package_namespaceObject_0 = JSON.parse('{"i8":"2.0.0-beta.6"}');
9199
+ var package_namespaceObject = {
9200
+ i8: "0.0.18"
9201
+ };
9202
+ var package_namespaceObject_0 = JSON.parse('{"i8":"2.0.0-beta.8"}');
9197
9203
  const external_node_fs_namespaceObject = require("node:fs");
9198
9204
  var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
9199
9205
  const external_node_https_namespaceObject = require("node:https");
@@ -25086,7 +25092,7 @@ var __webpack_exports__ = {};
25086
25092
  });
25087
25093
  } catch (e) {
25088
25094
  return {
25089
- code: 500,
25095
+ code: 414,
25090
25096
  message: `浏览器启动失败: ${e}`,
25091
25097
  data: {}
25092
25098
  };
@@ -30889,11 +30895,122 @@ var __webpack_exports__ = {};
30889
30895
  };
30890
30896
  return success(data, message);
30891
30897
  };
30898
+ const rid = ()=>`${Math.floor(Date.now() / 1e3).toString(16)}-${[
30899
+ ...Array(8)
30900
+ ].map(()=>Math.floor(16 * Math.random()).toString(16)).join("")}`;
30901
+ new Uint8Array(16);
30902
+ const hexTable = [];
30903
+ for(let i = 0; i < 256; i++)hexTable.push((i + 256).toString(16).substr(1));
30904
+ const createShipinhaoComment = async (_task, params)=>{
30905
+ if (!params.content || "" === params.content.trim()) return utils_response(400, "评论内容不能为空", void 0);
30906
+ if (!params.exportId) return utils_response(400, "exportId 不能为空", void 0);
30907
+ if (!params.extraParam) return utils_response(400, "缺少 extraParam 参数", void 0);
30908
+ if (!params.extraParam.fingerPrintDeviceId || !params.extraParam.aId || !params.extraParam.uin) return utils_response(400, "fingerPrintDeviceId、aId和uin不能为空", void 0);
30909
+ const headers = {
30910
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
30911
+ referer: "https://channels.weixin.qq.com/micro/interaction/comment",
30912
+ origin: "https://channels.weixin.qq.com",
30913
+ "content-type": "application/json",
30914
+ "finger-print-device-id": params.extraParam.fingerPrintDeviceId,
30915
+ "x-wechat-uin": params.extraParam.uin
30916
+ };
30917
+ const http = new Http({
30918
+ headers
30919
+ });
30920
+ const urlParams = new URLSearchParams({
30921
+ _aid: params.extraParam.aId,
30922
+ _rid: rid(),
30923
+ _pageUrl: "https://channels.weixin.qq.com/micro/interaction/comment"
30924
+ }).toString();
30925
+ const requestData = {
30926
+ replyCommentId: params.replyCommentId || "",
30927
+ content: params.content,
30928
+ clientId: `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`,
30929
+ rootCommentId: params.rootCommentId || "",
30930
+ comment: {},
30931
+ exportId: params.exportId,
30932
+ timestamp: Date.now().toString(),
30933
+ _log_finder_uin: "",
30934
+ _log_finder_id: params.extraParam.finderUserName || "",
30935
+ rawKeyBuff: null,
30936
+ pluginSessionId: null,
30937
+ scene: 7,
30938
+ reqScene: 7
30939
+ };
30940
+ if (params.rootCommentId) requestData.rootCommentId = params.rootCommentId;
30941
+ if (params.replyCommentId) requestData.replyCommentId = params.replyCommentId;
30942
+ const res = await http.api({
30943
+ method: "post",
30944
+ url: `https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/comment/create_comment?${urlParams}`,
30945
+ data: requestData
30946
+ });
30947
+ console.log(res, "----create comment res");
30948
+ const isSuccess = res?.errCode === 0;
30949
+ return utils_response(isSuccess ? 0 : 414, res?.errMsg || "添加评论失败", res.data);
30950
+ };
30951
+ const DouyinCreateCommentReplyParamsSchema = ActionCommonParamsSchema.extend({
30952
+ itemId: classic_schemas_string(),
30953
+ commentId: classic_schemas_string(),
30954
+ text: classic_schemas_string()
30955
+ });
30956
+ const { sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
30957
+ const { generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
30958
+ const douyinCreateCommentReply = async (_task, params)=>{
30959
+ const headers = {
30960
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
30961
+ referer: "https://creator.douyin.com/",
30962
+ origin: "https://creator.douyin.com/"
30963
+ };
30964
+ const args = [
30965
+ {
30966
+ headers
30967
+ },
30968
+ _task.logger,
30969
+ params.proxyLoc,
30970
+ params.localIP,
30971
+ params.accountId
30972
+ ];
30973
+ const http = new Http(...args);
30974
+ const csrfToken = generateCsrfTokenAdvanced(params.cookies);
30975
+ console.log("生成的 csrfToken:", csrfToken);
30976
+ const queryParams = {
30977
+ aid: "2906",
30978
+ msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
30979
+ a_bogus: ""
30980
+ };
30981
+ const aBogus = sign_reply(queryParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
30982
+ queryParams.a_bogus = aBogus;
30983
+ const queryString = new URLSearchParams(queryParams).toString();
30984
+ const body = {
30985
+ comment_Id: params.commentId,
30986
+ text: params.text,
30987
+ item_id: params.itemId
30988
+ };
30989
+ console.log("抖音添加评论回复参数:", body);
30990
+ const res = await http.api({
30991
+ method: "post",
30992
+ url: `https://creator.douyin.com/aweme/v1/creator/comment/reply/?${queryString}`,
30993
+ data: body,
30994
+ headers: {
30995
+ ...headers,
30996
+ "Content-Type": "application/json",
30997
+ "X-secsdk-csrf-token": csrfToken
30998
+ }
30999
+ }, {
31000
+ retries: 3,
31001
+ retryDelay: 20,
31002
+ timeout: 3000
31003
+ });
31004
+ console.log("抖音添加评论回复响应:", res);
31005
+ const isSuccess = 0 === res.status_code;
31006
+ const message = `抖音添加评论回复${isSuccess ? "成功" : `失败,原因:${res.status_msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
31007
+ return utils_response(isSuccess ? 0 : 414, message, res);
31008
+ };
30892
31009
  const DouyinGetCollectionParamsSchema = ActionCommonParamsSchema.extend({
30893
31010
  keyword: classic_schemas_string().optional(),
30894
31011
  count: classic_schemas_number().optional()
30895
31012
  });
30896
- const { sign_datail, sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
31013
+ const { sign_datail, sign_reply: douyinGetCollection_sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
30897
31014
  const douyinGetCollection = async (_task, params)=>{
30898
31015
  const headers = {
30899
31016
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
@@ -30929,7 +31046,7 @@ var __webpack_exports__ = {};
30929
31046
  msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "rWRQTO837CH1bajTIbvPAL9o1lpyzocwIToJZFtN61sBoeN_OJM2ykkGFhQxgq6OXOzn2XDML8Lvo829NxjGfQy00RLGJ2q9DMaPEhrgSVv9YklzRT1sT7R03XZ3I6_3y7D_m0wnjGszj8IBQq8EpTNk8B0S3YIbUGfnl_Za9VnS25CU7PygDEY=",
30930
31047
  a_bogus: ""
30931
31048
  };
30932
- const aBogus = sign_reply(collectionParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
31049
+ const aBogus = douyinGetCollection_sign_reply(collectionParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
30933
31050
  collectionParams.a_bogus = aBogus;
30934
31051
  const queryString = new URLSearchParams(collectionParams).toString();
30935
31052
  const res = await http.api({
@@ -30955,6 +31072,117 @@ var __webpack_exports__ = {};
30955
31072
  };
30956
31073
  return utils_response(isSuccess ? 0 : 414, message, data);
30957
31074
  };
31075
+ const DouyinGetCommentListParamsSchema = ActionCommonParamsSchema.extend({
31076
+ cursor: classic_schemas_number().optional(),
31077
+ count: classic_schemas_number().optional(),
31078
+ itemId: classic_schemas_string()
31079
+ });
31080
+ const { sign_datail: douyinGetCommentList_sign_datail, sign_reply: douyinGetCommentList_sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
31081
+ const { generateCsrfTokenAdvanced: douyinGetCommentList_generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
31082
+ const douyinGetCommentList = async (_task, params)=>{
31083
+ const headers = {
31084
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
31085
+ referer: "https://creator.douyin.com/",
31086
+ origin: "https://creator.douyin.com/"
31087
+ };
31088
+ const args = [
31089
+ {
31090
+ headers
31091
+ },
31092
+ _task.logger,
31093
+ params.proxyLoc,
31094
+ params.localIP,
31095
+ params.accountId
31096
+ ];
31097
+ const http = new Http(...args);
31098
+ const csrfToken = douyinGetCommentList_generateCsrfTokenAdvanced(params.cookies);
31099
+ console.log("生成的 csrfToken:", csrfToken);
31100
+ const commentListParams = {
31101
+ count: params.count?.toString() || "10",
31102
+ cursor: params.cursor?.toString() || "0",
31103
+ aid: "2906",
31104
+ sort: "TIME",
31105
+ item_id: params.itemId || "",
31106
+ msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
31107
+ a_bogus: ""
31108
+ };
31109
+ const aBogus = douyinGetCommentList_sign_reply(commentListParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
31110
+ commentListParams.a_bogus = aBogus;
31111
+ const queryString = new URLSearchParams(commentListParams).toString();
31112
+ console.log("抖音获取评论列表参数:", queryString);
31113
+ const res = await http.api({
31114
+ method: "get",
31115
+ url: `https://creator.douyin.com/aweme/v1/creator/comment/list/?${queryString}`,
31116
+ headers: {
31117
+ ...headers,
31118
+ "Content-Type": "application/json",
31119
+ "X-secsdk-csrf-token": csrfToken
31120
+ }
31121
+ }, {
31122
+ retries: 3,
31123
+ retryDelay: 20,
31124
+ timeout: 3000
31125
+ });
31126
+ console.log("抖音获取评论列表响应:", res);
31127
+ const isSuccess = 0 === res.status_code;
31128
+ const message = `抖音获取评论列表${isSuccess ? "成功" : `失败,原因:${res.status_msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
31129
+ return utils_response(isSuccess ? 0 : 414, message, res);
31130
+ };
31131
+ const DouyinGetCommentReplyListParamsSchema = ActionCommonParamsSchema.extend({
31132
+ commentId: classic_schemas_string(),
31133
+ cursor: classic_schemas_number().optional(),
31134
+ count: classic_schemas_number().optional()
31135
+ });
31136
+ const { sign_datail: douyinGetCommentReplyList_sign_datail, sign_reply: douyinGetCommentReplyList_sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
31137
+ const { generateCsrfTokenAdvanced: douyinGetCommentReplyList_generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
31138
+ const douyinGetCommentReplyList = async (_task, params)=>{
31139
+ const headers = {
31140
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
31141
+ referer: "https://creator.douyin.com/",
31142
+ origin: "https://creator.douyin.com/"
31143
+ };
31144
+ const args = [
31145
+ {
31146
+ headers
31147
+ },
31148
+ _task.logger,
31149
+ params.proxyLoc,
31150
+ params.localIP,
31151
+ params.accountId
31152
+ ];
31153
+ const http = new Http(...args);
31154
+ const csrfToken = douyinGetCommentReplyList_generateCsrfTokenAdvanced(params.cookies);
31155
+ console.log("生成的 csrfToken:", csrfToken);
31156
+ const replyListParams = {
31157
+ count: params.count?.toString() || "10",
31158
+ cursor: params.cursor?.toString() || "0",
31159
+ aid: "2906",
31160
+ comment_id: params.commentId,
31161
+ msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
31162
+ a_bogus: ""
31163
+ };
31164
+ const aBogus = douyinGetCommentReplyList_sign_reply(replyListParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
31165
+ replyListParams.a_bogus = aBogus;
31166
+ const queryString = new URLSearchParams(replyListParams).toString();
31167
+ console.log("抖音获取评论回复列表参数:", queryString);
31168
+ const res = await http.api({
31169
+ method: "get",
31170
+ url: `https://creator.douyin.com/aweme/v1/creator/comment/reply/list/?${queryString}`,
31171
+ headers: {
31172
+ ...headers,
31173
+ "Content-Type": "application/json",
31174
+ "X-secsdk-csrf-token": csrfToken
31175
+ }
31176
+ }, {
31177
+ retries: 3,
31178
+ retryDelay: 20,
31179
+ timeout: 3000
31180
+ });
31181
+ console.log("抖音获取评论回复列表响应:", res);
31182
+ const isSuccess = 0 === res.status_code;
31183
+ const message = `抖音获取评论回复列表${isSuccess ? "成功" : `失败,原因:${res.status_msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
31184
+ return utils_response(isSuccess ? 0 : 414, message, res);
31185
+ };
30958
31186
  const DouyinGetHotParamsSchema = ActionCommonParamsSchema.extend({
30959
31187
  query: classic_schemas_string().optional(),
30960
31188
  count: classic_schemas_number().optional()
@@ -31398,6 +31626,70 @@ var __webpack_exports__ = {};
31398
31626
  };
31399
31627
  return utils_response(isSuccess ? 0 : 414, message, data);
31400
31628
  };
31629
+ const DouyinGetWorkListParamsSchema = ActionCommonParamsSchema.extend({
31630
+ cursor: classic_schemas_number().optional(),
31631
+ count: classic_schemas_number().optional()
31632
+ });
31633
+ const { sign_datail: douyinGetWorkList_sign_datail, sign_reply: douyinGetWorkList_sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
31634
+ const { generateCsrfTokenAdvanced: douyinGetWorkList_generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
31635
+ const douyinGetWorkList = async (_task, params)=>{
31636
+ const headers = {
31637
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
31638
+ referer: "https://creator.douyin.com/",
31639
+ origin: "https://creator.douyin.com/"
31640
+ };
31641
+ const args = [
31642
+ {
31643
+ headers
31644
+ },
31645
+ _task.logger,
31646
+ params.proxyLoc,
31647
+ params.localIP,
31648
+ params.accountId
31649
+ ];
31650
+ const http = new Http(...args);
31651
+ const csrfToken = douyinGetWorkList_generateCsrfTokenAdvanced(params.cookies);
31652
+ console.log("生成的 csrfToken:", csrfToken);
31653
+ const workListParams = {
31654
+ count: params.count?.toString() || "10",
31655
+ cursor: params.cursor?.toString() || "",
31656
+ aid: "2906",
31657
+ msToken: params.cookies.find((e)=>"msToken" === e.name)?.value || "",
31658
+ a_bogus: ""
31659
+ };
31660
+ const aBogus = douyinGetWorkList_sign_reply(workListParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
31661
+ workListParams.a_bogus = aBogus;
31662
+ const queryString = new URLSearchParams(workListParams).toString();
31663
+ console.log("抖音获取作品列表参数:", queryString);
31664
+ const res = await http.api({
31665
+ method: "get",
31666
+ url: `https://creator.douyin.com/aweme/v1/creator/item/list/?${queryString}`,
31667
+ headers: {
31668
+ ...headers,
31669
+ "Content-Type": "application/json",
31670
+ "X-secsdk-csrf-token": csrfToken
31671
+ }
31672
+ }, {
31673
+ retries: 3,
31674
+ retryDelay: 20,
31675
+ timeout: 3000
31676
+ });
31677
+ console.log("抖音获取作品列表响应:", res);
31678
+ const isSuccess = 0 === res.status_code;
31679
+ const message = `抖音获取作品列表${isSuccess ? "成功" : `失败,原因:${res.status_msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
31680
+ const data = isSuccess ? {
31681
+ works: res?.aweme_list || [],
31682
+ has_more: res?.has_more || false,
31683
+ cursor: res?.cursor || 0,
31684
+ total: res?.aweme_list?.length || 0
31685
+ } : {
31686
+ works: [],
31687
+ has_more: false,
31688
+ cursor: 0,
31689
+ total: 0
31690
+ };
31691
+ return utils_response(isSuccess ? 0 : 414, message, data);
31692
+ };
31401
31693
  const rpa_scanRetryMaxCount = 60;
31402
31694
  const rpa_waitQrcodeResultMaxTime = 2000 * rpa_scanRetryMaxCount;
31403
31695
  const douyinLogin_rpa_rpaAction = async (task, params)=>{
@@ -31417,7 +31709,7 @@ var __webpack_exports__ = {};
31417
31709
  } catch (e) {
31418
31710
  task.logger.error("浏览器启动失败", e);
31419
31711
  return {
31420
- code: 500,
31712
+ code: 414,
31421
31713
  message: `浏览器启动失败: ${e}`,
31422
31714
  data: {}
31423
31715
  };
@@ -32174,7 +32466,7 @@ var __webpack_exports__ = {};
32174
32466
  }
32175
32467
  const { sign_reply: mock_sign_reply } = __webpack_require__("./src/utils/douyin/douyin.js");
32176
32468
  const { generateReqSignFromTicket } = __webpack_require__("./src/utils/douyin/reqSign.js.js");
32177
- const { generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
32469
+ const { generateCsrfTokenAdvanced: mock_generateCsrfTokenAdvanced } = __webpack_require__("./src/utils/douyin/csrfToken.js");
32178
32470
  const mock_mockAction = async (task, params)=>{
32179
32471
  if (!params.extraParam || !params.extraParam["security-sdk/s_sdk_pri_key"] || !params.extraParam["security-sdk/s_sdk_pub_key"] || !params.extraParam["security-sdk/s_sdk_sign_data_key/web_protect"]) return utils_response(400, "extraParam 参数缺失或不完整", "");
32180
32472
  const tmpCachePath = task.getTmpPath();
@@ -32220,7 +32512,7 @@ var __webpack_exports__ = {};
32220
32512
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
32221
32513
  origin: "https://creator.douyin.com",
32222
32514
  referer: "https://creator.douyin.com/",
32223
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
32515
+ "user-agent": params.userAgent || ""
32224
32516
  };
32225
32517
  const publishParams = {
32226
32518
  read_aid: "2906",
@@ -32231,7 +32523,7 @@ var __webpack_exports__ = {};
32231
32523
  browser_language: "zh-CN",
32232
32524
  browser_platform: "Win32",
32233
32525
  browser_name: "Mozilla",
32234
- browser_version: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
32526
+ browser_version: params.userAgent || "",
32235
32527
  browser_online: "true",
32236
32528
  timezone_name: "Asia/Shanghai",
32237
32529
  support_h265: "1",
@@ -32267,7 +32559,7 @@ var __webpack_exports__ = {};
32267
32559
  }
32268
32560
  }
32269
32561
  };
32270
- const aBogus = mock_sign_reply(publishParams, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
32562
+ const aBogus = mock_sign_reply(publishParams, params.userAgent);
32271
32563
  publishParams.a_bogus = aBogus;
32272
32564
  const queryString = new URLSearchParams(publishParams).toString();
32273
32565
  const args = [
@@ -32313,7 +32605,7 @@ var __webpack_exports__ = {};
32313
32605
  const publishQuery = {
32314
32606
  ...publishParams
32315
32607
  };
32316
- publishQuery.a_bogus = mock_sign_reply(publishQuery, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36");
32608
+ publishQuery.a_bogus = mock_sign_reply(publishQuery, params.userAgent);
32317
32609
  const publishQueryParams = new URLSearchParams(publishQuery).toString();
32318
32610
  function generateRandomString(length) {
32319
32611
  const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -32325,7 +32617,7 @@ var __webpack_exports__ = {};
32325
32617
  return randomString;
32326
32618
  }
32327
32619
  publishData.item.common.creation_id = generateRandomString(8) + Date.now();
32328
- const csrfToken = generateCsrfTokenAdvanced({
32620
+ const csrfToken = mock_generateCsrfTokenAdvanced({
32329
32621
  cookies: params.cookies,
32330
32622
  url: "https://creator.douyin.com/web/api/media/aweme/create_v2/",
32331
32623
  method: "POST",
@@ -32341,6 +32633,7 @@ var __webpack_exports__ = {};
32341
32633
  ...headers,
32342
32634
  Referer: "https://creator.douyin.com/creator-micro/content/post/image?default-tab=3&enter_from=publish_page&media_type=image&type=new",
32343
32635
  "Content-Type": "application/json",
32636
+ Accept: "application/json, text/plain, */*",
32344
32637
  "Bd-ticket-guard-client-data": bdTicketGuardClientData,
32345
32638
  "Bd-ticket-guard-ree-public-key": ree_public_key,
32346
32639
  "Bd-ticket-guard-version": "2",
@@ -32378,7 +32671,6 @@ var __webpack_exports__ = {};
32378
32671
  return utils_response(isSuccess ? 0 : 414, message, data);
32379
32672
  };
32380
32673
  const douyinPublish_rpa_rpaAction = async (task, params)=>{
32381
- const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
32382
32674
  const commonCookies = {
32383
32675
  path: "/",
32384
32676
  secure: true,
@@ -32394,55 +32686,261 @@ var __webpack_exports__ = {};
32394
32686
  ...commonCookies
32395
32687
  }))
32396
32688
  });
32397
- await updateTaskState?.({
32398
- state: types_TaskState.ACTION,
32399
- connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
32400
- sessionId: task.sessionId
32401
- });
32402
32689
  const tmpCachePath = task.getTmpPath();
32690
+ const waitForElement = async (selector, timeout = 10000)=>{
32691
+ try {
32692
+ const element = page.locator(selector);
32693
+ task.logger.warn(`element: ${element}`);
32694
+ await element.waitFor({
32695
+ state: "visible",
32696
+ timeout
32697
+ });
32698
+ return element;
32699
+ } catch {
32700
+ task.logger.warn(`元素未找到: ${selector}`);
32701
+ return null;
32702
+ }
32703
+ };
32704
+ const retryAction = async (action, maxRetries = 3, delay = 1000)=>{
32705
+ let lastError;
32706
+ for(let i = 0; i < maxRetries; i++)try {
32707
+ return await action();
32708
+ } catch (error) {
32709
+ lastError = error;
32710
+ task.logger.warn(`重试 ${i + 1}/${maxRetries}: ${lastError.message}`);
32711
+ if (i < maxRetries - 1) await page.waitForTimeout(delay);
32712
+ }
32713
+ throw lastError;
32714
+ };
32715
+ const safeClick = async (locator)=>{
32716
+ if (!locator) return false;
32717
+ try {
32718
+ await locator.click({
32719
+ timeout: 5000
32720
+ });
32721
+ return true;
32722
+ } catch (error) {
32723
+ task.logger.warn(`点击失败: ${error}`);
32724
+ return false;
32725
+ }
32726
+ };
32727
+ const safeFill = async (locator, text)=>{
32728
+ if (!locator || !text) return false;
32729
+ try {
32730
+ await locator.clear({
32731
+ timeout: 3000
32732
+ });
32733
+ await locator.fill(text, {
32734
+ timeout: 5000
32735
+ });
32736
+ return true;
32737
+ } catch (error) {
32738
+ task.logger.warn(`填充文本失败: ${error}`);
32739
+ return false;
32740
+ }
32741
+ };
32403
32742
  try {
32743
+ task.logger.info("检查登录状态...");
32404
32744
  await page.waitForSelector("#micro", {
32405
32745
  state: "visible",
32406
32746
  timeout: 20000
32407
32747
  });
32408
- } catch (error) {
32748
+ task.logger.info("✓ 登录状态正常");
32749
+ } catch (_error) {
32750
+ task.logger.error("✗ 登录失效或页面加载异常");
32409
32751
  return {
32410
32752
  code: 414,
32411
32753
  message: "登录失效",
32412
32754
  data: page.url()
32413
32755
  };
32414
32756
  }
32415
- const images = await Promise.all([
32416
- "https://svip-8.rcouyi.com/file/draw/volc/2026/01/15/2011725723554811904.png"
32417
- ].map((url)=>{
32418
- const fileName = getFilenameFromUrl(url);
32419
- return downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
32420
- }));
32421
- const fileChooser = await page.waitForSelector('input[type="file"]', {
32422
- timeout: 20000
32423
- });
32424
- if (fileChooser) await fileChooser.setInputFiles(images);
32425
- const titleInstance = page.locator(".semi-input-wrapper input[placeholder='添加作品标题']");
32426
- await titleInstance.waitFor({
32427
- state: "visible",
32428
- timeout: 50000
32429
- });
32430
- await titleInstance.click();
32431
- await titleInstance.fill(params.title || "1111");
32432
- await page.waitForTimeout(1000);
32433
- const descInstance = page.locator("div[data-placeholder='添加作品描述...']");
32434
- await descInstance.click();
32435
- await descInstance.pressSequentially(params.content.replace(/#.*?\[.*?]#/g, "") || "22222");
32436
- if ("1" === params.visibleRange) await page.locator("label:has-text('好友可见')").first().click();
32437
- else if ("2" === params.visibleRange) await page.locator("label:has-text('仅自己可见')").first().click();
32438
- if (!params.isImmediatelyPublish) {
32439
- await await page.locator('label:has-text("定时发布")').first().click();
32440
- await page.waitForTimeout(500);
32441
- const releaseTimeInstance = page.locator(".semi-datepicker-input input[placeholder='日期和时间']");
32442
- await releaseTimeInstance.click();
32757
+ if (params.banners && params.banners.length > 0 && params.coverImage && params.coverImage.length > 0) {
32758
+ const imgs = [
32759
+ params.coverImage
32760
+ ].concat(params.banners);
32761
+ task.logger.info(`开始上传 ${imgs.length} 张图片`);
32762
+ await retryAction(async ()=>{
32763
+ const images = await Promise.all(imgs.map((url)=>{
32764
+ const fileName = getFilenameFromUrl(url);
32765
+ return downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
32766
+ }));
32767
+ const fileChooser = await page.waitForSelector('input[type="file"]', {
32768
+ timeout: 20000
32769
+ });
32770
+ if (!fileChooser) throw new Error("未找到图片上传输入框");
32771
+ await fileChooser.setInputFiles(images);
32772
+ task.logger.info(`图片上传成功: ${images.length} 张`);
32773
+ await page.waitForTimeout(2000);
32774
+ });
32775
+ }
32776
+ if (params.title) {
32777
+ task.logger.info(`填写标题: ${params.title}`);
32778
+ await retryAction(async ()=>{
32779
+ const titleInstance = await waitForElement(".semi-input-wrapper input[placeholder='添加作品标题']", 50000);
32780
+ if (!titleInstance) throw new Error("未找到标题输入框");
32781
+ await titleInstance.click();
32782
+ await safeFill(titleInstance, params.title);
32783
+ task.logger.info("标题填写完成");
32784
+ });
32785
+ }
32786
+ if (params.content) {
32787
+ task.logger.info("填写描述");
32443
32788
  await page.waitForTimeout(1000);
32444
- await releaseTimeInstance.blur();
32789
+ await retryAction(async ()=>{
32790
+ const descInstance = await waitForElement("div[data-placeholder='添加作品描述...']", 10000);
32791
+ if (!descInstance) throw new Error("未找到描述编辑器");
32792
+ await descInstance.click();
32793
+ await page.waitForTimeout(500);
32794
+ const cleanContent = params.content.replace(/#.*?\[.*?]#/g, "");
32795
+ await descInstance.pressSequentially(cleanContent, {
32796
+ delay: 10
32797
+ });
32798
+ task.logger.info("描述填写完成");
32799
+ });
32445
32800
  }
32801
+ if (params.topic && params.topic.length > 0) {
32802
+ task.logger.info(`添加话题标签: ${params.topic.length} 个`);
32803
+ try {
32804
+ const topics = params.topic;
32805
+ await retryAction(async ()=>{
32806
+ const descInstance = page.locator(".editor-kit-container.editor.editor-comp-publish");
32807
+ for (const topic of topics)if (topic.cha_name) {
32808
+ const topicTag = `#${topic.cha_name} `;
32809
+ await descInstance.pressSequentially(topicTag, {
32810
+ delay: 10
32811
+ });
32812
+ task.logger.info(`已添加话题: ${topicTag.trim()}`);
32813
+ await page.waitForTimeout(300);
32814
+ }
32815
+ task.logger.info("✓ 话题标签添加完成");
32816
+ });
32817
+ } catch (error) {
32818
+ task.logger.warn(`添加话题标签失败: ${error}`);
32819
+ }
32820
+ }
32821
+ if (params.mix?.mix_name) {
32822
+ task.logger.info(`选择合集: ${params.mix.mix_name}`);
32823
+ const instanceCollection = page.locator("[class^='mix-sel-wrap'] .semi-select").nth(1);
32824
+ await instanceCollection.click();
32825
+ await page.waitForTimeout(2000);
32826
+ page.locator(".semi-select-option-list .semi-select-option").filter({
32827
+ hasText: params.mix.mix_name
32828
+ }).first().click({
32829
+ force: true
32830
+ });
32831
+ }
32832
+ if (params.musicId && params.musicName) {
32833
+ task.logger.info(`选择音乐: ${params.musicName} - ${params.musicAuthor || ""}`);
32834
+ try {
32835
+ await retryAction(async ()=>{
32836
+ const musicTrigger = await waitForElement("[class^='container-right-']", 10000);
32837
+ if (!musicTrigger) throw new Error("未找到音乐选择触发器");
32838
+ await musicTrigger.click();
32839
+ task.logger.info("已打开音乐选择面板");
32840
+ await page.waitForTimeout(1000);
32841
+ const searchBox = await waitForElement("[class^='music-search']", 10000);
32842
+ if (!searchBox) throw new Error("未找到音乐搜索框");
32843
+ await searchBox.click();
32844
+ await page.waitForTimeout(500);
32845
+ const searchInput = page.locator("[class^='music-search'] input");
32846
+ const searchText = params.musicAuthor ? `${params.musicName} - ${params.musicAuthor}` : params.musicName;
32847
+ await searchInput.fill(searchText || "");
32848
+ task.logger.info(`已输入搜索内容: ${searchText}`);
32849
+ await page.waitForTimeout(300);
32850
+ await searchInput.press("Enter");
32851
+ task.logger.info("已触发搜索");
32852
+ await page.waitForTimeout(4000);
32853
+ const resultContainer = page.locator("[class^='card-container-']");
32854
+ task.logger.info(`resultContainer: ${resultContainer}`);
32855
+ if (!resultContainer) throw new Error("未找到音乐搜索结果");
32856
+ const musicCards = page.locator("[class^='card-container-']");
32857
+ const matchedCard = musicCards.filter({
32858
+ hasText: params.musicName
32859
+ }).first();
32860
+ const cardCount = await matchedCard.count();
32861
+ if (0 === cardCount) {
32862
+ task.logger.warn(`未找到匹配的音乐: ${params.musicName}`);
32863
+ throw new Error(`未找到匹配的音乐: ${params.musicName}`);
32864
+ }
32865
+ task.logger.info("找到匹配的音乐,准备选择");
32866
+ await matchedCard.hover();
32867
+ task.logger.info("已 hover 到音乐卡片");
32868
+ await page.waitForTimeout(2000);
32869
+ const selectButton = matchedCard.locator(".semi-button").first();
32870
+ const buttonClicked = await safeClick(selectButton);
32871
+ if (!buttonClicked) throw new Error("点击音乐选择按钮失败");
32872
+ task.logger.info("✓ 音乐选择完成");
32873
+ await page.waitForTimeout(500);
32874
+ });
32875
+ } catch (error) {
32876
+ task.logger.warn(`选择音乐失败: ${error}`);
32877
+ }
32878
+ }
32879
+ if (params.hotSentence) {
32880
+ task.logger.info(`选择热点: ${params.hotSentence}`);
32881
+ const instance = page.locator(".semi-select-filterable").nth(1);
32882
+ await instance.click();
32883
+ await page.waitForTimeout(1000);
32884
+ await page.locator(".semi-input-wrapper input").nth(1).fill(params.hotSentence);
32885
+ await page.waitForTimeout(2000);
32886
+ page.locator(".semi-popover-content .semi-select-option").filter({
32887
+ hasText: params.hotSentence
32888
+ }).first().click({
32889
+ force: true
32890
+ });
32891
+ }
32892
+ if (params.visibleRange) {
32893
+ task.logger.info(`设置可见范围: ${params.visibleRange}`);
32894
+ if ("2" === params.visibleRange) {
32895
+ await page.locator("label:has-text('好友可见')").first().click();
32896
+ task.logger.info("已设置为好友可见");
32897
+ } else if ("1" === params.visibleRange) {
32898
+ await page.locator("label:has-text('仅自己可见')").first().click();
32899
+ task.logger.info("已设置为仅自己可见");
32900
+ }
32901
+ }
32902
+ if (!params.allowSave) {
32903
+ task.logger.info(`设置保存权限: ${params.allowSave ? "允许" : "不允许"}`);
32904
+ try {
32905
+ await page.locator("label:has-text('不允许')").first().click();
32906
+ task.logger.info("已设置为保存权限不允许");
32907
+ await page.waitForTimeout(300);
32908
+ } catch (error) {
32909
+ task.logger.warn(`设置保存权限失败: ${error}`);
32910
+ }
32911
+ }
32912
+ if (!params.isImmediatelyPublish && params.scheduledPublish) {
32913
+ task.logger.info("设置定时发布");
32914
+ try {
32915
+ await page.locator('label:has-text("定时发布")').first().click();
32916
+ task.logger.info("已选择定时发布");
32917
+ await page.waitForTimeout(500);
32918
+ const timestamp = params.scheduledPublish > 10000000000 ? params.scheduledPublish / 1000 : params.scheduledPublish;
32919
+ const publishDate = new Date(1000 * timestamp);
32920
+ const year = publishDate.getFullYear();
32921
+ const month = String(publishDate.getMonth() + 1).padStart(2, "0");
32922
+ const day = String(publishDate.getDate()).padStart(2, "0");
32923
+ const hour = String(publishDate.getHours()).padStart(2, "0");
32924
+ const minute = String(publishDate.getMinutes()).padStart(2, "0");
32925
+ const formattedTime = `${year}-${month}-${day} ${hour}:${minute}`;
32926
+ task.logger.info(`目标发布时间: ${formattedTime}`);
32927
+ const releaseTimeInstance = await waitForElement(".semi-datepicker-input input[placeholder='日期和时间']", 10000);
32928
+ if (!releaseTimeInstance) throw new Error("未找到时间输入框");
32929
+ await releaseTimeInstance.click();
32930
+ await page.waitForTimeout(500);
32931
+ await releaseTimeInstance.fill(formattedTime);
32932
+ await page.waitForTimeout(500);
32933
+ const inputValue = await releaseTimeInstance.inputValue();
32934
+ if (inputValue !== formattedTime) task.logger.warn(`时间输入验证失败,期望: ${formattedTime}, 实际: ${inputValue}`);
32935
+ else task.logger.info("定时发布设置完成");
32936
+ await releaseTimeInstance.blur();
32937
+ await page.waitForTimeout(500);
32938
+ } catch (error) {
32939
+ task.logger.warn(`定时发布设置失败: ${error}`);
32940
+ }
32941
+ }
32942
+ task.logger.info("准备发布...");
32943
+ await page.waitForTimeout(1000);
32446
32944
  const response = await new Promise((resolve)=>{
32447
32945
  const handleResponse = async (response)=>{
32448
32946
  if (response.url().includes("/web/api/media/aweme/create_v2")) {
@@ -32456,15 +32954,12 @@ var __webpack_exports__ = {};
32456
32954
  console.log("监听响应事件");
32457
32955
  page.on("response", handleResponse);
32458
32956
  console.log("点击发布按钮");
32459
- page.locator("#DCPF button:has-text('发布')").first().click();
32460
- console.log("发布按钮已点击");
32461
- });
32462
- await updateTaskState?.({
32463
- state: types_TaskState.SUCCESS,
32464
- result: {
32465
- response
32466
- }
32957
+ setTimeout(()=>{
32958
+ page.locator("#DCPF button:has-text('发布')").first().click();
32959
+ console.log("发布按钮已点击");
32960
+ }, 1000);
32467
32961
  });
32962
+ console.log("发布成功了");
32468
32963
  await page.close();
32469
32964
  return success(response);
32470
32965
  };
@@ -32484,9 +32979,12 @@ var __webpack_exports__ = {};
32484
32979
  banners: classic_schemas_array(classic_schemas_string()),
32485
32980
  mix: classic_schemas_object({
32486
32981
  mix_id: classic_schemas_string(),
32487
- mix_order: classic_schemas_number()
32982
+ mix_order: classic_schemas_number(),
32983
+ mix_name: classic_schemas_string().optional()
32488
32984
  }).optional(),
32489
32985
  musicId: classic_schemas_string().optional(),
32986
+ musicName: classic_schemas_string().optional(),
32987
+ musicAuthor: classic_schemas_string().optional(),
32490
32988
  musicDuration: classic_schemas_number().optional(),
32491
32989
  challengeIds: classic_schemas_string().optional(),
32492
32990
  hotSentence: classic_schemas_string().optional(),
@@ -32577,43 +33075,6 @@ var __webpack_exports__ = {};
32577
33075
  });
32578
33076
  return success(data, "获取百家号配置项成功!");
32579
33077
  };
32580
- const rid = ()=>`${Math.floor(Date.now() / 1e3).toString(16)}-${[
32581
- ...Array(8)
32582
- ].map(()=>Math.floor(16 * Math.random()).toString(16)).join("")}`;
32583
- let randomValuesFunc = null;
32584
- const byteBuffer = new Uint8Array(16);
32585
- const UUID_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
32586
- const hexTable = [];
32587
- for(let i = 0; i < 256; i++)hexTable.push((i + 256).toString(16).substr(1));
32588
- function initRandomGenerator() {
32589
- if (randomValuesFunc) return randomValuesFunc;
32590
- const globalCrypto = "undefined" != typeof crypto ? crypto : void 0;
32591
- const globalMsCrypto = "undefined" != typeof msCrypto ? msCrypto : void 0;
32592
- const cryptoAPI = globalCrypto?.getRandomValues?.bind(globalCrypto) || globalMsCrypto?.getRandomValues?.bind(globalMsCrypto);
32593
- if (!cryptoAPI) throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
32594
- randomValuesFunc = cryptoAPI;
32595
- return randomValuesFunc;
32596
- }
32597
- function generateRandomBytes() {
32598
- const rng = initRandomGenerator();
32599
- return rng(byteBuffer);
32600
- }
32601
- function bytesToUuid(bytes, offset = 0) {
32602
- const uuidString = (hexTable[bytes[offset + 0]] + hexTable[bytes[offset + 1]] + hexTable[bytes[offset + 2]] + hexTable[bytes[offset + 3]] + "-" + hexTable[bytes[offset + 4]] + hexTable[bytes[offset + 5]] + "-" + hexTable[bytes[offset + 6]] + hexTable[bytes[offset + 7]] + "-" + hexTable[bytes[offset + 8]] + hexTable[bytes[offset + 9]] + "-" + hexTable[bytes[offset + 10]] + hexTable[bytes[offset + 11]] + hexTable[bytes[offset + 12]] + hexTable[bytes[offset + 13]] + hexTable[bytes[offset + 14]] + hexTable[bytes[offset + 15]]).toLowerCase();
32603
- if (!UUID_REGEX.test(uuidString)) throw new TypeError("Stringified UUID is invalid");
32604
- return uuidString;
32605
- }
32606
- function utils_uuidv4(options = {}, buffer = null, bufferOffset = 0) {
32607
- const rng = options.random || options.rng || generateRandomBytes;
32608
- const bytes = rng();
32609
- bytes[6] = 0x0f & bytes[6] | 0x40;
32610
- bytes[8] = 0x3f & bytes[8] | 0x80;
32611
- if (buffer) {
32612
- for(let i = 0; i < 16; i++)buffer[bufferOffset + i] = bytes[i];
32613
- return buffer;
32614
- }
32615
- return bytesToUuid(bytes);
32616
- }
32617
33078
  const getShipinhaoBgm = async (_task, params)=>{
32618
33079
  if (!params.extraParam) return utils_response(400, "缺少 extraParam 参数", {
32619
33080
  items: [],
@@ -32650,7 +33111,7 @@ var __webpack_exports__ = {};
32650
33111
  query: params.query || "",
32651
33112
  timestamp: Date.now().toString(),
32652
33113
  _log_finder_uin: "",
32653
- _log_finder_id: "v2_060000231003b20faec8c4e48d1ac4d0cf04ea30b0770cdb1c9d90e6403c4964e53c4a1e53f9@finder",
33114
+ _log_finder_id: params.extraParam.finderUserName || "",
32654
33115
  rawKeyBuff: null,
32655
33116
  pluginSessionId: null,
32656
33117
  scene: 7,
@@ -32686,7 +33147,7 @@ var __webpack_exports__ = {};
32686
33147
  const requestData = {
32687
33148
  timestamp: Date.now().toString(),
32688
33149
  _log_finder_uin: "",
32689
- _log_finder_id: "v2_060000231003b20faec8c4e48d1ac4d0cf04ea30b0770cdb1c9d90e6403c4964e53c4a1e53f9@finder",
33150
+ _log_finder_id: params.extraParam.finderUserName || "",
32690
33151
  rawKeyBuff: null,
32691
33152
  pluginSessionId: null,
32692
33153
  scene: 7,
@@ -32738,7 +33199,7 @@ var __webpack_exports__ = {};
32738
33199
  pageSize: params.pageSize ?? 20,
32739
33200
  timestamp: Date.now().toString(),
32740
33201
  _log_finder_uin: "",
32741
- _log_finder_id: "v2_060000231003b20faec8c4e48d1ac4d0cf04ea30b0770cdb1c9d90e6403c4964e53c4a1e53f9@finder",
33202
+ _log_finder_id: params.extraParam.finderUserName || "",
32742
33203
  rawKeyBuff: null,
32743
33204
  pluginSessionId: null,
32744
33205
  scene: 7,
@@ -32776,7 +33237,7 @@ var __webpack_exports__ = {};
32776
33237
  forMcn: false,
32777
33238
  timestamp: Date.now().toString(),
32778
33239
  _log_finder_uin: "",
32779
- _log_finder_id: "v2_060000231003b20faec8c4e48d1ac4d0cf04ea30b0770cdb1c9d90e6403c4964e53c4a1e53f9@finder",
33240
+ _log_finder_id: params.extraParam?.finderUserName || "",
32780
33241
  rawKeyBuff: null,
32781
33242
  pluginSessionId: null,
32782
33243
  scene: 7,
@@ -32784,7 +33245,7 @@ var __webpack_exports__ = {};
32784
33245
  };
32785
33246
  const res = await http.api({
32786
33247
  method: "post",
32787
- url: `https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/post/post_list?${urlParams}`,
33248
+ url: `https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/comment/comment_list?${urlParams}`,
32788
33249
  data: requestData
32789
33250
  });
32790
33251
  console.log(res, "----res");
@@ -32845,7 +33306,7 @@ var __webpack_exports__ = {};
32845
33306
  lastBuff: params.lastBuff || "",
32846
33307
  timestamp: Date.now().toString(),
32847
33308
  _log_finder_uin: "",
32848
- _log_finder_id: "v2_060000231003b20faec8c4e48d1ac4d0cf04ea30b0770cdb1c9d90e6403c4964e53c4a1e53f9@finder",
33309
+ _log_finder_id: params.extraParam?.finderUserName || "",
32849
33310
  rawKeyBuff: null,
32850
33311
  pluginSessionId: null,
32851
33312
  scene: 7,
@@ -34633,11 +35094,12 @@ var __webpack_exports__ = {};
34633
35094
  ...res
34634
35095
  });
34635
35096
  const isSuccess = 0 === res.errCode;
34636
- const message = `视频号验证链接${isSuccess ? "成功" : `失败,原因:${res.errMsg || "无法添加此链接"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
35097
+ const baseResp = res.data?.baseResp;
35098
+ const message = `视频号验证链接${res.data?.title ? "成功" : `失败,原因:${baseResp?.errmsg || "无法添加此链接"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
34637
35099
  const data = {
34638
35100
  title: res?.data?.title || "",
34639
- errMsg: res?.errMsg || "",
34640
- errCode: res?.errCode
35101
+ errMsg: baseResp?.errmsg || "",
35102
+ errCode: baseResp?.errcode
34641
35103
  };
34642
35104
  return utils_response(isSuccess ? 0 : 414, message, data);
34643
35105
  };
@@ -34726,19 +35188,20 @@ var __webpack_exports__ = {};
34726
35188
  const isSuccess = 0 === res.errCode;
34727
35189
  const message = `视频号获取位置${isSuccess ? "成功" : `失败,原因:${res.errMsg || res.errCode || "未知错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
34728
35190
  let locations = [];
34729
- if (isSuccess && res?.data?.list) locations = res.data.list;
35191
+ let address;
35192
+ if (isSuccess && res?.data?.list) {
35193
+ locations = res.data.list;
35194
+ address = res.data?.address;
35195
+ }
34730
35196
  const data = {
34731
35197
  locations,
34732
- total: res?.data?.total || locations.length
35198
+ total: res?.data?.total || locations.length,
35199
+ address
34733
35200
  };
34734
35201
  return utils_response(isSuccess ? 0 : 414, message, data);
34735
35202
  };
34736
35203
  const shipinhaoLogin_rpa_scanRetryMaxCount = 60;
34737
35204
  const shipinhaoLogin_rpa_waitQrcodeResultMaxTime = 2000 * shipinhaoLogin_rpa_scanRetryMaxCount;
34738
- const DEFAULT_VIEWPORT = {
34739
- width: 1280,
34740
- height: 720
34741
- };
34742
35205
  const shipinhaoLogin_rpa_rpaAction = async (task, params)=>{
34743
35206
  const reporter = task.reportService?.reportLoginStatus ?? (()=>Promise.resolve());
34744
35207
  let page;
@@ -34746,8 +35209,7 @@ var __webpack_exports__ = {};
34746
35209
  let isSelfClosing = false;
34747
35210
  try {
34748
35211
  page = await task.createPage({
34749
- url: "https://channels.weixin.qq.com/login.html",
34750
- viewport: params.viewport || DEFAULT_VIEWPORT
35212
+ url: "https://channels.weixin.qq.com/login.html"
34751
35213
  });
34752
35214
  if (!task._session?.id) throw new Error("Session ID 不存在");
34753
35215
  task._steelBrowser?.on("disconnected", ()=>{
@@ -34757,7 +35219,7 @@ var __webpack_exports__ = {};
34757
35219
  } catch (e) {
34758
35220
  task.logger.error("浏览器启动失败", e);
34759
35221
  return {
34760
- code: 500,
35222
+ code: 414,
34761
35223
  message: `浏览器启动失败: ${e}`,
34762
35224
  data: {}
34763
35225
  };
@@ -35299,33 +35761,257 @@ var __webpack_exports__ = {};
35299
35761
  if ("server" === params.actionType) return shipinhaoLogin_rpa_server_rpaServer(task, params);
35300
35762
  return executeAction(shipinhaoLogin_rpa_server_rpaServer)(task, params);
35301
35763
  };
35302
- function calculateBufferMd5(buffer) {
35303
- const hash = external_node_crypto_default().createHash("md5");
35304
- hash.update(buffer);
35305
- return hash.digest("hex");
35306
- }
35307
- function calculatePartialMd5(buffer) {
35308
- const MAX_SIZE = 5242880;
35309
- const slice = buffer.length > MAX_SIZE ? buffer.slice(0, MAX_SIZE) : buffer;
35310
- const hash = external_node_crypto_default().createHash("md5");
35311
- hash.update(slice);
35312
- return hash.digest("hex");
35313
- }
35314
- async function readImageFile(imagePath) {
35315
- try {
35316
- if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) {
35317
- const response = await lib_axios.get(imagePath, {
35764
+ class VideoChannelUploader {
35765
+ constructor(config = {}){
35766
+ this.uploadTaskId = "";
35767
+ this.partInfo = [];
35768
+ this.md5 = "";
35769
+ this.chunkCount = 0;
35770
+ this.uploadedChunks = 0;
35771
+ this.startTime = 0;
35772
+ this.uploadSpeed = 0;
35773
+ this.speedRecords = [];
35774
+ this.chunkSize = config.chunkSize || 8388608;
35775
+ this.concurrentLimit = config.concurrentLimit || 4;
35776
+ this.singleFileSize = config.singleFileSize || 10485760;
35777
+ }
35778
+ calculateMd5(buffer) {
35779
+ const MAX_SIZE = 5242880;
35780
+ const slice = buffer.length > MAX_SIZE ? buffer.slice(0, MAX_SIZE) : buffer;
35781
+ return external_node_crypto_default().createHash("md5").update(slice).digest("hex");
35782
+ }
35783
+ calculateChunkMd5(buffer) {
35784
+ return external_node_crypto_default().createHash("md5").update(buffer).digest("hex");
35785
+ }
35786
+ generateUUID() {
35787
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c)=>{
35788
+ const r = 16 * Math.random() | 0;
35789
+ const v = "x" === c ? r : 0x3 & r | 0x8;
35790
+ return v.toString(16);
35791
+ });
35792
+ }
35793
+ getImageSize(buffer) {
35794
+ try {
35795
+ if (0x89 === buffer[0] && 0x50 === buffer[1]) return {
35796
+ width: buffer.readUInt32BE(16),
35797
+ height: buffer.readUInt32BE(20)
35798
+ };
35799
+ if (0xff === buffer[0] && 0xd8 === buffer[1]) {
35800
+ let offset = 2;
35801
+ while(offset < buffer.length){
35802
+ if (0xff !== buffer[offset]) break;
35803
+ const marker = buffer[offset + 1];
35804
+ const size = buffer.readUInt16BE(offset + 2);
35805
+ if (0xc0 === marker || 0xc1 === marker || 0xc2 === marker) return {
35806
+ height: buffer.readUInt16BE(offset + 5),
35807
+ width: buffer.readUInt16BE(offset + 7)
35808
+ };
35809
+ offset += size + 2;
35810
+ }
35811
+ }
35812
+ if (0x47 === buffer[0] && 0x49 === buffer[1]) return {
35813
+ width: buffer.readUInt16LE(6),
35814
+ height: buffer.readUInt16LE(8)
35815
+ };
35816
+ return {
35817
+ width: 0,
35818
+ height: 0
35819
+ };
35820
+ } catch {
35821
+ return {
35822
+ width: 0,
35823
+ height: 0
35824
+ };
35825
+ }
35826
+ }
35827
+ async readFile(filePath) {
35828
+ if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
35829
+ const resp = await lib_axios.get(filePath, {
35318
35830
  responseType: "arraybuffer"
35319
35831
  });
35320
- return Buffer.from(response.data);
35832
+ return Buffer.from(resp.data);
35321
35833
  }
35322
- if (external_node_fs_default().existsSync(imagePath)) return external_node_fs_default().readFileSync(imagePath);
35323
- return null;
35324
- } catch (error) {
35325
- console.error("读取图片失败:", error);
35326
- return null;
35834
+ return external_node_fs_default().promises.readFile(filePath);
35835
+ }
35836
+ async getUploadId(fileSize, fileName, uin, authKey, taskId) {
35837
+ const blockSum = Math.ceil(fileSize / this.chunkSize);
35838
+ const blockPartLength = [];
35839
+ for(let i = 1; i <= blockSum; i++){
35840
+ const end = Math.min(i * this.chunkSize, fileSize);
35841
+ blockPartLength.push(end);
35842
+ }
35843
+ const requestBody = {
35844
+ BlockSum: blockSum,
35845
+ BlockPartLength: blockPartLength
35846
+ };
35847
+ const headers = {
35848
+ "X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=2`,
35849
+ Authorization: authKey,
35850
+ Accept: "application/json, text/plain, */*",
35851
+ "Content-MD5": "null",
35852
+ Referer: "https://channels.weixin.qq.com/",
35853
+ Origin: "https://channels.weixin.qq.com/"
35854
+ };
35855
+ const resp = await lib_axios.put("https://finderassistancea.video.qq.com/applyuploaddfs", requestBody, {
35856
+ headers
35857
+ });
35858
+ if (!resp.data?.UploadID) throw new Error(`获取 UploadID 失败: ${resp.data?.errMsg || "未知错误"}`);
35859
+ return resp.data.UploadID;
35860
+ }
35861
+ async uploadChunk(chunk, fileName, fileSize, uin, authKey, uploadId, partNumber, taskId, onProgress) {
35862
+ const md5Hash = this.calculateChunkMd5(chunk);
35863
+ const headers = {
35864
+ "Content-MD5": md5Hash,
35865
+ "X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
35866
+ Authorization: authKey,
35867
+ "Content-Type": "application/octet-stream",
35868
+ Referer: "https://channels.weixin.qq.com/platform/post/create",
35869
+ Origin: "https://channels.weixin.qq.com"
35870
+ };
35871
+ const url = `https://finderassistancea.video.qq.com/uploadpartdfs?PartNumber=${partNumber}&UploadID=${encodeURIComponent(uploadId)}`;
35872
+ const resp = await lib_axios.put(url, chunk, {
35873
+ headers,
35874
+ maxBodyLength: 1 / 0,
35875
+ maxContentLength: 1 / 0,
35876
+ onUploadProgress: (progressEvent)=>{
35877
+ if (onProgress && progressEvent.bytes) onProgress(progressEvent.bytes);
35878
+ }
35879
+ });
35880
+ if (resp.data?.errCode !== void 0 && 0 !== resp.data.errCode) throw new Error(`分片 ${partNumber} 上传失败: ${resp.data.errMsg}`);
35881
+ return resp.data.ETag;
35882
+ }
35883
+ async confirmChunks(uploadId, fileName, uin, authKey, transFlag, taskId) {
35884
+ const headers = {
35885
+ "Content-MD5": "null",
35886
+ "X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=0&taskid=${taskId}&scene=0`,
35887
+ Authorization: authKey,
35888
+ Referer: "https://channels.weixin.qq.com/platform/post/create",
35889
+ Origin: "https://channels.weixin.qq.com"
35890
+ };
35891
+ const requestBody = {
35892
+ TransFlag: transFlag || "0_0",
35893
+ PartNumberMarker: "1"
35894
+ };
35895
+ const url = `https://finderassistancea.video.qq.com/listparts?UploadID=${encodeURIComponent(uploadId)}`;
35896
+ const resp = await lib_axios.post(url, requestBody, {
35897
+ headers
35898
+ });
35899
+ if (resp.data?.ListPartsResult?.Part) return resp.data.ListPartsResult.Part.map((p)=>({
35900
+ PartNumber: parseInt(p.PartNumber),
35901
+ ETag: p.ETag
35902
+ }));
35903
+ return [];
35904
+ }
35905
+ async completeUpload(uploadId, fileName, fileSize, uin, authKey, transFlag, partInfo, taskId) {
35906
+ const headers = {
35907
+ "Content-MD5": "null",
35908
+ "X-Arguments": `apptype=251&filetype=20304&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
35909
+ Authorization: authKey,
35910
+ Referer: "https://channels.weixin.qq.com/platform/post/create",
35911
+ Origin: "https://channels.weixin.qq.com"
35912
+ };
35913
+ const requestBody = {
35914
+ TransFlag: transFlag || "0_0",
35915
+ PartInfo: partInfo
35916
+ };
35917
+ const url = `https://finderassistancea.video.qq.com/completepartuploaddfs?UploadID=${encodeURIComponent(uploadId)}`;
35918
+ const resp = await lib_axios.post(url, requestBody, {
35919
+ headers
35920
+ });
35921
+ if (!resp.data?.DownloadURL) throw new Error(`完成上传失败: ${resp.data?.errMsg || "未知错误"}`);
35922
+ return resp.data.DownloadURL;
35923
+ }
35924
+ async asyncPool(concurrency, items, fn) {
35925
+ const executing = [];
35926
+ for (const item of items){
35927
+ const p = Promise.resolve().then(()=>fn(item));
35928
+ executing.push(p);
35929
+ if (executing.length >= concurrency) await Promise.race(executing);
35930
+ }
35931
+ await Promise.all(executing);
35932
+ }
35933
+ async upload(imagePath, uin, authKey, options = {}) {
35934
+ const { onProgress, transFlag } = options;
35935
+ const fileBuffer = await this.readFile(imagePath);
35936
+ const fileSize = fileBuffer.length;
35937
+ const fileName = external_node_path_default().basename(imagePath);
35938
+ if (fileSize > 20971520) throw new Error("图片大小超过 20MB 限制");
35939
+ this.md5 = this.calculateMd5(fileBuffer);
35940
+ const { width, height } = this.getImageSize(fileBuffer);
35941
+ this.startTime = Date.now();
35942
+ this.chunkCount = Math.ceil(fileSize / this.chunkSize);
35943
+ this.uploadedChunks = 0;
35944
+ this.partInfo = new Array(this.chunkCount).fill(null);
35945
+ const taskId = this.generateUUID();
35946
+ this.generateUUID();
35947
+ console.log(`[上传开始] 文件: ${fileName}, 大小: ${fileSize}, 分片: ${this.chunkCount}`);
35948
+ this.uploadTaskId = await this.getUploadId(fileSize, fileName, uin, authKey, taskId);
35949
+ console.log(`[获取 UploadID] ${this.uploadTaskId}`);
35950
+ this.startSpeedWatch();
35951
+ if (fileSize <= this.chunkSize) {
35952
+ console.log("[直接上传] 单文件模式");
35953
+ const etag = await this.uploadChunk(fileBuffer, fileName, fileSize, uin, authKey, this.uploadTaskId, 1, taskId, (delta)=>this.updateProgress(delta, onProgress));
35954
+ this.partInfo[0] = {
35955
+ PartNumber: 1,
35956
+ ETag: etag
35957
+ };
35958
+ this.uploadedChunks = 1;
35959
+ } else {
35960
+ console.log(`[分片上传] 并发数: ${this.concurrentLimit}`);
35961
+ const chunks = Array.from({
35962
+ length: this.chunkCount
35963
+ }, (_, i)=>i);
35964
+ await this.asyncPool(this.concurrentLimit, chunks, async (index)=>{
35965
+ const start = index * this.chunkSize;
35966
+ const end = Math.min((index + 1) * this.chunkSize, fileSize);
35967
+ const chunk = fileBuffer.slice(start, end);
35968
+ console.log(`[上传分片 ${index + 1}/${this.chunkCount}] 大小: ${chunk.length}`);
35969
+ const etag = await this.uploadChunk(chunk, fileName, fileSize, uin, authKey, this.uploadTaskId, index + 1, taskId, (delta)=>this.updateProgress(delta, onProgress));
35970
+ this.partInfo[index] = {
35971
+ PartNumber: index + 1,
35972
+ ETag: etag
35973
+ };
35974
+ this.uploadedChunks++;
35975
+ onProgress?.({
35976
+ uploadedChunks: this.uploadedChunks,
35977
+ totalChunks: this.chunkCount,
35978
+ percent: Math.floor(this.uploadedChunks / this.chunkCount * 100),
35979
+ speed: this.uploadSpeed
35980
+ });
35981
+ });
35982
+ }
35983
+ console.log("[完成上传] 合并分片...");
35984
+ const downloadUrl = await this.completeUpload(this.uploadTaskId, fileName, fileSize, uin, authKey, transFlag || "0_0", this.partInfo.filter(Boolean), taskId);
35985
+ this.stopSpeedWatch();
35986
+ return {
35987
+ downloadUrl,
35988
+ width,
35989
+ height,
35990
+ fileSize,
35991
+ md5: external_node_crypto_default().createHash("md5").update(fileBuffer).digest("hex")
35992
+ };
35993
+ }
35994
+ updateProgress(delta, onProgress) {}
35995
+ startSpeedWatch() {
35996
+ let lastUploaded = 0;
35997
+ this.speedInterval = setInterval(()=>{
35998
+ const current = this.uploadedChunks * this.chunkSize;
35999
+ this.uploadSpeed = Math.floor((current - lastUploaded) / 1024);
36000
+ this.speedRecords.push(this.uploadSpeed);
36001
+ lastUploaded = current;
36002
+ }, 1000);
36003
+ }
36004
+ stopSpeedWatch() {
36005
+ if (this.speedInterval) clearInterval(this.speedInterval);
35327
36006
  }
35328
36007
  }
36008
+ function generateUUID() {
36009
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c)=>{
36010
+ const r = 16 * Math.random() | 0;
36011
+ const v = "x" === c ? r : 0x3 & r | 0x8;
36012
+ return v.toString(16);
36013
+ });
36014
+ }
35329
36015
  function mock_getTimeStamp(length) {
35330
36016
  return Date.now().toString().substring(0, length);
35331
36017
  }
@@ -35374,119 +36060,21 @@ var __webpack_exports__ = {};
35374
36060
  });
35375
36061
  return response.data;
35376
36062
  }
35377
- async function getUploadId(fileSize, fileName, _finderUsername, taskId, uin, authKey, mediaType) {
35378
- const blockSize = 8388608;
35379
- const blockSum = Math.ceil(fileSize / blockSize);
35380
- const blockPartLength = [];
35381
- if (fileSize < blockSize) blockPartLength.push(fileSize);
35382
- else for(let i = 1; i <= blockSum; i++)if (i * blockSize <= fileSize) blockPartLength.push(i * blockSize);
35383
- else {
35384
- blockPartLength.push(fileSize);
35385
- break;
35386
- }
35387
- const requestBody = {
35388
- BlockSum: blockSum,
35389
- BlockPartLength: blockPartLength
35390
- };
35391
- console.log("taskId:", taskId);
35392
- const headers = {
35393
- "X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=2`,
35394
- Authorization: authKey,
35395
- Accept: "application/json, text/plain, */*",
35396
- "Content-MD5": "null",
35397
- Referer: "https://channels.weixin.qq.com/",
35398
- Origin: "https://channels.weixin.qq.com/"
35399
- };
35400
- try {
35401
- const response = await lib_axios.put("https://finderassistancea.video.qq.com/applyuploaddfs", requestBody, {
35402
- headers
35403
- });
35404
- return response.data;
35405
- } catch (e) {
35406
- console.log("getUploadId error:", e);
35407
- return {
35408
- errCode: -1,
35409
- errMsg: e instanceof Error ? e.message : "未知错误"
35410
- };
35411
- }
35412
- }
35413
- async function uploadImagePart(imageBuffer, fileName, mediaType, _finderUsername, taskId, fileSize, uin, authKey, uploadId, partNumber = 1) {
35414
- const md5Hash = calculatePartialMd5(imageBuffer);
35415
- const headers = {
35416
- "Content-MD5": md5Hash,
35417
- "X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
35418
- Authorization: authKey,
35419
- "Content-Type": "application/octet-stream",
35420
- Referer: "https://channels.weixin.qq.com/platform/post/create",
35421
- Origin: "https://channels.weixin.qq.com",
35422
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
35423
- };
35424
- const url = `https://finderassistancea.video.qq.com/uploadpartdfs?PartNumber=${partNumber}&UploadID=${encodeURIComponent(uploadId)}`;
35425
- const response = await lib_axios.put(url, imageBuffer, {
35426
- headers
36063
+ async function uploadImageComplete(imagePath, taskId, finderUsername, uin, authKey) {
36064
+ const uploader = new VideoChannelUploader({
36065
+ chunkSize: 8388608,
36066
+ concurrentLimit: 4
35427
36067
  });
35428
- console.log("上传图片响应:", JSON.stringify(response.data));
35429
- return response.data;
35430
- }
35431
- async function getUploadedImageInfo(partInfo, _finderUsername, fileName, uploadId, fileSize, taskId, uin, authKey, mediaType) {
35432
- const headers = {
35433
- "Content-MD5": "null",
35434
- "X-Arguments": `apptype=251&filetype=${mediaType}&weixinnum=${uin}&filekey=${encodeURIComponent(fileName)}&filesize=${fileSize}&taskid=${taskId}&scene=0`,
35435
- Authorization: authKey,
35436
- Referer: "https://channels.weixin.qq.com/platform/post/create",
35437
- Origin: "https://channels.weixin.qq.com",
35438
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
35439
- };
35440
- const requestBody = {
35441
- TransFlag: "0_0",
35442
- PartInfo: partInfo
35443
- };
35444
- const url = `https://finderassistancea.video.qq.com/completepartuploaddfs?UploadID=${encodeURIComponent(uploadId)}`;
35445
- const response = await lib_axios.post(url, requestBody, {
35446
- headers
36068
+ const result = await uploader.upload(imagePath, uin, authKey, {
36069
+ onProgress: (p)=>console.log(`上传进度: ${p.percent}%`)
35447
36070
  });
35448
- return response.data;
35449
- }
35450
- async function uploadImageComplete(imagePath, taskId, finderUsername, uin, authKey, _retryCount = 3) {
35451
- try {
35452
- const imageBuffer = await readImageFile(imagePath);
35453
- if (!imageBuffer || 0 === imageBuffer.length) return {
35454
- errMsg: `读取图片失败: ${imagePath}`
35455
- };
35456
- if (imageBuffer.length > 5242880) return {
35457
- errMsg: `图片大小超限制5MB: ${imagePath}`
35458
- };
35459
- const fileName = external_node_path_default().basename(imagePath);
35460
- const fileSize = imageBuffer.length;
35461
- const uploadIdResponse = await getUploadId(fileSize, fileName, finderUsername, taskId, uin, authKey, 20304);
35462
- console.log("申请上传ID响应SSS:", JSON.stringify(uploadIdResponse));
35463
- if (!uploadIdResponse.UploadID) return {
35464
- errMsg: `获取上传id失败: ${uploadIdResponse.errMsg}`
35465
- };
35466
- const uploadResponse = await uploadImagePart(imageBuffer, fileName, 20304, finderUsername, taskId, fileSize, uin, authKey, uploadIdResponse.UploadID);
35467
- if (!uploadResponse.ETag) return {
35468
- errMsg: `上传图片失败: ${uploadResponse.errMsg}`
35469
- };
35470
- const partInfo = [
35471
- {
35472
- PartNumber: 1,
35473
- ETag: uploadResponse.ETag
35474
- }
35475
- ];
35476
- const imageInfo = await getUploadedImageInfo(partInfo, finderUsername, fileName, uploadIdResponse.UploadID, fileSize, taskId, uin, authKey, 20304);
35477
- if (!imageInfo.DownloadURL) return {
35478
- errMsg: `获取图片信息失败: ${imageInfo.errMsg}`
35479
- };
35480
- const md5 = calculateBufferMd5(imageBuffer);
35481
- return {
35482
- DownloadURL: imageInfo.DownloadURL,
35483
- md5
35484
- };
35485
- } catch (error) {
35486
- return {
35487
- errMsg: error instanceof Error ? error.message : "上传图片失败"
35488
- };
35489
- }
36071
+ return {
36072
+ DownloadURL: result.downloadUrl,
36073
+ md5: result.md5,
36074
+ fileSize: result.fileSize,
36075
+ width: result.width,
36076
+ height: result.height
36077
+ };
35490
36078
  }
35491
36079
  function buildLocation(address) {
35492
36080
  if (!address || !address.city) return {
@@ -35558,7 +36146,7 @@ var __webpack_exports__ = {};
35558
36146
  const topicList = params.topic || [];
35559
36147
  const location1 = params.address ? buildLocation(params.address) : {};
35560
36148
  const publishData = {
35561
- clientid: utils_uuidv4(),
36149
+ clientid: generateUUID(),
35562
36150
  timestamp: mock_getTimeStamp(13),
35563
36151
  _log_finder_id: params.finderUsername,
35564
36152
  _log_finder_uin: "",
@@ -35600,7 +36188,7 @@ var __webpack_exports__ = {};
35600
36188
  }
35601
36189
  }
35602
36190
  };
35603
- if (params.scheduledPublish) publishData.effectiveTime = Math.floor(params.scheduledPublish / 1000);
36191
+ if (params.scheduledPublish) publishData.effectiveTime = params.scheduledPublish;
35604
36192
  const objectDesc = publishData.objectDesc;
35605
36193
  if (topicList.length) objectDesc.topic = {
35606
36194
  finderTopicInfo: buildTopicXml(params.content, topicList)
@@ -35640,6 +36228,7 @@ var __webpack_exports__ = {};
35640
36228
  _pageUrl: "https://channels.weixin.qq.com/micro/content/post/finderNewLifeCreate"
35641
36229
  };
35642
36230
  const queryString = new URLSearchParams(queryData).toString();
36231
+ console.log("1111111111111111", JSON.stringify(requestBody));
35643
36232
  const apiResponse = await lib_axios.post(`${publishUrl}?${queryString}`, requestBody, {
35644
36233
  headers: {
35645
36234
  cookie: cookies,
@@ -35653,6 +36242,7 @@ var __webpack_exports__ = {};
35653
36242
  }
35654
36243
  const shipinhaoPublish_mock_mockAction = async (task, params)=>{
35655
36244
  task.logger.info("开始执行视频号发布 - Mock API 方式");
36245
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
35656
36246
  if (!params.extraParam.fingerPrintDeviceId || !params.extraParam.aId) return utils_response(400, "fingerPrintDeviceId和aId 不能为空", "");
35657
36247
  try {
35658
36248
  const cookieString = params.cookies.map((c)=>`${c.name}=${c.value}`).join("; ");
@@ -35675,7 +36265,8 @@ var __webpack_exports__ = {};
35675
36265
  if (0 !== authKeyResponse.errCode || !authKeyResponse.data?.authKey) return utils_response(authKeyResponse.errCode || 500, `获取上传认证参数失败: ${authKeyResponse.errMsg}`, "");
35676
36266
  const authKey = authKeyResponse.data.authKey;
35677
36267
  const uin = authKeyResponse.data.uin;
35678
- const taskId = utils_uuidv4();
36268
+ if (!uin) return utils_response(500, "获取用户 uin 失败", "");
36269
+ const taskId = String(generateUUID());
35679
36270
  task.logger.info(`开始上传 ${images.length} 张图片...`);
35680
36271
  const uploadedImages = [];
35681
36272
  for(let i = 0; i < images.length; i++){
@@ -35686,11 +36277,11 @@ var __webpack_exports__ = {};
35686
36277
  uploadedImages.push({
35687
36278
  url: `https://finder.video.qq.com${uploadResult.DownloadURL.split("qq.com")[1] || ""}`,
35688
36279
  md5sum: uploadResult.md5 || "",
35689
- fileSize: 0,
36280
+ fileSize: uploadResult.fileSize || 0,
35690
36281
  thumbUrl: uploadResult.DownloadURL,
35691
36282
  fullThumbUrl: uploadResult.DownloadURL,
35692
- width: 0,
35693
- height: 0,
36283
+ width: uploadResult.width || 0,
36284
+ height: uploadResult.height || 0,
35694
36285
  mediaType: 2,
35695
36286
  videoPlayLen: 0,
35696
36287
  urlCdnTaskId: ""
@@ -35715,6 +36306,7 @@ var __webpack_exports__ = {};
35715
36306
  topic: topicNames,
35716
36307
  link: params.link,
35717
36308
  address: addressInfo,
36309
+ collection: params.collection,
35718
36310
  scheduledPublish: params.scheduledPublish,
35719
36311
  music: params.music
35720
36312
  });
@@ -35723,6 +36315,12 @@ var __webpack_exports__ = {};
35723
36315
  if (0 === resultCode) {
35724
36316
  task.logger.info("发布成功");
35725
36317
  const publishId = uploadedImages[0]?.thumbUrl?.split("encfilekey=")[1]?.split("&")[0] || "";
36318
+ await updateTaskState?.({
36319
+ state: types_TaskState.SUCCESS,
36320
+ result: {
36321
+ response: resultMsg
36322
+ }
36323
+ });
35726
36324
  return utils_response(0, "发布成功", publishId);
35727
36325
  }
35728
36326
  let errorMessage = resultMsg;
@@ -35731,6 +36329,10 @@ var __webpack_exports__ = {};
35731
36329
  else if (300330 === resultCode) errorMessage = "未登录";
35732
36330
  else if (300002 === resultCode) errorMessage = "官方平台在校验音乐/位置/定时信息时失败了,请重新编辑后发布";
35733
36331
  task.logger.error(`发布失败: ${errorMessage}`);
36332
+ await updateTaskState?.({
36333
+ state: types_TaskState.FAILED,
36334
+ error: errorMessage
36335
+ });
35734
36336
  return utils_response(resultCode || 500, errorMessage, "");
35735
36337
  } catch (error) {
35736
36338
  const errorMsg = error instanceof Error ? error.message : "发布失败";
@@ -35772,33 +36374,6 @@ var __webpack_exports__ = {};
35772
36374
  }
35773
36375
  throw lastError;
35774
36376
  };
35775
- const safeClick = async (locator)=>{
35776
- if (!locator) return false;
35777
- try {
35778
- await locator.click({
35779
- timeout: 5000
35780
- });
35781
- return true;
35782
- } catch (error) {
35783
- task.logger.warn(`点击失败: ${error}`);
35784
- return false;
35785
- }
35786
- };
35787
- const safeFill = async (locator, text)=>{
35788
- if (!locator || !text) return false;
35789
- try {
35790
- await locator.clear({
35791
- timeout: 3000
35792
- });
35793
- await locator.fill(text, {
35794
- timeout: 5000
35795
- });
35796
- return true;
35797
- } catch (error) {
35798
- task.logger.warn(`填充文本失败: ${error}`);
35799
- return false;
35800
- }
35801
- };
35802
36377
  task.logger.info("等待页面加载...");
35803
36378
  task.logger.info("检查登录状态...");
35804
36379
  if (task.debug) {
@@ -35812,16 +36387,8 @@ var __webpack_exports__ = {};
35812
36387
  timeout: 10000
35813
36388
  });
35814
36389
  task.logger.info("✓ 登录状态正常,找到编辑器容器");
35815
- } catch (error) {
36390
+ } catch {
35816
36391
  task.logger.error("✗ 未找到编辑器,可能登录失效");
35817
- if (task.debug) {
35818
- const screenshotPath = external_node_path_default().join(tmpCachePath, `login-error-${Date.now()}.png`);
35819
- await page.screenshot({
35820
- path: screenshotPath,
35821
- fullPage: true
35822
- });
35823
- task.logger.error(`登录检查失败截图: ${screenshotPath}`);
35824
- }
35825
36392
  return {
35826
36393
  code: 414,
35827
36394
  message: "登录失效或页面加载异常",
@@ -35888,7 +36455,12 @@ var __webpack_exports__ = {};
35888
36455
  const titleInput = await waitForElement('input[placeholder*="填写标题"]', 10000);
35889
36456
  if (!titleInput) throw new Error("未找到标题输入框");
35890
36457
  await titleInput.click();
35891
- await safeFill(titleInput, params.title);
36458
+ await titleInput.clear({
36459
+ timeout: 3000
36460
+ });
36461
+ await titleInput.fill(params.title, {
36462
+ timeout: 5000
36463
+ });
35892
36464
  task.logger.info("标题填写完成");
35893
36465
  });
35894
36466
  }
@@ -35899,137 +36471,518 @@ var __webpack_exports__ = {};
35899
36471
  if (!descEditor) throw new Error("未找到描述编辑器");
35900
36472
  await descEditor.click();
35901
36473
  await page.waitForTimeout(500);
35902
- if (params.topic && params.topic.length > 0) {
35903
- const topicButton = page.locator(".quick-btns > .finder-tag-wrap.btn");
35904
- const contentWithoutTopics = params.content.replace(/#[^#]+#/g, "").trim();
35905
- if (contentWithoutTopics) {
35906
- await descEditor.pressSequentially(contentWithoutTopics, {
35907
- delay: 50
35908
- });
35909
- await page.waitForTimeout(500);
35910
- }
35911
- for(let i = 0; i < params.topic.length; i++){
35912
- const topic = params.topic[i];
35913
- task.logger.info(`添加话题: ${topic}`);
35914
- await page.waitForTimeout(300);
35915
- if (await topicButton.count() > 0) {
35916
- await topicButton.click();
35917
- await page.waitForTimeout(500);
35918
- }
35919
- await descEditor.pressSequentially(topic, {
35920
- delay: 50
35921
- });
35922
- await page.waitForTimeout(500);
35923
- }
35924
- } else await descEditor.pressSequentially(params.content, {
35925
- delay: 50
36474
+ await descEditor.evaluate((el)=>{
36475
+ el.textContent = "";
35926
36476
  });
36477
+ await page.waitForTimeout(300);
36478
+ task.logger.info("已清空编辑器内容");
36479
+ await descEditor.pressSequentially(params.content, {
36480
+ delay: 10
36481
+ });
36482
+ await page.waitForTimeout(500);
35927
36483
  task.logger.info("内容填写完成");
35928
36484
  });
35929
36485
  }
35930
- if (params.address) {
36486
+ if (params.address?.poi_id) {
35931
36487
  task.logger.info(`选择地点: ${params.address.name}`);
35932
- try {
35933
- const locationSelector = await waitForElement(".location-selector, .address-input", 5000);
35934
- if (locationSelector) {
35935
- await safeClick(locationSelector);
35936
- await page.waitForTimeout(500);
35937
- const locationInput = page.locator(".location-search input, .address-input input");
35938
- if (await locationInput.count() > 0) {
35939
- await locationInput.first().fill(params.address.name);
35940
- await page.waitForTimeout(1000);
35941
- const firstLocation = page.locator(".location-list .location-item, .d-options .d-grid-item").first();
35942
- if (await firstLocation.count() > 0) {
35943
- await firstLocation.click();
35944
- task.logger.info("地点选择完成");
35945
- }
35946
- }
35947
- }
35948
- } catch (error) {
35949
- task.logger.warn(`地点选择失败: ${error}`);
35950
- }
36488
+ const instance = page.locator(".position-display-wrap");
36489
+ await instance.click();
36490
+ await page.waitForTimeout(1000);
36491
+ await page.locator(".location-filter-wrap input").fill(params.address?.name || params.address?.address || params.address?.city_name);
36492
+ await page.waitForTimeout(2000);
36493
+ const poperInstance = page.locator(".location-filter-wrap .common-option-list-wrap .option-item");
36494
+ await poperInstance.nth(1).waitFor();
36495
+ await poperInstance.nth(1).click();
36496
+ task.logger.info("地点选择完成");
36497
+ }
36498
+ if (params.collection) {
36499
+ task.logger.info(`选择合集: ${params.collection.collectionName}`);
36500
+ const instanceCollection = page.locator(".post-album-display-wrap");
36501
+ await instanceCollection.click();
36502
+ await page.waitForTimeout(1000);
36503
+ page.locator(".post-album-wrap .option-item").filter({
36504
+ hasText: params.collection.collectionName
36505
+ }).first().click({
36506
+ force: true
36507
+ });
36508
+ }
36509
+ if (params.link) {
36510
+ const instanceLink = page.locator(".link-display-wrap");
36511
+ await instanceLink.first().click();
36512
+ task.logger.info(`添加链接: ${params.link.link}`);
36513
+ await page.waitForTimeout(500);
36514
+ const linkTypeName = 1 === params.link.urlType ? "公众号文章" : "红包封面";
36515
+ page.locator(".post-link-wrap .link-list-options .link-option-item").filter({
36516
+ hasText: linkTypeName
36517
+ }).first().click({
36518
+ force: true
36519
+ });
36520
+ await waitForElement(".link-input-wrap", 3000);
36521
+ const linkInput = page.locator('.link-input-wrap input[type="text"]');
36522
+ await linkInput.first().fill(params.link.link);
36523
+ }
36524
+ if (params.music) {
36525
+ task.logger.info(`添加背景音乐: ${params.music.name}`);
36526
+ const musicFormItem = page.locator(".post-with-link").filter({
36527
+ hasText: "音乐"
36528
+ });
36529
+ const musicDisplayWrap = musicFormItem.locator(".link-display-wrap").first();
36530
+ await musicDisplayWrap.click();
36531
+ const searchInput = musicFormItem.locator('.weui-desktop-search input[type="text"]').first();
36532
+ const searchTxt = `${params.music.name} - ${params.music.authorName}`;
36533
+ await searchInput.fill(searchTxt);
36534
+ await page.waitForTimeout(300);
36535
+ await searchInput.press("Enter");
36536
+ await page.waitForTimeout(2000);
36537
+ const bgmItemWrap = musicFormItem.locator(".bgm-item-wrap").filter({
36538
+ hasText: searchTxt
36539
+ }).first();
36540
+ await bgmItemWrap.hover();
36541
+ await page.waitForTimeout(500);
36542
+ await bgmItemWrap.locator(".selected-icon").first().click({
36543
+ force: true
36544
+ });
35951
36545
  }
35952
36546
  if (!params.isImmediatelyPublish && params.scheduledPublish) {
35953
36547
  task.logger.info("设置定时发布");
35954
- try {
35955
- const scheduledRadio = page.locator('text="定时发布"').first();
35956
- if (await scheduledRadio.count() > 0) {
35957
- await scheduledRadio.click();
35958
- await page.waitForTimeout(500);
35959
- const dateInput = page.locator(".date-picker input").first();
35960
- if (await dateInput.count() > 0) {
35961
- const publishDate = new Date(1000 * params.scheduledPublish);
35962
- const dateStr = publishDate.toISOString().slice(0, 16).replace("T", " ");
35963
- await dateInput.fill(dateStr);
35964
- task.logger.info(`定时发布时间设置为: ${dateStr}`);
35965
- }
35966
- }
35967
- } catch (error) {
35968
- task.logger.warn(`定时发布设置失败: ${error}`);
35969
- }
36548
+ const timingRadio = page.locator(".weui-desktop-form__check-content").filter({
36549
+ hasNotText: "不定时"
36550
+ }).first();
36551
+ await timingRadio.click();
36552
+ await page.waitForTimeout(500);
36553
+ const instance = page.locator('.weui-desktop-picker__date input[placeholder*="请选择发表时间"]');
36554
+ await instance.click();
36555
+ const dateD = utils_TimeFormatter.format(params.scheduledPublish, "d");
36556
+ const nowMonth = utils_TimeFormatter.format(Date.now(), "MM月");
36557
+ const nowMonthText = utils_TimeFormatter.format(Date.now(), "M月");
36558
+ const month = utils_TimeFormatter.format(params.scheduledPublish, "MM月");
36559
+ const monthLocator = await page.locator("weui-desktop-picker__panel__label").filter({
36560
+ hasText: month
36561
+ }).first();
36562
+ if (!monthLocator) {
36563
+ await page.locator(".weui-desktop-picker__panel__label").filter({
36564
+ hasText: nowMonth
36565
+ }).first().click();
36566
+ await page.waitForTimeout(500);
36567
+ await page.locator(".weui-desktop-picker__table-row td a").filter({
36568
+ hasText: nowMonthText
36569
+ }).first().click();
36570
+ }
36571
+ await page.waitForTimeout(500);
36572
+ await page.locator(".weui-desktop-picker__table-row td a").filter({
36573
+ hasText: dateD
36574
+ }).first().click();
36575
+ await page.locator(".weui-desktop-form__input-wrp input[placeholder*='请选择时间']").fill(utils_TimeFormatter.format(params.scheduledPublish, "hh:mm"));
36576
+ await page.locator("i.weui-desktop-icon__time").click();
36577
+ await page.locator(".post-time-wrap .form-item .label").filter({
36578
+ hasText: "发表时间"
36579
+ }).click();
35970
36580
  }
35971
36581
  task.logger.info("准备发布...");
35972
- await page.waitForTimeout(1000);
35973
- const publishPromise = page.waitForResponse((response)=>{
36582
+ await page.waitForTimeout(300);
36583
+ let articleId = "";
36584
+ let message = "";
36585
+ const handleResponse = async (response)=>{
35974
36586
  const url = response.url();
35975
- return url.includes("/post/post_create") || url.includes("/post/post_draft");
35976
- }, {
35977
- timeout: 60000
36587
+ if (url.includes("/post/post_create") || url.includes("/post/post_draft")) {
36588
+ const jsonResponse = await response.json();
36589
+ page.off("response", handleResponse);
36590
+ articleId = jsonResponse.object?.id || jsonResponse.data?.objectId || "";
36591
+ message = jsonResponse?.errMsg || "";
36592
+ }
36593
+ };
36594
+ page.on("response", handleResponse);
36595
+ task._timerRecord.PrePublish = Date.now();
36596
+ const publishText = "1" === params.publishType ? "发表" : "保存草稿";
36597
+ await page.locator(".form-btns .weui-desktop-btn").filter({
36598
+ hasText: publishText
36599
+ }).first().click();
36600
+ task.logger.info("已点击发布按钮,等待响应...");
36601
+ await page.close();
36602
+ return success(articleId, message || "发布成功");
36603
+ } catch (error) {
36604
+ const errorMsg = error instanceof Error ? error.message : String(error);
36605
+ task.logger.error(`微信视频号发布失败: ${errorMsg}`);
36606
+ return utils_response(500, `微信视频号发布失败: ${errorMsg}`, "");
36607
+ }
36608
+ };
36609
+ const rpaAction_Server = async (task, params)=>{
36610
+ task.logger.info("开始微信视频号发布(Server 模式)");
36611
+ const defaultPage = task.steelBrowserContext?.pages()[0];
36612
+ if (defaultPage) {
36613
+ if (!defaultPage._routeRegistered) {
36614
+ defaultPage._routeRegistered = true;
36615
+ const blockedPatterns = [
36616
+ "**/apm-fe.weixin.com*",
36617
+ "**/t2.weixin.com*"
36618
+ ].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
36619
+ await defaultPage.route("**/*", async (route)=>{
36620
+ const req = route.request();
36621
+ const url = req.url();
36622
+ const blocked = blockedPatterns.some((regex)=>regex.test(url));
36623
+ if (!blocked) return route.continue();
36624
+ if ("OPTIONS" === req.method()) {
36625
+ console.log("处理 OPTIONS 预检:", url);
36626
+ await route.fulfill({
36627
+ status: 204,
36628
+ headers: {
36629
+ "access-control-allow-origin": "*",
36630
+ "access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
36631
+ "access-control-allow-headers": "*"
36632
+ },
36633
+ body: ""
36634
+ });
36635
+ return;
36636
+ }
36637
+ await route.fulfill({
36638
+ status: 204,
36639
+ body: ""
36640
+ });
36641
+ });
36642
+ }
36643
+ }
36644
+ const tmpCachePath = task.getTmpPath();
36645
+ task.logger?.info("==>进入RPA操作:任务开始,下载图片开始...");
36646
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
36647
+ const imagePromise = Promise.all(params.banners.map((url)=>{
36648
+ const fileName = getFilenameFromUrl(url);
36649
+ return downloadImage(url, external_node_path_default().join(tmpCachePath, fileName));
36650
+ }));
36651
+ let proxyUrl;
36652
+ if (params.localIP) {
36653
+ const args = [
36654
+ params.localIP,
36655
+ params.proxyLoc,
36656
+ params.accountId
36657
+ ];
36658
+ task.logger?.info(`==> 开始获取代理信息:${args}`);
36659
+ const ProxyAgentResult = await ProxyAgent({
36660
+ logger: task.logger
36661
+ }, ...args);
36662
+ task.logger?.info("==> 代理信息获取成功!");
36663
+ proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
36664
+ }
36665
+ task.logger?.info("==>开始打开视频号页面...");
36666
+ const page = await task.createPage({
36667
+ show: task.debug,
36668
+ cookies: params.cookies,
36669
+ proxyUrl,
36670
+ url: params.url || "https://channels.weixin.qq.com/platform/post/finderNewLifeCreate",
36671
+ ...params.viewport ? {
36672
+ viewport: params.viewport
36673
+ } : {}
36674
+ });
36675
+ task.logger?.info("==>视频号页面打开成功");
36676
+ console.log(task.steelConnector?.getLive(task.sessionId || ""));
36677
+ await updateTaskState?.({
36678
+ state: types_TaskState.ACTION,
36679
+ connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
36680
+ sessionId: task.sessionId
36681
+ });
36682
+ const clickTimeout = 10000;
36683
+ try {
36684
+ await page.waitForSelector(".post-edit-wrap", {
36685
+ state: "visible",
36686
+ timeout: 10000
35978
36687
  });
35979
- const publishButton = await waitForElement(".form-btns .weui-desktop-btn_wrp .weui-desktop-btn.weui-desktop-btn_primary", 10000);
35980
- if (publishButton) {
35981
- await publishButton.click();
35982
- task.logger.info("已点击发布按钮,等待响应...");
36688
+ task.logger?.info(" 登录状态正常,找到编辑器容器");
36689
+ } catch (error) {
36690
+ task.logger?.error("✗ 未找到编辑器,可能登录失效");
36691
+ return {
36692
+ code: 414,
36693
+ message: "登录失效或页面加载异常",
36694
+ data: page.url()
36695
+ };
36696
+ }
36697
+ const images = await imagePromise;
36698
+ task.logger?.info(`==>图片下载完成,共 ${images.length} 张,开始上传图片...`);
36699
+ const uploadSelectors = [
36700
+ '.ant-upload-btn input[type="file"]',
36701
+ '.upload input[type="file"][accept*="image"]',
36702
+ '.upload-wrap input[type="file"]',
36703
+ 'input[type="file"][accept*="image"]'
36704
+ ];
36705
+ let uploadInput = null;
36706
+ for (const selector of uploadSelectors){
36707
+ const input = page.locator(selector);
36708
+ const count = await input.count();
36709
+ if (count > 0) {
36710
+ uploadInput = input.first();
36711
+ task.logger?.info(`找到上传输入框: ${selector}`);
36712
+ break;
36713
+ }
36714
+ }
36715
+ if (!uploadInput) {
36716
+ task.logger?.warn("未找到上传输入框,等待 3 秒后重试...");
36717
+ await page.waitForTimeout(3000);
36718
+ const anyFileInput = page.locator('input[type="file"]');
36719
+ const inputCount = await anyFileInput.count();
36720
+ if (inputCount > 0) {
36721
+ uploadInput = anyFileInput.first();
36722
+ task.logger?.info(`找到文件输入框(共 ${inputCount} 个)`);
35983
36723
  } else {
35984
- task.logger.warn("未找到主发布按钮,尝试备用方案...");
35985
- const backupSelectors = [
35986
- 'button:has-text("发布")',
35987
- 'button:has-text("发表")',
35988
- 'div:has-text("发布")',
35989
- 'span:has-text("发 布")',
35990
- 'span:has-text("发布")'
35991
- ];
35992
- let clicked = false;
35993
- for (const selector of backupSelectors){
35994
- const btn = page.locator(selector).first();
35995
- if (await btn.count() > 0) {
35996
- await btn.click();
35997
- clicked = true;
35998
- task.logger.info(`使用备用按钮发布: ${selector}`);
35999
- break;
36000
- }
36724
+ if (task.debug) {
36725
+ const screenshotPath = external_node_path_default().join(tmpCachePath, `upload-error-${Date.now()}.png`);
36726
+ await page.screenshot({
36727
+ path: screenshotPath,
36728
+ fullPage: true
36729
+ });
36730
+ task.logger?.error(`未找到上传输入框,已截图保存至: ${screenshotPath}`);
36001
36731
  }
36002
- if (!clicked) return utils_response(500, "未找到发布按钮", "");
36732
+ throw new Error("未找到图片上传输入框");
36003
36733
  }
36004
- try {
36005
- const publishResponse = await publishPromise;
36006
- const result = await publishResponse.json();
36007
- task.logger.info("发布响应:", result);
36008
- if (0 === result.errCode || result.base_resp?.errcode === 0) {
36009
- const objectId = result.object?.id || result.data?.objectId || "";
36010
- task.logger.info(`✅ 发布成功,ID: ${objectId}`);
36011
- await page.waitForTimeout(2000);
36012
- return success(objectId);
36734
+ }
36735
+ await uploadInput.setInputFiles(images, {
36736
+ timeout: 60000
36737
+ });
36738
+ task.logger?.info(`==>图片上传完成: ${images.length} 张`);
36739
+ await page.waitForTimeout(3000);
36740
+ if (params.title) {
36741
+ task.logger?.info(`填写标题: ${params.title}`);
36742
+ const titleInput = page.locator('input[placeholder*="填写标题"]');
36743
+ await titleInput.waitFor({
36744
+ state: "visible",
36745
+ timeout: clickTimeout
36746
+ });
36747
+ await titleInput.click({
36748
+ timeout: clickTimeout
36749
+ });
36750
+ await titleInput.clear({
36751
+ timeout: 3000
36752
+ });
36753
+ await titleInput.fill(params.title, {
36754
+ timeout: 5000
36755
+ });
36756
+ task.logger?.info("==>标题填写完成");
36757
+ }
36758
+ if (params.content) {
36759
+ task.logger?.info("填写描述和话题");
36760
+ const descEditor = page.locator(".input-editor");
36761
+ await descEditor.waitFor({
36762
+ state: "visible",
36763
+ timeout: clickTimeout
36764
+ });
36765
+ await descEditor.click({
36766
+ timeout: clickTimeout
36767
+ });
36768
+ await page.waitForTimeout(500);
36769
+ await descEditor.evaluate((el)=>{
36770
+ el.textContent = "";
36771
+ });
36772
+ await page.waitForTimeout(300);
36773
+ task.logger?.info("已清空编辑器内容");
36774
+ await descEditor.pressSequentially(params.content, {
36775
+ delay: 10
36776
+ });
36777
+ await page.waitForTimeout(500);
36778
+ task.logger?.info("==>内容填写完成");
36779
+ }
36780
+ if (params.address?.poi_id) {
36781
+ task.logger?.info(`选择地点: ${params.address.name}`);
36782
+ const positionDisplayWrap = page.locator(".position-display-wrap");
36783
+ await positionDisplayWrap.click({
36784
+ timeout: clickTimeout
36785
+ });
36786
+ await page.waitForTimeout(1000);
36787
+ await page.locator(".location-filter-wrap input").fill(params.address?.name || params.address?.address || params.address?.city_name);
36788
+ await page.waitForTimeout(2000);
36789
+ const poperInstance = page.locator(".location-filter-wrap .common-option-list-wrap .option-item");
36790
+ await poperInstance.nth(1).waitFor();
36791
+ await poperInstance.nth(1).click({
36792
+ timeout: clickTimeout
36793
+ });
36794
+ task.logger?.info("==>地点选择完成");
36795
+ }
36796
+ if (params.collection) {
36797
+ task.logger?.info(`选择合集: ${params.collection.collectionName}`);
36798
+ const instanceCollection = page.locator(".post-album-display-wrap");
36799
+ await instanceCollection.click({
36800
+ timeout: clickTimeout
36801
+ });
36802
+ await page.waitForTimeout(1000);
36803
+ await page.locator(".post-album-wrap .option-item").filter({
36804
+ hasText: params.collection.collectionName
36805
+ }).first().click({
36806
+ force: true
36807
+ });
36808
+ task.logger?.info("==>合集选择完成");
36809
+ }
36810
+ if (params.link) {
36811
+ task.logger?.info(`添加链接: ${params.link.link}`);
36812
+ const instanceLink = page.locator(".link-display-wrap");
36813
+ await instanceLink.first().click({
36814
+ timeout: clickTimeout
36815
+ });
36816
+ await page.waitForTimeout(500);
36817
+ const linkTypeName = 1 === params.link.urlType ? "公众号文章" : "红包封面";
36818
+ await page.locator(".post-link-wrap .link-list-options .link-option-item").filter({
36819
+ hasText: linkTypeName
36820
+ }).first().click({
36821
+ force: true
36822
+ });
36823
+ await page.waitForSelector(".link-input-wrap", {
36824
+ state: "visible",
36825
+ timeout: 3000
36826
+ });
36827
+ const linkInput = page.locator('.link-input-wrap input[type="text"]');
36828
+ await linkInput.first().fill(params.link.link);
36829
+ task.logger?.info("==>链接添加完成");
36830
+ }
36831
+ if (params.music) {
36832
+ task.logger?.info(`添加背景音乐: ${params.music.name}`);
36833
+ const musicFormItem = page.locator(".post-with-link").filter({
36834
+ hasText: "音乐"
36835
+ });
36836
+ const musicDisplayWrap = musicFormItem.locator(".link-display-wrap").first();
36837
+ await musicDisplayWrap.click({
36838
+ timeout: clickTimeout
36839
+ });
36840
+ const searchInput = musicFormItem.locator('.weui-desktop-search input[type="text"]').first();
36841
+ const searchTxt = `${params.music.name} - ${params.music.authorName}`;
36842
+ await searchInput.fill(searchTxt);
36843
+ await page.waitForTimeout(300);
36844
+ await searchInput.press("Enter");
36845
+ await page.waitForTimeout(2000);
36846
+ const bgmItemWrap = musicFormItem.locator(".bgm-item-wrap").filter({
36847
+ hasText: searchTxt
36848
+ }).first();
36849
+ await bgmItemWrap.hover();
36850
+ await page.waitForTimeout(500);
36851
+ await bgmItemWrap.locator(".selected-icon").first().click({
36852
+ force: true
36853
+ });
36854
+ task.logger?.info("==>背景音乐添加完成");
36855
+ }
36856
+ if (!params.isImmediatelyPublish && params.scheduledPublish) {
36857
+ task.logger?.info("设置定时发布");
36858
+ const timingRadio = page.locator(".weui-desktop-form__check-content").filter({
36859
+ hasNotText: "不定时"
36860
+ }).first();
36861
+ await timingRadio.click({
36862
+ timeout: clickTimeout
36863
+ });
36864
+ await page.waitForTimeout(500);
36865
+ const dateInput = page.locator('.weui-desktop-picker__date input[placeholder*="请选择发表时间"]');
36866
+ await dateInput.click({
36867
+ timeout: clickTimeout
36868
+ });
36869
+ const dateD = utils_TimeFormatter.format(params.scheduledPublish, "d");
36870
+ const nowMonth = utils_TimeFormatter.format(Date.now(), "MM月");
36871
+ const nowMonthText = utils_TimeFormatter.format(Date.now(), "M月");
36872
+ const month = utils_TimeFormatter.format(params.scheduledPublish, "MM月");
36873
+ const monthLocator = page.locator("weui-desktop-picker__panel__label").filter({
36874
+ hasText: month
36875
+ }).first();
36876
+ const monthCount = await monthLocator.count();
36877
+ if (0 === monthCount) {
36878
+ await page.locator(".weui-desktop-picker__panel__label").filter({
36879
+ hasText: nowMonth
36880
+ }).first().click({
36881
+ timeout: clickTimeout
36882
+ });
36883
+ await page.waitForTimeout(500);
36884
+ await page.locator(".weui-desktop-picker__table-row td a").filter({
36885
+ hasText: nowMonthText
36886
+ }).first().click({
36887
+ timeout: clickTimeout
36888
+ });
36889
+ }
36890
+ await page.waitForTimeout(500);
36891
+ await page.locator(".weui-desktop-picker__table-row td a").filter({
36892
+ hasText: dateD
36893
+ }).first().click({
36894
+ timeout: clickTimeout
36895
+ });
36896
+ await page.locator(".weui-desktop-form__input-wrp input[placeholder*='请选择时间']").fill(utils_TimeFormatter.format(params.scheduledPublish, "hh:mm"));
36897
+ await page.locator("i.weui-desktop-icon__time").click({
36898
+ timeout: clickTimeout
36899
+ });
36900
+ await page.locator(".post-time-wrap .form-item .label").filter({
36901
+ hasText: "发表时间"
36902
+ }).click({
36903
+ timeout: clickTimeout
36904
+ });
36905
+ task.logger?.info("==>定时发布设置完成");
36906
+ }
36907
+ task.logger?.info("准备发布...");
36908
+ await page.waitForTimeout(300);
36909
+ if (MockPublish) {
36910
+ const message = "视频号模拟发布成功";
36911
+ const data = "123456789";
36912
+ await updateTaskState?.({
36913
+ state: types_TaskState.SUCCESS,
36914
+ result: {
36915
+ response: data
36013
36916
  }
36014
- {
36015
- const errorMsg = result.errMsg || result.base_resp?.errmsg || "发布失败";
36016
- const errorCode = result.errCode || result.base_resp?.errcode || 500;
36017
- task.logger.error(`❌ 发布失败 [${errorCode}]: ${errorMsg}`);
36018
- return utils_response(errorCode, errorMsg, "");
36917
+ });
36918
+ return success(data, message);
36919
+ }
36920
+ const publishResponse = await new Promise((resolve)=>{
36921
+ const handleResponse = async (response)=>{
36922
+ const url = response.url();
36923
+ if (url.includes("/post/post_create") || url.includes("/post/post_draft")) {
36924
+ const jsonResponse = await response.json();
36925
+ page.off("response", handleResponse);
36926
+ const articleId = jsonResponse.object?.id || jsonResponse.data?.objectId || "";
36927
+ const message = jsonResponse?.errMsg || "";
36928
+ const errCode = jsonResponse.data?.baseResp?.errcode ?? jsonResponse.errCode;
36929
+ if (0 === errCode) resolve({
36930
+ success: true,
36931
+ msg: message || "发布成功",
36932
+ data: {
36933
+ id: articleId,
36934
+ objectId: articleId
36935
+ }
36936
+ });
36937
+ else {
36938
+ let errorMessage = message;
36939
+ if (-11224 === errCode) errorMessage = "视频号管理员完成实名且绑定手机号后才可以发表";
36940
+ else if (300333 === errCode || 300334 === errCode) errorMessage = "登录失效";
36941
+ else if (300330 === errCode) errorMessage = "未登录";
36942
+ else if (300002 === errCode) errorMessage = "官方平台在校验音乐/位置/定时信息时失败了,请重新编辑后发布";
36943
+ resolve({
36944
+ success: false,
36945
+ msg: errorMessage
36946
+ });
36947
+ }
36019
36948
  }
36020
- } catch (error) {
36021
- task.logger.error(`等待发布响应超时: ${error.message}`);
36022
- return utils_response(500, "发布超时,请检查网络或稍后重试", "");
36023
- }
36024
- } catch (error) {
36025
- const errorMsg = error instanceof Error ? error.message : String(error);
36026
- const errorStack = error instanceof Error ? error.stack : "";
36027
- task.logger.error(`微信视频号发布失败: ${errorMsg}`);
36028
- task.logger.error(errorStack || "");
36029
- return utils_response(500, `微信视频号发布失败: ${errorMsg}`, "");
36030
- } finally{
36031
- if (!task.debug) await page.close();
36949
+ };
36950
+ page.on("response", handleResponse);
36951
+ const publishText = "1" === params.publishType ? "发表" : "保存草稿";
36952
+ page.locator(".form-btns .weui-desktop-btn").filter({
36953
+ hasText: publishText
36954
+ }).first().click({
36955
+ timeout: clickTimeout
36956
+ });
36957
+ setTimeout(()=>{
36958
+ page.off("response", handleResponse);
36959
+ resolve({
36960
+ success: false,
36961
+ msg: "发布超时"
36962
+ });
36963
+ }, 10000);
36964
+ });
36965
+ if (!publishResponse?.success) {
36966
+ const msg = `发布失败:${publishResponse?.msg || "未知错误"}`;
36967
+ await updateTaskState?.({
36968
+ state: types_TaskState.FAILED,
36969
+ error: msg
36970
+ });
36971
+ await page.close();
36972
+ return {
36973
+ code: 414,
36974
+ message: msg,
36975
+ data: ""
36976
+ };
36032
36977
  }
36978
+ await updateTaskState?.({
36979
+ state: types_TaskState.SUCCESS,
36980
+ result: {
36981
+ response: publishResponse?.data?.id || ""
36982
+ }
36983
+ });
36984
+ await page.close();
36985
+ return success(publishResponse?.data?.id || "", publishResponse?.msg || "发布成功");
36033
36986
  };
36034
36987
  const ShipinhaoPublishParamsSchema = ActionCommonParamsSchema.extend({
36035
36988
  title: classic_schemas_string(),
@@ -36038,19 +36991,14 @@ var __webpack_exports__ = {};
36038
36991
  topic: classic_schemas_array(classic_schemas_string()).optional(),
36039
36992
  address: classic_schemas_object({
36040
36993
  poi_id: classic_schemas_string(),
36041
- name: classic_schemas_string(),
36042
- address: classic_schemas_string(),
36994
+ name: classic_schemas_string().optional(),
36995
+ address: classic_schemas_string().optional(),
36043
36996
  latitude: classic_schemas_number(),
36044
36997
  longitude: classic_schemas_number(),
36045
- city_name: classic_schemas_string(),
36046
- poi_type: classic_schemas_number(),
36047
- type: classic_schemas_string()
36998
+ city_name: classic_schemas_string()
36048
36999
  }).optional(),
36049
37000
  link: classic_schemas_object({
36050
- urlType: classic_schemas_enum([
36051
- "1",
36052
- "2"
36053
- ]),
37001
+ urlType: classic_schemas_number(),
36054
37002
  link: classic_schemas_string(),
36055
37003
  title: classic_schemas_string()
36056
37004
  }).optional(),
@@ -36085,7 +37033,8 @@ var __webpack_exports__ = {};
36085
37033
  console.log("shipinhaoPublish params:", params);
36086
37034
  if ("rpa" === params.actionType) return shipinhaoPublish_rpa_rpaAction(task, params);
36087
37035
  if ("mockApi" === params.actionType) return shipinhaoPublish_mock_mockAction(task, params);
36088
- return executeAction(shipinhaoPublish_mock_mockAction, shipinhaoPublish_rpa_rpaAction)(task, params);
37036
+ if ("server" === params.actionType) return rpaAction_Server(task, params);
37037
+ return executeAction(shipinhaoPublish_mock_mockAction, rpaAction_Server)(task, params);
36089
37038
  };
36090
37039
  const toutiaoLogin_rpa_scanRetryMaxCount = 60;
36091
37040
  const toutiaoLogin_rpa_waitQrcodeResultMaxTime = 2000 * toutiaoLogin_rpa_scanRetryMaxCount;
@@ -36105,7 +37054,7 @@ var __webpack_exports__ = {};
36105
37054
  });
36106
37055
  } catch (e) {
36107
37056
  return {
36108
- code: 500,
37057
+ code: 414,
36109
37058
  message: `浏览器启动失败: ${e}`,
36110
37059
  data: {}
36111
37060
  };
@@ -37141,7 +38090,7 @@ var __webpack_exports__ = {};
37141
38090
  });
37142
38091
  } catch (e) {
37143
38092
  return {
37144
- code: 500,
38093
+ code: 414,
37145
38094
  message: `浏览器启动失败: ${e}`,
37146
38095
  data: {}
37147
38096
  };
@@ -39031,7 +39980,7 @@ var __webpack_exports__ = {};
39031
39980
  } catch (e) {
39032
39981
  task.logger.error("浏览器启动失败", e);
39033
39982
  return {
39034
- code: 500,
39983
+ code: 414,
39035
39984
  message: `浏览器启动失败: ${e}`,
39036
39985
  data: {}
39037
39986
  };
@@ -40012,7 +40961,7 @@ var __webpack_exports__ = {};
40012
40961
  await page.close();
40013
40962
  return success(response);
40014
40963
  };
40015
- const rpaAction_Server = async (task, params)=>{
40964
+ const rpa_server_rpaAction_Server = async (task, params)=>{
40016
40965
  if (params.originalBind && params?.selfDeclaration?.type === "source-statement") return {
40017
40966
  code: 414,
40018
40967
  message: "已声明原创不可选择“来源转载”",
@@ -40895,8 +41844,8 @@ var __webpack_exports__ = {};
40895
41844
  const xiaohongshuPublish = async (task, params)=>{
40896
41845
  if ("rpa" === params.actionType) return xiaohongshuPublish_rpa_rpaAction(task, params);
40897
41846
  if ("mockApi" === params.actionType) return xiaohongshuPublish_mock_mockAction(task, params);
40898
- if ("server" === params.actionType) return rpaAction_Server(task, params);
40899
- return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, rpaAction_Server)(task, params);
41847
+ if ("server" === params.actionType) return rpa_server_rpaAction_Server(task, params);
41848
+ return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, rpa_server_rpaAction_Server)(task, params);
40900
41849
  };
40901
41850
  const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
40902
41851
  const xiaohongshuWebCommentAction = async (_task, params)=>{
@@ -41616,6 +42565,9 @@ var __webpack_exports__ = {};
41616
42565
  getShipinhaoCommentList(params) {
41617
42566
  return this.bindTask(getShipinhaoCommentList, params);
41618
42567
  }
42568
+ createShipinhaoComment(params) {
42569
+ return this.bindTask(createShipinhaoComment, params);
42570
+ }
41619
42571
  getXhsCollection(params) {
41620
42572
  return this.bindTask(getXhsCollection, params);
41621
42573
  }
@@ -41682,6 +42634,18 @@ var __webpack_exports__ = {};
41682
42634
  douyinGetCollection(params) {
41683
42635
  return this.bindTask(douyinGetCollection, params);
41684
42636
  }
42637
+ douyinGetCommentList(params) {
42638
+ return this.bindTask(douyinGetCommentList, params);
42639
+ }
42640
+ douyinGetCommentReplyList(params) {
42641
+ return this.bindTask(douyinGetCommentReplyList, params);
42642
+ }
42643
+ douyinCreateCommentReply(params) {
42644
+ return this.bindTask(douyinCreateCommentReply, params);
42645
+ }
42646
+ douyinGetWorkList(params) {
42647
+ return this.bindTask(douyinGetWorkList, params);
42648
+ }
41685
42649
  douyinLogin(params) {
41686
42650
  return this.bindTask(douyinLogin, params);
41687
42651
  }