@iflyrpa/actions 3.0.1 → 3.0.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -5434,9 +5434,7 @@ function __webpack_require__(moduleId) {
5434
5434
  return module;
5435
5435
  };
5436
5436
  })();
5437
- var package_namespaceObject = {
5438
- i8: "3.0.0"
5439
- };
5437
+ var package_namespaceObject = JSON.parse('{"i8":"3.0.2-beta.0"}');
5440
5438
  var dist = __webpack_require__("../../node_modules/.pnpm/https-proxy-agent@7.0.6/node_modules/https-proxy-agent/dist/index.js");
5441
5439
  async function ProxyAgent(task, ip, adr, accountId, refresh) {
5442
5440
  const http = new Http({
@@ -5558,6 +5556,9 @@ class Http {
5558
5556
  case "ERR_BAD_REQUEST":
5559
5557
  _message = "请求出现错误,请检查请求参数!";
5560
5558
  break;
5559
+ case "ERR_BAD_RESPONSE":
5560
+ _message = `服务器响应异常 (${error.response?.status ?? "unknown"}),请稍后重试!`;
5561
+ break;
5561
5562
  case "ERR_CANCELED":
5562
5563
  errorResponse.code = 414;
5563
5564
  _message = "请求连接超时,请稍候重试!";
@@ -5608,6 +5609,9 @@ class Http {
5608
5609
  const isRetry = [
5609
5610
  0,
5610
5611
  500,
5612
+ 502,
5613
+ 503,
5614
+ 504,
5611
5615
  599
5612
5616
  ].includes(handledError.code);
5613
5617
  if (Rtimes < retries && isRetry) {
@@ -9618,7 +9622,7 @@ const types_errorResponse = (message, code = 500)=>({
9618
9622
  data: null
9619
9623
  });
9620
9624
  const MockPublish = false;
9621
- const DisabledReq = true;
9625
+ const DisabledReq = false;
9622
9626
  const scanRetryMaxCount = 60;
9623
9627
  const waitQrcodeResultMaxTime = 2000 * scanRetryMaxCount;
9624
9628
  const rpaServer = async (task, params)=>{
@@ -13925,7 +13929,7 @@ class DouyinImageUploader {
13925
13929
  this.authCache = null;
13926
13930
  this.authExpireTime = 0;
13927
13931
  this.AUTH_REFRESH_BUFFER = 300000;
13928
- this.CONCURRENT_LIMIT = 5;
13932
+ this.CONCURRENT_LIMIT = 10;
13929
13933
  this.UPLOAD_DELAY = 1000;
13930
13934
  this.UPLOAD_TIMEOUT = 300000;
13931
13935
  this.TOS_UPLOAD_TIMEOUT = 600000;
@@ -13954,16 +13958,17 @@ class DouyinImageUploader {
13954
13958
  const aBogus = imageUploader_getABogus(`https://creator.douyin.com/web/api/media/upload/auth/v5/?${queryString}`, {}, this.headers["user-agent"]);
13955
13959
  this.queryParams.a_bogus = aBogus;
13956
13960
  const newQueryString = new URLSearchParams(this.queryParams).toString();
13957
- const uploadAuth = await this.proxyHttp.api({
13958
- method: "get",
13959
- url: `https://creator.douyin.com/web/api/media/upload/auth/v5/?${newQueryString}`,
13960
- headers: {
13961
- ...this.headers,
13962
- "Content-Type": "application/json"
13963
- }
13964
- }, {
13965
- timeout: 300000
13966
- });
13961
+ const uploadAuth = await this.withRetry(()=>this.proxyHttp.api({
13962
+ method: "get",
13963
+ url: `https://creator.douyin.com/web/api/media/upload/auth/v5/?${newQueryString}`,
13964
+ headers: {
13965
+ ...this.headers,
13966
+ "Content-Type": "application/json"
13967
+ }
13968
+ }, {
13969
+ timeout: 300000,
13970
+ retries: 0
13971
+ }), 3, 1000, "获取上传凭证");
13967
13972
  if (!uploadAuth.auth) throw new Error(uploadAuth.status_msg || "获取上传权限失败");
13968
13973
  try {
13969
13974
  const authData = JSON.parse(uploadAuth.auth);
@@ -14003,19 +14008,19 @@ class DouyinImageUploader {
14003
14008
  };
14004
14009
  const result = generateAuthorization(addrParamsConfig).authorization;
14005
14010
  const addrParamsQueryString = canonicalQueryString(addrParamsConfig.params);
14006
- const response = await this.proxyHttp.api({
14007
- method: "get",
14008
- url: `https://imagex.bytedanceapi.com/?${addrParamsQueryString}`,
14009
- headers: {
14010
- ...this.headers,
14011
- Authorization: result,
14012
- "Content-Type": "application/json",
14013
- "X-amz-date": amzDate,
14014
- "X-amz-security-token": authData.SessionToken
14015
- }
14016
- }, {
14017
- timeout: this.UPLOAD_TIMEOUT
14018
- });
14011
+ const response = await this.withRetry(()=>this.proxyHttp.api({
14012
+ method: "get",
14013
+ url: `https://imagex.bytedanceapi.com/?${addrParamsQueryString}`,
14014
+ headers: {
14015
+ ...this.headers,
14016
+ Authorization: result,
14017
+ "Content-Type": "application/json",
14018
+ "X-amz-date": amzDate,
14019
+ "X-amz-security-token": authData.SessionToken
14020
+ }
14021
+ }, {
14022
+ timeout: this.UPLOAD_TIMEOUT
14023
+ }), 3, 1000, "获取上传地址");
14019
14024
  if (!response) throw new Error("获取上传地址失败: 响应为空");
14020
14025
  if (response.ResponseMetadata?.Error) throw new Error(`ImageX错误: ${response.ResponseMetadata.Error.Code} - ${response.ResponseMetadata.Error.Message}`);
14021
14026
  if (!response.Result) {
@@ -14046,23 +14051,24 @@ class DouyinImageUploader {
14046
14051
  console.log(`上传至: ${uploadUrl.substring(0, 80)}...`);
14047
14052
  console.log(`文件大小: ${imageInfo.size} bytes, CRC32: ${imageInfo.md5}`);
14048
14053
  try {
14049
- const uploadImgResp = await this.proxyHttp.api({
14050
- method: "post",
14051
- url: uploadUrl,
14052
- headers: {
14053
- ...this.headers,
14054
- Authorization: uploadAddr.auth,
14055
- "Content-crc32": imageInfo.md5,
14056
- "Content-Type": "application/octet-stream",
14057
- "Content-Length": imageInfo.size.toString()
14058
- },
14059
- data: fileBuffer,
14060
- httpAgent: this.uploadAgent,
14061
- httpsAgent: this.uploadAgent,
14062
- timeout: this.TOS_UPLOAD_TIMEOUT,
14063
- maxBodyLength: 1 / 0,
14064
- maxContentLength: 1 / 0
14065
- });
14054
+ const uploadImgResp = await this.withRetry(()=>this.proxyHttp.api({
14055
+ method: "post",
14056
+ url: uploadUrl,
14057
+ headers: {
14058
+ ...this.headers,
14059
+ Authorization: uploadAddr.auth,
14060
+ "Content-crc32": imageInfo.md5,
14061
+ "Content-Type": "application/octet-stream",
14062
+ "Content-Length": imageInfo.size.toString()
14063
+ },
14064
+ data: fileBuffer,
14065
+ httpAgent: this.uploadAgent,
14066
+ httpsAgent: this.uploadAgent,
14067
+ maxBodyLength: 1 / 0,
14068
+ maxContentLength: 1 / 0
14069
+ }, {
14070
+ timeout: this.TOS_UPLOAD_TIMEOUT
14071
+ }), 5, 3000, "TOS上传");
14066
14072
  console.log("TOS 上传响应:", uploadImgResp);
14067
14073
  const isSuccess = uploadImgResp && (2000 === uploadImgResp.code || 200 === uploadImgResp.status || 200 === uploadImgResp.statusCode || uploadImgResp.data && uploadImgResp.data.crc32 || "Success" === uploadImgResp.message);
14068
14074
  if (!isSuccess) throw new Error(`上传失败: ${JSON.stringify(uploadImgResp)}`);
@@ -14083,20 +14089,22 @@ class DouyinImageUploader {
14083
14089
  async processSingleImage(imageUrl, index, total) {
14084
14090
  console.log(`\n[${index + 1}/${total}] 处理图片: ${imageUrl.substring(0, 50)}...`);
14085
14091
  const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(imageUrl);
14086
- const localPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(this.tmpCachePath, fileName);
14092
+ const localPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].resolve(this.tmpCachePath, fileName);
14087
14093
  try {
14088
14094
  await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(imageUrl, localPath);
14089
14095
  console.log(`图片下载完成: ${localPath}`);
14096
+ const imageInfo = await this.getImageInfo(localPath);
14097
+ console.log(`图片信息: ${imageInfo.width}x${imageInfo.height}, ${imageInfo.size} bytes`);
14098
+ const auth = await this.getValidAuth();
14099
+ const uploadAddr = await this.getUploadAddress(auth);
14100
+ const result = await this.uploadToTOS(imageInfo, uploadAddr);
14101
+ this.safeDeleteFile(localPath);
14102
+ return result;
14090
14103
  } catch (error) {
14091
- throw new Error(`下载图片失败: ${imageUrl}`);
14092
- }
14093
- const imageInfo = await this.getImageInfo(localPath);
14094
- console.log(`图片信息: ${imageInfo.width}x${imageInfo.height}, ${imageInfo.size} bytes`);
14095
- const auth = await this.getValidAuth();
14096
- const uploadAddr = await this.getUploadAddress(auth);
14097
- const result = await this.uploadToTOS(imageInfo, uploadAddr);
14098
- this.safeDeleteFile(localPath);
14099
- return result;
14104
+ console.error(`[${index + 1}/${total}] 图片上传失败,已跳过: ${imageUrl}`, error?.message ?? error);
14105
+ this.safeDeleteFile(localPath);
14106
+ return null;
14107
+ }
14100
14108
  }
14101
14109
  async getImageInfo(localPath) {
14102
14110
  const stats = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].statSync(localPath);
@@ -14129,13 +14137,11 @@ class DouyinImageUploader {
14129
14137
  const globalIndex = i + idx;
14130
14138
  return this.processSingleImage(url, globalIndex, total);
14131
14139
  });
14132
- try {
14133
- const batchResults = await Promise.all(batchPromises);
14134
- results.push(...batchResults);
14135
- } catch (error) {
14136
- console.error(`批次 ${batchIndex} 上传失败:`, error);
14137
- throw error;
14138
- }
14140
+ const batchResults = await Promise.all(batchPromises);
14141
+ const successResults = batchResults.filter((r)=>null !== r);
14142
+ results.push(...successResults);
14143
+ const failedCount = batchResults.length - successResults.length;
14144
+ if (failedCount > 0) console.warn(`批次 ${batchIndex} 中有 ${failedCount} 张图片上传失败`);
14139
14145
  if (i + this.CONCURRENT_LIMIT < total) {
14140
14146
  console.log(`等待 ${this.UPLOAD_DELAY}ms...`);
14141
14147
  await this.delay(this.UPLOAD_DELAY);
@@ -14147,6 +14153,7 @@ class DouyinImageUploader {
14147
14153
  async uploadCover(coverUrl) {
14148
14154
  console.log("\n========== 上传封面 ==========\n");
14149
14155
  const result = await this.processSingleImage(coverUrl, 0, 1);
14156
+ if (!result) console.error(`封面图上传失败,已跳过: ${coverUrl}`);
14150
14157
  return result;
14151
14158
  }
14152
14159
  safeDeleteFile(filePath) {
@@ -14160,6 +14167,17 @@ class DouyinImageUploader {
14160
14167
  delay(ms) {
14161
14168
  return new Promise((resolve)=>setTimeout(resolve, ms));
14162
14169
  }
14170
+ async withRetry(fn, retries = 3, delayMs = 1000, label = "") {
14171
+ for(let attempt = 1; attempt <= retries; attempt++)try {
14172
+ return await fn();
14173
+ } catch (err) {
14174
+ if (attempt === retries) throw err;
14175
+ const waitTime = delayMs * attempt;
14176
+ console.warn(`${label} 第 ${attempt} 次失败,${waitTime}ms 后重试:`, err?.message ?? err);
14177
+ await this.delay(waitTime);
14178
+ }
14179
+ throw new Error("unreachable");
14180
+ }
14163
14181
  destroy() {
14164
14182
  this.uploadAgent.destroy();
14165
14183
  }
@@ -14356,14 +14374,16 @@ const mock_mockAction = async (task, params)=>{
14356
14374
  const uploader = new DouyinImageUploader(proxyHttp, headers, publishParams, tmpCachePath);
14357
14375
  if (params.coverImage) {
14358
14376
  const cover = await uploader.uploadCover(params.coverImage);
14359
- publishData.item.common.images.push({
14360
- uri: cover.uri,
14361
- width: cover.width,
14362
- height: cover.height
14363
- });
14364
- publishData.item.cover = {
14365
- poster: cover.uri
14366
- };
14377
+ if (cover) {
14378
+ publishData.item.common.images.push({
14379
+ uri: cover.uri,
14380
+ width: cover.width,
14381
+ height: cover.height
14382
+ });
14383
+ publishData.item.cover = {
14384
+ poster: cover.uri
14385
+ };
14386
+ }
14367
14387
  }
14368
14388
  if (params.banners && params.banners.length > 0) {
14369
14389
  const banners = params.banners.filter((i)=>i !== params.coverImage);
@@ -14389,11 +14409,15 @@ const mock_mockAction = async (task, params)=>{
14389
14409
  }
14390
14410
  if (!response || !response.data) return;
14391
14411
  const responseData = response.data;
14392
- if (response && responseData?.status_code && 0 !== responseData.status_code) return {
14393
- code: responseData?.status_code,
14394
- message: responseData.status_msg || "文章发布异常,请稍后重试。",
14395
- data: responseData
14396
- };
14412
+ if (response && responseData?.status_code && 0 !== responseData.status_code) {
14413
+ const errorCode = 4 === responseData.status_code ? 500 : responseData.status_code;
14414
+ if (4 === responseData.status_code) task.logger.warn(`抖音服务器错误 status_code: 4,映射为 500 触发重试。原始响应: ${JSON.stringify(responseData)}`);
14415
+ return {
14416
+ code: errorCode,
14417
+ message: responseData.status_msg || "文章发布异常,请稍后重试。",
14418
+ data: responseData
14419
+ };
14420
+ }
14397
14421
  });
14398
14422
  task._timerRecord.PrePublish = Date.now();
14399
14423
  if (MockPublish) {
@@ -14476,7 +14500,9 @@ const mock_mockAction = async (task, params)=>{
14476
14500
  "x-tt-session-dtrait": sessionDtrait || ""
14477
14501
  }
14478
14502
  }, {
14479
- timeout: 60000
14503
+ timeout: 60000,
14504
+ retries: 3,
14505
+ retryDelay: 2000
14480
14506
  });
14481
14507
  reportLogger({
14482
14508
  token: params.huiwenToken || "",
@@ -14489,9 +14515,8 @@ const mock_mockAction = async (task, params)=>{
14489
14515
  platform: "douyin",
14490
14516
  publishParams: publishData
14491
14517
  });
14492
- console.log("publishResult", JSON.stringify(publishResult));
14493
- task.logger.warn("发布数据");
14494
- task.logger.warn(JSON.stringify(publishData));
14518
+ task.logger.warn("发布结果");
14519
+ task.logger.warn(JSON.stringify(publishResult));
14495
14520
  const isSuccess = 0 === publishResult.status_code;
14496
14521
  const message = `图文发布${isSuccess ? "成功" : `失败,原因:${publishResult.status_msg} ${decision?.verify_title} ${decision?.verify_desc}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
14497
14522
  const data = isSuccess ? publishResult.item_id || "" : "";
@@ -23179,423 +23204,1516 @@ const xiaohongshuLogin = async (task, params)=>{
23179
23204
  if ("server" === params.actionType) return xiaohongshuLogin_rpa_server_rpaServer(task, params);
23180
23205
  return executeAction(xiaohongshuLogin_rpa_rpaAction)(task, params);
23181
23206
  };
23182
- const FictionalRendition = schemas_object({
23183
- type: literal("fictional-rendition")
23184
- });
23185
- const AIGenerated = schemas_object({
23186
- type: literal("ai-generated")
23187
- });
23188
- const SourceStatement = schemas_object({
23189
- type: literal("source-statement"),
23190
- childType: schemas_enum([
23191
- "self-labeling",
23192
- "self-shooting",
23193
- "transshipment"
23194
- ]),
23195
- shootingLocation: custom().optional(),
23196
- shootingDate: schemas_string().optional(),
23197
- sourceMedia: schemas_string().optional()
23198
- });
23199
- union([
23200
- FictionalRendition,
23201
- AIGenerated,
23202
- SourceStatement
23203
- ]);
23204
- const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
23205
- banners: schemas_array(schemas_string()),
23206
- title: schemas_string(),
23207
- content: schemas_string(),
23208
- address: custom().optional(),
23209
- selfDeclaration: custom().optional(),
23210
- topic: schemas_array(custom()).optional(),
23211
- proxyLoc: schemas_string().optional(),
23212
- localIP: schemas_string().optional(),
23213
- huiwenToken: schemas_string().optional(),
23214
- visibleRange: schemas_enum([
23215
- "public",
23216
- "private",
23217
- "friends"
23218
- ]),
23219
- isImmediatelyPublish: schemas_boolean().optional(),
23220
- scheduledPublish: schemas_string().optional(),
23221
- collectionId: schemas_string().optional(),
23222
- collectionBind: custom().optional(),
23223
- groupBind: custom().optional(),
23224
- noteCopyBind: schemas_boolean().optional(),
23225
- coProduceBind: schemas_boolean().optional(),
23226
- originalBind: schemas_boolean().optional()
23227
- });
23228
- const xiaohongshuPublish = async (_task, _params)=>({
23207
+ let _windowCache = null;
23208
+ const getWindow = ()=>{
23209
+ if (_windowCache) return _windowCache;
23210
+ _windowCache = "undefined" != typeof window ? window : globalThis;
23211
+ return _windowCache;
23212
+ };
23213
+ if ("undefined" != typeof process) {
23214
+ process.on("uncaughtException", ()=>{});
23215
+ process.on("unhandledRejection", ()=>{});
23216
+ }
23217
+ const mnsv2_enc = (arg1, arg2, cookieString)=>{
23218
+ const win = getWindow();
23219
+ win.ck = cookieString;
23220
+ __webpack_require__("./src/utils/xhs_ob_feed/ob.env.js");
23221
+ try {
23222
+ __webpack_require__("./src/utils/xhs_ob_feed/ob.enc.js");
23223
+ } catch {}
23224
+ let result = "";
23225
+ try {
23226
+ result = win.mnsv2(arg1, arg2);
23227
+ } catch {}
23228
+ return result;
23229
+ };
23230
+ const mnsvc2 = mnsv2_enc;
23231
+ const xhs_ob_feed_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob_feed/x_s.encoder.js");
23232
+ class xhs_ob_feed_Xhshow {
23233
+ stringifyCookies(cookies) {
23234
+ return Object.entries(cookies).map(([key, value])=>`${key}=${value}`).join("; ");
23235
+ }
23236
+ signHeadersGet(uri, cookieString, xsecAppid = "ugc", params) {
23237
+ let para1 = "";
23238
+ if (params && 0 !== Object.keys(params).length) {
23239
+ const _queryPara = Object.entries(params).map(([key, value])=>{
23240
+ let valueStr = "";
23241
+ if (Array.isArray(value)) valueStr = value.map((v)=>String(v)).join(",");
23242
+ else if (null != value) valueStr = String(value);
23243
+ return `${key}=${valueStr}`;
23244
+ });
23245
+ para1 = `${uri}?${_queryPara.join("&")}`;
23246
+ } else para1 = uri;
23247
+ const md5Para1 = __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(para1).digest("hex");
23248
+ const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23249
+ return {
23250
+ "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23251
+ };
23252
+ }
23253
+ signHeadersPost(uri, cookieString, xsecAppid = "ugc", payload) {
23254
+ const para1 = uri + JSON.stringify(payload || {});
23255
+ const md5Para1 = __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(para1).digest("hex");
23256
+ const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23257
+ return {
23258
+ "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23259
+ };
23260
+ }
23261
+ }
23262
+ const xiaohongshuPublish_mock_errnoMap = {
23263
+ "-1": "未知拦截器错误,请稍后重试。",
23264
+ 915: "所属C端账号手机号被修改,请重新登录",
23265
+ 914: "所属C端账号密码被修改,请重新登录",
23266
+ 903: "账户已登出,需重新登陆重试!",
23267
+ 902: "登录已过期,请重新登录!",
23268
+ 906: "账号存在风险,请重新登录!",
23269
+ "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
23270
+ };
23271
+ const mock_xsEncrypt = new xhs_ob_feed_Xhshow();
23272
+ const xiaohongshuPublish_mock_mockAction = async (task, params)=>{
23273
+ const tmpCachePath = task.getTmpPath();
23274
+ if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
23229
23275
  code: 414,
23230
- data: "",
23231
- message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
23232
- });
23233
- const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
23234
- const xiaohongshuWebCommentAction = async (_task, params)=>{
23235
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "点赞相关操作失败", {});
23276
+ message: "原创声明与转载声明互斥,请重新选择后发布!",
23277
+ data: ""
23278
+ };
23279
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23280
+ if (!a1Cookie) return {
23281
+ code: 414,
23282
+ message: "账号数据异常,请重新绑定账号后重试。",
23283
+ data: ""
23284
+ };
23236
23285
  const headers = {
23237
23286
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23238
- referer: "https://www.xiaohongshu.com/",
23239
- origin: "https://www.xiaohongshu.com/"
23287
+ origin: "https://creator.xiaohongshu.com",
23288
+ referer: "https://creator.xiaohongshu.com/",
23289
+ "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"
23240
23290
  };
23291
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
23292
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23293
+ return acc;
23294
+ }, {});
23241
23295
  const args = [
23242
23296
  {
23243
23297
  headers
23244
23298
  },
23245
- _task.logger,
23299
+ task.logger,
23246
23300
  params.proxyLoc,
23247
23301
  params.localIP,
23248
23302
  params.accountId
23249
23303
  ];
23250
- const http = new Http(...args);
23251
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23252
- if (!a1Cookie) return {
23253
- code: 414,
23254
- message: "账号数据异常,请重新绑定账号后重试。",
23255
- data: []
23256
- };
23257
- if (!params.note_id && !params.comment_id && !params.action) return {
23258
- code: 414,
23259
- message: "参数缺失,请检查后重试!",
23260
- data: {}
23261
- };
23262
- const actionParams = {
23263
- note_id: params.note_id,
23264
- comment_id: params.comment_id
23265
- };
23266
- let likeActionRes = {
23267
- code: 500,
23268
- success: false,
23269
- msg: ""
23304
+ const http = new Http({
23305
+ headers
23306
+ });
23307
+ const proxyHttp = new Http(...args);
23308
+ proxyHttp.addResponseInterceptor((response)=>{
23309
+ const responseData = response.data;
23310
+ if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
23311
+ const errmsg = xiaohongshuPublish_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
23312
+ return {
23313
+ code: xiaohongshuPublish_mock_errnoMap[responseData.code] ? 414 : 500,
23314
+ message: errmsg,
23315
+ data: responseData
23316
+ };
23317
+ }
23318
+ });
23319
+ const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
23320
+ const fetchCoverParams = {
23321
+ biz_name: "spectrum",
23322
+ scene: "image",
23323
+ file_count: params.banners.length,
23324
+ version: 1,
23325
+ source: "web"
23270
23326
  };
23271
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23272
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23273
- return acc;
23274
- }, {});
23275
- switch(params.action){
23276
- case "like":
23277
- {
23278
- const likeAction = "/api/sns/web/v1/comment/like";
23279
- const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
23280
- likeActionRes = await http.api({
23281
- method: "post",
23282
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
23283
- data: actionParams,
23284
- headers: likeActionXsHeader
23285
- }, {
23286
- retries: 3,
23287
- retryDelay: 20,
23288
- timeout: 3000
23289
- });
23290
- break;
23291
- }
23292
- case "dislike":
23293
- {
23294
- const dislikeMentions = "/api/sns/web/v1/comment/dislike";
23295
- const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
23296
- likeActionRes = await http.api({
23297
- method: "post",
23298
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
23299
- data: actionParams,
23300
- headers: dislikeXsHeader
23301
- }, {
23302
- retries: 3,
23303
- retryDelay: 20,
23304
- timeout: 3000
23327
+ const fetchCoverXsHeader = mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
23328
+ const uploadInfos = [];
23329
+ if (params.banners.length > 18) {
23330
+ const num = Math.ceil(params.banners.length / 14);
23331
+ for(let i = 0; i < num; i++){
23332
+ const start = 14 * i;
23333
+ params.banners.length;
23334
+ ({
23335
+ ...fetchCoverParams
23336
+ });
23337
+ const batchCoverIdInfo = await proxyHttp.api({
23338
+ method: "get",
23339
+ baseURL: "https://creator.xiaohongshu.com",
23340
+ url: fetchCoverUrl,
23341
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23342
+ headers: fetchCoverXsHeader,
23343
+ params: fetchCoverParams
23344
+ }, {
23345
+ retries: 3,
23346
+ retryDelay: 20,
23347
+ timeout: 3000
23348
+ });
23349
+ for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
23350
+ bucket: item.bucket || "",
23351
+ uploadAddr: item.uploadAddr || "",
23352
+ fileIds: fileId,
23353
+ token: item.token || ""
23354
+ });
23355
+ }
23356
+ } else {
23357
+ const coverIdInfo = await proxyHttp.api({
23358
+ method: "get",
23359
+ baseURL: "https://creator.xiaohongshu.com",
23360
+ url: fetchCoverUrl,
23361
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23362
+ headers: fetchCoverXsHeader,
23363
+ params: fetchCoverParams
23364
+ }, {
23365
+ retries: 3,
23366
+ retryDelay: 20,
23367
+ timeout: 3000
23368
+ });
23369
+ for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
23370
+ bucket: item.bucket || "",
23371
+ uploadAddr: item.uploadAddr || "",
23372
+ fileIds: fileId,
23373
+ token: item.token || ""
23374
+ });
23375
+ }
23376
+ if (uploadInfos.length < params.banners.length) return {
23377
+ code: 414,
23378
+ message: "可用 OSS bucket 数量不足,无法上传所有图片!",
23379
+ data: ""
23380
+ };
23381
+ if (0 === uploadInfos.length) return {
23382
+ code: 414,
23383
+ message: "图片上传失败,请稍后重试!",
23384
+ data: ""
23385
+ };
23386
+ const availableBuckets = Array.from({
23387
+ length: uploadInfos.length
23388
+ }, (_, i)=>i);
23389
+ const uploadFile = async (url, index)=>{
23390
+ const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
23391
+ const localUrl = await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
23392
+ const fileBuffer = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(localUrl);
23393
+ const MAX_RETRIES = uploadInfos.length;
23394
+ let attempt = 0;
23395
+ while(attempt < MAX_RETRIES){
23396
+ const ossBucketIndex = availableBuckets.shift();
23397
+ if (void 0 === ossBucketIndex) break;
23398
+ const currentInfo = uploadInfos[ossBucketIndex];
23399
+ const ossFileId = currentInfo.fileIds;
23400
+ const ossToken = currentInfo.token;
23401
+ const ossDomain = currentInfo.uploadAddr;
23402
+ try {
23403
+ await http.api({
23404
+ method: "put",
23405
+ url: `https://${ossDomain}/${ossFileId}`,
23406
+ data: fileBuffer,
23407
+ headers: {
23408
+ "x-cos-security-token": ossToken
23409
+ },
23410
+ defaultErrorMsg: "图片上传异常,请稍后重试发布。"
23305
23411
  });
23306
- break;
23412
+ return {
23413
+ ossFileId,
23414
+ ossToken
23415
+ };
23416
+ } catch (error) {
23417
+ attempt++;
23307
23418
  }
23308
- default:
23309
- return {
23310
- code: 414,
23311
- message: "参数action错误,请重试!",
23312
- data: {}
23419
+ }
23420
+ return {
23421
+ ossFileId: "",
23422
+ ossToken: ""
23423
+ };
23424
+ };
23425
+ const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
23426
+ const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
23427
+ if (invalidUpload) return {
23428
+ code: 414,
23429
+ message: "图片上传异常,请稍后重试发布。",
23430
+ data: ""
23431
+ };
23432
+ if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
23433
+ if (!topic.id) {
23434
+ const topicData = {
23435
+ topic_names: topic.name
23313
23436
  };
23314
- }
23315
- const isSuccess = 0 === likeActionRes.code;
23316
- const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23317
- const data = isSuccess ? likeActionRes.success : {};
23318
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
23319
- };
23320
- const xiaohongshuWebIntimacySearch = async (_task, params)=>{
23321
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(0, "搜索@列表数据成功", []);
23322
- const headers = {
23323
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23324
- referer: "https://www.xiaohongshu.com/",
23325
- origin: "https://www.xiaohongshu.com"
23437
+ const topicXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
23438
+ const createTopic = await proxyHttp.api({
23439
+ method: "POST",
23440
+ url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
23441
+ headers: topicXsHeader,
23442
+ data: topicData,
23443
+ defaultErrorMsg: "话题创建异常,请稍后重试。"
23444
+ }, {
23445
+ retries: 3,
23446
+ retryDelay: 20,
23447
+ timeout: 3000
23448
+ });
23449
+ if (!createTopic?.data) throw types_errorResponse("话题创建失败,请检查话题字段!", 414);
23450
+ Object.assign(topic, createTopic?.data?.topic_infos[0]);
23451
+ }
23452
+ }));
23453
+ const visibleRangeMap = {
23454
+ public: 0,
23455
+ private: 1,
23456
+ friends: 4
23326
23457
  };
23327
- const args = [
23328
- {
23329
- headers
23458
+ const publishData = {
23459
+ common: {
23460
+ ats: [],
23461
+ biz_relations: [],
23462
+ desc: params?.content,
23463
+ goods_info: {},
23464
+ hash_tag: params.topic || [],
23465
+ note_id: "",
23466
+ source: JSON.stringify({
23467
+ type: "web",
23468
+ ids: "",
23469
+ extraInfo: '{"systemId":"web"}'
23470
+ }),
23471
+ title: params?.title,
23472
+ type: "normal",
23473
+ privacy_info: {
23474
+ op_type: 1,
23475
+ type: visibleRangeMap[params.visibleRange]
23476
+ },
23477
+ post_loc: params.address ? {
23478
+ name: params.address?.name,
23479
+ poi_id: params.address?.poi_id,
23480
+ poi_type: params.address?.poi_type,
23481
+ subname: params.address?.full_address
23482
+ } : null,
23483
+ business_binds: ""
23330
23484
  },
23331
- _task.logger,
23332
- params.proxyLoc,
23333
- params.localIP,
23334
- params.accountId
23335
- ];
23336
- const http = new Http(...args);
23337
- let intimacyDetail = [];
23338
- const res = await http.api({
23485
+ image_info: {
23486
+ images: coverInfos.map((it)=>({
23487
+ extra_info_json: '{"mimeType":"image/png"}',
23488
+ file_id: it.ossFileId,
23489
+ metadata: {
23490
+ source: -1
23491
+ },
23492
+ stickers: {
23493
+ floating: [],
23494
+ version: 2
23495
+ }
23496
+ }))
23497
+ },
23498
+ video_info: null
23499
+ };
23500
+ const userDeclarationBind = {
23501
+ origin: 2,
23502
+ photoInfo: {},
23503
+ repostInfo: {}
23504
+ };
23505
+ if (params.selfDeclaration?.type === "fictional-rendition") userDeclarationBind.origin = 1;
23506
+ else if (params.selfDeclaration?.type === "ai-generated") userDeclarationBind.origin = 2;
23507
+ else if (params.selfDeclaration?.type === "source-statement") {
23508
+ if ("self-labeling" === params.selfDeclaration.childType) userDeclarationBind.origin = 3;
23509
+ else if ("self-shooting" === params.selfDeclaration.childType) {
23510
+ userDeclarationBind.origin = 4;
23511
+ const photoInfo = {};
23512
+ if (params.selfDeclaration.shootingLocation) photoInfo.photoPlace = {
23513
+ name: params.selfDeclaration.shootingLocation.name,
23514
+ poiId: params.selfDeclaration.shootingLocation.poi_id,
23515
+ poiType: params.selfDeclaration.shootingLocation.poi_type,
23516
+ subname: params.selfDeclaration.shootingLocation.full_address
23517
+ };
23518
+ if (params.selfDeclaration.shootingDate) photoInfo.photoTime = params.selfDeclaration.shootingDate;
23519
+ userDeclarationBind.photoInfo = photoInfo;
23520
+ } else if ("transshipment" === params.selfDeclaration.childType) {
23521
+ userDeclarationBind.origin = 5;
23522
+ if (params.selfDeclaration.sourceMedia) userDeclarationBind.repostInfo = {
23523
+ source: params.selfDeclaration.sourceMedia
23524
+ };
23525
+ }
23526
+ }
23527
+ const bizId = params?.originalBind && (params.cookies.find((it)=>"x-user-id-creator.xiaohongshu.com" === it.name)?.value || await proxyHttp.api({
23339
23528
  method: "get",
23340
- url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
23341
- ...params.searchValue ? {
23342
- params: {
23343
- keyword: params.searchValue,
23344
- page: 1,
23345
- rows: 30
23346
- }
23347
- } : {}
23529
+ url: "https://creator.xiaohongshu.com/api/galaxy/user/my-info"
23348
23530
  }, {
23349
23531
  retries: 3,
23350
23532
  retryDelay: 20,
23351
23533
  timeout: 3000
23352
- });
23353
- const isSuccess = 0 === res.code;
23354
- if (isSuccess) intimacyDetail = res.data.items;
23355
- const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23356
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, intimacyDetail);
23357
- };
23358
- const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
23359
- const xiaohongshuWebMsgRead = async (_task, params)=>{
23360
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "Read指定Tab失败", {});
23361
- const headers = {
23362
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23363
- referer: "https://www.xiaohongshu.com/",
23364
- origin: "https://www.xiaohongshu.com/"
23365
- };
23366
- const args = [
23367
- {
23368
- headers
23534
+ }).then((userData)=>userData.data?.userDetail?.id));
23535
+ const business_binds = {
23536
+ version: 1,
23537
+ bizType: "",
23538
+ noteId: "",
23539
+ noteOrderBind: {},
23540
+ notePostTiming: params.isImmediatelyPublish ? {} : {
23541
+ postTime: params.scheduledPublish
23369
23542
  },
23370
- _task.logger,
23371
- params.proxyLoc,
23372
- params.localIP,
23373
- params.accountId
23374
- ];
23375
- const http = new Http(...args);
23376
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23377
- if (!a1Cookie) return {
23378
- code: 414,
23379
- message: "账号数据异常,请重新绑定账号后重试。",
23380
- data: []
23381
- };
23382
- if (!params.type) return {
23383
- code: 414,
23384
- message: "参数缺失,请检查后重试!",
23385
- data: {}
23386
- };
23387
- const replyParams = {
23388
- type: params.type
23543
+ coProduceBind: {
23544
+ enable: !!params?.coProduceBind
23545
+ },
23546
+ noteCopyBind: {
23547
+ copyable: !!params?.noteCopyBind
23548
+ },
23549
+ optionRelationList: params.originalBind ? [
23550
+ {
23551
+ type: "ORIGINAL_STATEMENT",
23552
+ relationList: [
23553
+ {
23554
+ bizId,
23555
+ bizType: "ORIGINAL_STATEMENT",
23556
+ extraInfo: "{}"
23557
+ }
23558
+ ]
23559
+ }
23560
+ ] : [],
23561
+ ...params?.groupBind ? {
23562
+ groupBind: {
23563
+ groupId: params?.groupBind?.group_id,
23564
+ groupName: params.groupBind?.group_name,
23565
+ desc: params.groupBind?.desc,
23566
+ avatar: params.groupBind?.avatar
23567
+ }
23568
+ } : {
23569
+ groupBind: {}
23570
+ },
23571
+ ...params.selfDeclaration ? {
23572
+ userDeclarationBind
23573
+ } : {},
23574
+ ...params?.collectionBind?.id ? {
23575
+ noteCollectionBind: {
23576
+ id: params.collectionBind.id
23577
+ }
23578
+ } : {}
23389
23579
  };
23390
- const fatchMentions = "/api/sns/web/v1/message/read";
23391
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23392
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23393
- return acc;
23394
- }, {});
23395
- const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
23396
- const res = await http.api({
23580
+ publishData.common.business_binds = JSON.stringify(business_binds);
23581
+ const publishXsHeader = mock_xsEncrypt.signHeadersPost("/web_api/sns/v2/note", recordCookie, "ugc", publishData);
23582
+ task._timerRecord.PrePublish = Date.now();
23583
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23584
+ if (MockPublish) {
23585
+ const message = `文章模拟发布成功 ${http.proxyInfo}`;
23586
+ const data = "123456789";
23587
+ await updateTaskState?.({
23588
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
23589
+ result: {
23590
+ response: data
23591
+ }
23592
+ });
23593
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
23594
+ }
23595
+ const publishResult = await proxyHttp.api({
23397
23596
  method: "post",
23398
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
23399
- data: replyParams,
23400
- headers: fatchMentionsXsHeader
23597
+ url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
23598
+ data: publishData,
23599
+ headers: publishXsHeader,
23600
+ defaultErrorMsg: "文章发布异常,请稍后重试。"
23401
23601
  }, {
23402
- retries: 3,
23403
- retryDelay: 20,
23404
- timeout: 3000
23602
+ retries: 2,
23603
+ retryDelay: 500,
23604
+ timeout: 12000
23605
+ });
23606
+ reportLogger({
23607
+ token: params.huiwenToken || "",
23608
+ enverionment: task.enverionment || "development",
23609
+ postId: params.articleId,
23610
+ eip: proxyHttp.proxyInfo,
23611
+ proxyIp: params.localIP,
23612
+ accountId: params.accountId,
23613
+ uid: params.uid,
23614
+ platform: "xiaohongshu",
23615
+ publishParams: publishData
23616
+ });
23617
+ const isSuccess = publishResult.success;
23618
+ const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
23619
+ const data = isSuccess ? publishResult.data?.id || "" : "";
23620
+ if (!isSuccess) {
23621
+ await updateTaskState?.({
23622
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.FAILED,
23623
+ error: message
23624
+ });
23625
+ return {
23626
+ code: 414,
23627
+ data,
23628
+ message
23629
+ };
23630
+ }
23631
+ await updateTaskState?.({
23632
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
23633
+ result: {
23634
+ response: data
23635
+ }
23405
23636
  });
23406
- const isSuccess = 0 === res.code;
23407
- const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23408
- const data = isSuccess ? res.success : {};
23409
23637
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
23410
23638
  };
23411
- const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
23412
- const xiaohongshuWebMsgReply = async (_task, params)=>{
23413
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "评论回复失败", {});
23414
- const headers = {
23415
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23416
- referer: "https://www.xiaohongshu.com/",
23417
- origin: "https://www.xiaohongshu.com/"
23639
+ const xiaohongshuPublish_rpa_rpaAction = async (task, params)=>{
23640
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23641
+ const commonCookies = {
23642
+ path: "/",
23643
+ sameSite: "lax",
23644
+ secure: false,
23645
+ domain: ".xiaohongshu.com",
23646
+ url: "https://creator.xiaohongshu.com",
23647
+ httpOnly: true
23418
23648
  };
23419
- const args = [
23420
- {
23421
- headers
23422
- },
23423
- _task.logger,
23424
- params.proxyLoc,
23425
- params.localIP,
23426
- params.accountId
23427
- ];
23428
- const http = new Http(...args);
23429
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23430
- if (!a1Cookie) return {
23431
- code: 414,
23432
- message: "账号数据异常,请重新绑定账号后重试。",
23433
- data: []
23649
+ const page = await task.createPage({
23650
+ show: task.debug,
23651
+ url: params.url || "https://creator.xiaohongshu.com/publish/publish",
23652
+ cookies: params.cookies?.map((it)=>({
23653
+ ...it,
23654
+ ...commonCookies
23655
+ }))
23656
+ });
23657
+ await updateTaskState?.({
23658
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.ACTION,
23659
+ connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
23660
+ sessionId: task.sessionId
23661
+ });
23662
+ const tmpCachePath = task.getTmpPath();
23663
+ const selectAddress = async (selector, address)=>{
23664
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23665
+ await instance.click();
23666
+ await instance.locator("input").fill(address);
23667
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
23668
+ await poperInstance.first().waitFor();
23669
+ await poperInstance.first().click();
23434
23670
  };
23435
- if (!params.note_id || !params.target_comment_id || !params.content) return {
23436
- code: 414,
23437
- message: "参数缺失,请检查后重试!",
23438
- data: {}
23671
+ const selectDate = async (selector, date)=>{
23672
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23673
+ await instance.click();
23674
+ await instance.fill(date);
23675
+ await instance.blur();
23439
23676
  };
23440
- const replyParams = {
23441
- at_users: params.at_users ?? [],
23442
- content: params.content,
23443
- note_id: params.note_id,
23444
- target_comment_id: params.target_comment_id
23677
+ const getPoperInstance = async ()=>{
23678
+ await page.waitForTimeout(500);
23679
+ const elements = page.locator(".d-popover");
23680
+ const count = await elements.count();
23681
+ const visibleElements = [];
23682
+ for(let i = 0; i < count; i++){
23683
+ const element = elements.nth(i);
23684
+ const style = await element.getAttribute("style");
23685
+ if (style && !style.includes("display: none")) visibleElements.push(element);
23686
+ }
23687
+ if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
23688
+ throw new Error("未找到 popover 弹窗");
23689
+ };
23690
+ const getDialogInstance = async ()=>{
23691
+ await page.waitForTimeout(1000);
23692
+ const elements = page.locator(".el-dialog");
23693
+ return elements.last();
23445
23694
  };
23446
- const replyPath = "/api/sns/web/v1/comment/post";
23447
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23448
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23449
- return acc;
23450
- }, {});
23451
- const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
23452
- const res = await http.api({
23453
- method: "post",
23454
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
23455
- data: replyParams,
23456
- headers: replyXsHeader
23457
- }, {
23458
- retries: 3,
23459
- retryDelay: 20,
23460
- timeout: 3000
23461
- });
23462
- const isSuccess = 0 === res.code;
23463
- const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23464
- const data = isSuccess ? res.data : {};
23465
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
23466
- };
23467
- let _windowCache = null;
23468
- const getWindow = ()=>{
23469
- if (_windowCache) return _windowCache;
23470
- _windowCache = "undefined" != typeof window ? window : globalThis;
23471
- return _windowCache;
23472
- };
23473
- if ("undefined" != typeof process) {
23474
- process.on("uncaughtException", ()=>{});
23475
- process.on("unhandledRejection", ()=>{});
23476
- }
23477
- const mnsv2_enc = (arg1, arg2, cookieString)=>{
23478
- const win = getWindow();
23479
- win.ck = cookieString;
23480
- __webpack_require__("./src/utils/xhs_ob_feed/ob.env.js");
23481
- try {
23482
- __webpack_require__("./src/utils/xhs_ob_feed/ob.enc.js");
23483
- } catch {}
23484
- let result = "";
23485
23695
  try {
23486
- result = win.mnsv2(arg1, arg2);
23487
- } catch {}
23488
- return result;
23489
- };
23490
- const mnsvc2 = mnsv2_enc;
23491
- const xhs_ob_feed_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob_feed/x_s.encoder.js");
23492
- class xhs_ob_feed_Xhshow {
23493
- stringifyCookies(cookies) {
23494
- return Object.entries(cookies).map(([key, value])=>`${key}=${value}`).join("; ");
23495
- }
23496
- signHeadersGet(uri, cookieString, xsecAppid = "ugc", params) {
23497
- let para1 = "";
23498
- if (params && 0 !== Object.keys(params).length) {
23499
- const _queryPara = Object.entries(params).map(([key, value])=>{
23500
- let valueStr = "";
23501
- if (Array.isArray(value)) valueStr = value.map((v)=>String(v)).join(",");
23502
- else if (null != value) valueStr = String(value);
23503
- return `${key}=${valueStr}`;
23504
- });
23505
- para1 = `${uri}?${_queryPara.join("&")}`;
23506
- } else para1 = uri;
23507
- const md5Para1 = __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(para1).digest("hex");
23508
- const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23696
+ await page.waitForSelector("#CreatorPlatform", {
23697
+ state: "visible"
23698
+ });
23699
+ } catch (error) {
23509
23700
  return {
23510
- "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23701
+ code: 414,
23702
+ message: "登录失效",
23703
+ data: page.url()
23511
23704
  };
23512
23705
  }
23513
- signHeadersPost(uri, cookieString, xsecAppid = "ugc", payload) {
23514
- const para1 = uri + JSON.stringify(payload || {});
23515
- const md5Para1 = __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(para1).digest("hex");
23516
- const mnsvc2_data = mnsvc2(para1, md5Para1, this.stringifyCookies(cookieString));
23706
+ await page.locator("#content-area .menu-container .publish-video .btn-wrapper .btn-inner").click();
23707
+ await page.locator('.header-tabs .creator-tab:not([style*="-9999px"])').filter({
23708
+ hasText: /^上传图文$/
23709
+ }).click();
23710
+ const images = await Promise.all(params.banners.map((url)=>{
23711
+ const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
23712
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
23713
+ }));
23714
+ const fileChooser = await page.$("input.upload-input");
23715
+ if (fileChooser) await fileChooser.setInputFiles(images);
23716
+ const titleInstance = page.locator(".input input");
23717
+ await titleInstance.waitFor({
23718
+ state: "visible",
23719
+ timeout: 50000
23720
+ });
23721
+ await titleInstance.click();
23722
+ await titleInstance.fill(params.title);
23723
+ const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
23724
+ await descInstance.click();
23725
+ await descInstance.pressSequentially(params.content.replace(/#.*?\[.*?]#/g, ""));
23726
+ if (params.topic && params.topic.length > 0) for (const it of params.topic){
23727
+ await descInstance.pressSequentially(`#${it.name}`);
23728
+ await page.locator("#creator-editor-topic-container").waitFor({
23729
+ state: "visible"
23730
+ });
23731
+ await page.waitForTimeout(500);
23732
+ await page.locator("#creator-editor-topic-container .item").first().click();
23733
+ }
23734
+ if (params.address) await selectAddress(page.locator(".address-card-wrapper .d-select-wrapper"), params.address.name);
23735
+ if (params.selfDeclaration) {
23736
+ await page.locator(".declaration-wrapper .d-select-wrapper").click();
23737
+ const poperInstance = await getPoperInstance();
23738
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
23739
+ if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
23740
+ hasText: "虚构演绎,仅供娱乐"
23741
+ }).click();
23742
+ else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
23743
+ hasText: "笔记含AI合成内容"
23744
+ }).click();
23745
+ else if ("source-statement" === params.selfDeclaration.type) {
23746
+ await selfDeclarationInstance.filter({
23747
+ hasText: /内容来源声明/
23748
+ }).click();
23749
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
23750
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
23751
+ if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
23752
+ hasText: "已在正文中自主标注"
23753
+ }).click();
23754
+ else if ("self-shooting" === params.selfDeclaration.childType) {
23755
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
23756
+ await selfDeclarationSecondaryMenuInstance.filter({
23757
+ hasText: "自主拍摄"
23758
+ }).click();
23759
+ const selfShootingPopup = await getDialogInstance();
23760
+ const hasCustomContent = shootingDate || shootingLocation;
23761
+ if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
23762
+ if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
23763
+ await selfShootingPopup.locator("footer button").filter({
23764
+ hasText: hasCustomContent ? "确认" : "取消"
23765
+ }).click();
23766
+ } else if ("transshipment" === params.selfDeclaration.childType) {
23767
+ await selfDeclarationSecondaryMenuInstance.filter({
23768
+ hasText: "来源转载"
23769
+ }).click();
23770
+ const selfShootingPopup = await getDialogInstance();
23771
+ const sourceMedia = params.selfDeclaration.sourceMedia;
23772
+ if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
23773
+ await selfShootingPopup.locator("footer button").filter({
23774
+ hasText: sourceMedia ? "确认" : "取消"
23775
+ }).click();
23776
+ }
23777
+ }
23778
+ }
23779
+ if ("private" === params.visibleRange) {
23780
+ await page.locator(".publish-page-content-setting-content .d-select-wrapper").last().click();
23781
+ const poperInstance = await getPoperInstance();
23782
+ await poperInstance.locator(".d-options .d-option").filter({
23783
+ hasText: "仅自己可见"
23784
+ }).click();
23785
+ }
23786
+ task._timerRecord.PrePublish = Date.now();
23787
+ const releaseTimeInstance = page.locator("label").filter({
23788
+ hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
23789
+ });
23790
+ await releaseTimeInstance.click();
23791
+ if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
23792
+ await page.waitForFunction(()=>{
23793
+ const publishBtn = Array.from(document.querySelectorAll("button")).find((b)=>b.textContent?.trim() === "发布");
23794
+ const uploading = document.querySelector(".progress-container");
23795
+ return !!publishBtn && !uploading;
23796
+ }, {
23797
+ timeout: 180000,
23798
+ polling: 2000
23799
+ });
23800
+ const response = await new Promise((resolve, reject)=>{
23801
+ const handleResponse = async (response)=>{
23802
+ if (response.url().includes("/web_api/sns/v2/note")) {
23803
+ const jsonResponse = await response.json();
23804
+ page.off("response", handleResponse);
23805
+ if (jsonResponse?.success) resolve(jsonResponse?.data?.id);
23806
+ else reject(new Error(jsonResponse?.msg || "发布失败"));
23807
+ }
23808
+ };
23809
+ page.on("response", handleResponse);
23810
+ page.locator(".publish-page-publish-btn button").filter({
23811
+ hasText: "发布"
23812
+ }).click();
23813
+ });
23814
+ await updateTaskState?.({
23815
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
23816
+ result: {
23817
+ response
23818
+ }
23819
+ });
23820
+ await page.close();
23821
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(response);
23822
+ };
23823
+ const xiaohongshuPublish_rpa_server_rpaAction_Server = async (task, params)=>{
23824
+ if (params.originalBind && params?.selfDeclaration?.type === "source-statement") return {
23825
+ code: 414,
23826
+ message: "已声明原创不可选择“来源转载”",
23827
+ data: ""
23828
+ };
23829
+ const defaultPage = task.steelBrowserContext?.pages()[0];
23830
+ if (defaultPage) {
23831
+ if (!defaultPage._routeRegistered) {
23832
+ defaultPage._routeRegistered = true;
23833
+ const blockedPatterns = [
23834
+ "**/ffmpeg-core.wasm*",
23835
+ "**/apm-fe.xiaohongshu.com*",
23836
+ "**/t2.xiaohongshu.com*",
23837
+ "**/fe-video-qc.xhscdn.com*"
23838
+ ].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
23839
+ await defaultPage.route("**/*", async (route)=>{
23840
+ const req = route.request();
23841
+ const url = req.url();
23842
+ const blocked = blockedPatterns.some((regex)=>regex.test(url));
23843
+ if (!blocked) return route.continue();
23844
+ if ("OPTIONS" === req.method()) {
23845
+ console.log("处理 OPTIONS 预检:", url);
23846
+ await route.fulfill({
23847
+ status: 204,
23848
+ headers: {
23849
+ "access-control-allow-origin": "*",
23850
+ "access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
23851
+ "access-control-allow-headers": "*"
23852
+ },
23853
+ body: ""
23854
+ });
23855
+ return;
23856
+ }
23857
+ await route.fulfill({
23858
+ status: 204,
23859
+ body: ""
23860
+ });
23861
+ });
23862
+ }
23863
+ }
23864
+ const tmpCachePath = task.getTmpPath();
23865
+ task.logger?.info("==>进入RPA操作:任务开始,下载图片开始...");
23866
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23867
+ const imagePromise = Promise.all(params.banners.map((url)=>{
23868
+ const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
23869
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
23870
+ }));
23871
+ let proxyUrl;
23872
+ if (params.localIP) {
23873
+ const args = [
23874
+ params.localIP,
23875
+ params.proxyLoc,
23876
+ params.accountId
23877
+ ];
23878
+ task.logger?.info(`==> 开始获取代理信息:${args}`);
23879
+ const ProxyAgentResult = await ProxyAgent({
23880
+ logger: task.logger
23881
+ }, ...args);
23882
+ task.logger?.info("==> 代理信息获取成功!");
23883
+ proxyUrl = ProxyAgentResult ? `http://${ProxyAgentResult.ip}:${ProxyAgentResult.port}` : void 0;
23884
+ }
23885
+ task.logger?.info("==>开始打开小红书页面...");
23886
+ const page = await task.createPage({
23887
+ show: task.debug,
23888
+ cookies: params.cookies,
23889
+ proxyUrl,
23890
+ url: params.url || "https://creator.xiaohongshu.com/publish/publish?source=official&from=menu&target=image",
23891
+ ...params.viewport ? {
23892
+ viewport: params.viewport
23893
+ } : {}
23894
+ });
23895
+ task.logger?.info("==>小红书页面打开成功");
23896
+ await updateTaskState?.({
23897
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.ACTION,
23898
+ connectAddress: task.steelConnector?.getProxyUrl(task.sessionId || "", "v1/sessions/debug"),
23899
+ sessionId: task.sessionId
23900
+ });
23901
+ const clickTimeout = 10000;
23902
+ const selectAddress = async (selector, address)=>{
23903
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23904
+ await instance.click({
23905
+ timeout: clickTimeout
23906
+ });
23907
+ await instance.locator("input").fill(address);
23908
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
23909
+ await poperInstance.first().waitFor();
23910
+ await poperInstance.first().click({
23911
+ timeout: clickTimeout
23912
+ });
23913
+ };
23914
+ const selectDate = async (selector, date)=>{
23915
+ const instance = "string" == typeof selector ? page.locator(selector) : selector;
23916
+ await instance.click({
23917
+ timeout: clickTimeout
23918
+ });
23919
+ await instance.fill(date);
23920
+ await instance.blur();
23921
+ };
23922
+ const getPoperInstance = async ()=>{
23923
+ await page.waitForTimeout(500);
23924
+ const elements = page.locator(".d-popover");
23925
+ const count = await elements.count();
23926
+ const visibleElements = [];
23927
+ for(let i = 0; i < count; i++){
23928
+ const element = elements.nth(i);
23929
+ const style = await element.getAttribute("style");
23930
+ if (style && !style.includes("display: none")) visibleElements.push(element);
23931
+ }
23932
+ if (visibleElements.length > 0) return visibleElements[visibleElements.length - 1];
23933
+ throw new Error("未找到 popover 弹窗");
23934
+ };
23935
+ const getDialogInstance = async ()=>{
23936
+ await page.waitForTimeout(1000);
23937
+ const elements = page.locator(".el-dialog");
23938
+ return elements.last();
23939
+ };
23940
+ try {
23941
+ await page.waitForSelector("#CreatorPlatform", {
23942
+ state: "attached"
23943
+ });
23944
+ } catch (error) {
23517
23945
  return {
23518
- "X-S": xhs_ob_feed_encode_mnsv2(mnsvc2_data, xsecAppid, "Windows", "object")
23946
+ code: 414,
23947
+ message: "登录失效",
23948
+ data: page.url()
23519
23949
  };
23520
23950
  }
23951
+ const images = await imagePromise;
23952
+ task.logger?.info(`==>图片下载完成,共 ${images.length} 张,开始上传图片...`);
23953
+ const fileChooser = await page.waitForSelector("input.upload-input", {
23954
+ timeout: 10000
23955
+ });
23956
+ if (fileChooser) await fileChooser.setInputFiles(images, {
23957
+ timeout: 60000
23958
+ }).catch((err)=>{
23959
+ task.logger?.error(`设置上传文件失败:${err.message}`);
23960
+ });
23961
+ else task.logger?.error("文件上传输入框未找到");
23962
+ task.logger?.info("==>图片上传完成,开始渲染预览图...");
23963
+ const titleInstance = page.locator(".input input");
23964
+ await titleInstance.waitFor({
23965
+ state: "attached",
23966
+ timeout: 60000
23967
+ });
23968
+ await titleInstance.click({
23969
+ timeout: 24 * clickTimeout
23970
+ });
23971
+ task.logger?.info("==> 预览图渲染成功,开始RPA操作!");
23972
+ await titleInstance.fill(params.title);
23973
+ const descInstance = page.locator(".editor-container .tiptap.ProseMirror");
23974
+ await descInstance.click({
23975
+ timeout: clickTimeout
23976
+ });
23977
+ await descInstance.fill(`${params.content.replace(/#.*?\[.*?]#/g, "")}\n`);
23978
+ await page.keyboard.press("Control+End");
23979
+ if (params.topic && params.topic.length > 0) for (const it of params.topic){
23980
+ await page.keyboard.insertText(`#${it.name}`);
23981
+ await page.locator(".ql-mention-loading").waitFor({
23982
+ state: "detached"
23983
+ });
23984
+ await page.waitForTimeout(1000);
23985
+ await page.locator("#creator-editor-topic-container .item.is-selected").click({
23986
+ timeout: clickTimeout
23987
+ });
23988
+ await page.keyboard.press("Control+End");
23989
+ }
23990
+ const container = page.locator(".plugin.editor-container");
23991
+ await container.focus();
23992
+ await page.mouse.wheel(0, 500);
23993
+ if (params.address) await selectAddress(page.locator(".media-extension .address-input").filter({
23994
+ hasText: "添加地点"
23995
+ }), params.address.name);
23996
+ if (params.collectionBind) {
23997
+ await page.locator(".media-extension .collection-container").filter({
23998
+ hasText: "添加合集"
23999
+ }).click({
24000
+ timeout: clickTimeout
24001
+ });
24002
+ const collectionName = params.collectionBind.name;
24003
+ const collectionBindInstance = await getPoperInstance();
24004
+ const collectionItemInstance = collectionBindInstance.locator(".d-grid-item .item-label", {
24005
+ hasText: collectionName
24006
+ });
24007
+ await collectionBindInstance.locator(".loading").waitFor({
24008
+ state: "detached"
24009
+ });
24010
+ await collectionItemInstance.click({
24011
+ timeout: clickTimeout
24012
+ });
24013
+ }
24014
+ if (params.groupBind) {
24015
+ await page.locator(".media-extension .address-input").filter({
24016
+ hasText: "选择群聊"
24017
+ }).click({
24018
+ timeout: clickTimeout
24019
+ });
24020
+ const groupBindName = params.groupBind.group_name;
24021
+ const groupBindInstance = await getPoperInstance();
24022
+ const groupItemInstance = groupBindInstance.locator(".d-grid-item .name", {
24023
+ hasText: groupBindName
24024
+ });
24025
+ await groupBindInstance.locator(".loading").waitFor({
24026
+ state: "detached"
24027
+ });
24028
+ await groupItemInstance.click({
24029
+ timeout: clickTimeout
24030
+ });
24031
+ }
24032
+ const OriginalBindBtn = page.locator(".btn-text.red", {
24033
+ hasText: "去声明"
24034
+ });
24035
+ const isOriginalBindBtnVisible = await OriginalBindBtn.isVisible();
24036
+ if (isOriginalBindBtnVisible && params.originalBind) {
24037
+ await OriginalBindBtn.click({
24038
+ timeout: clickTimeout
24039
+ });
24040
+ const poperInstance = await getPoperInstance();
24041
+ await poperInstance.locator(".d-checkbox-simulator").click({
24042
+ timeout: clickTimeout
24043
+ });
24044
+ await poperInstance.locator(".footer .custom-button.bg-red").click({
24045
+ timeout: clickTimeout
24046
+ });
24047
+ }
24048
+ if (params.selfDeclaration) {
24049
+ await page.locator(".media-settings .flexbox").filter({
24050
+ hasText: "内容类型声明"
24051
+ }).locator(".d-select-placeholder").click({
24052
+ timeout: clickTimeout
24053
+ });
24054
+ const poperInstance = await getPoperInstance();
24055
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
24056
+ if ("fictional-rendition" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
24057
+ hasText: "虚构演绎,仅供娱乐"
24058
+ }).click({
24059
+ timeout: clickTimeout
24060
+ });
24061
+ else if ("ai-generated" === params.selfDeclaration.type) await selfDeclarationInstance.filter({
24062
+ hasText: "笔记含AI合成内容"
24063
+ }).click({
24064
+ timeout: clickTimeout
24065
+ });
24066
+ else if ("source-statement" === params.selfDeclaration.type) {
24067
+ await selfDeclarationInstance.filter({
24068
+ hasText: /内容来源声明/
24069
+ }).click({
24070
+ timeout: clickTimeout
24071
+ });
24072
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
24073
+ await selfDeclarationSecondaryMenuInstance.first().waitFor();
24074
+ if ("self-labeling" === params.selfDeclaration.childType) await selfDeclarationSecondaryMenuInstance.filter({
24075
+ hasText: "已在正文中自主标注"
24076
+ }).click({
24077
+ timeout: clickTimeout
24078
+ });
24079
+ else if ("self-shooting" === params.selfDeclaration.childType) {
24080
+ const { shootingDate, shootingLocation } = params.selfDeclaration;
24081
+ await selfDeclarationSecondaryMenuInstance.filter({
24082
+ hasText: "自主拍摄"
24083
+ }).click({
24084
+ timeout: clickTimeout
24085
+ });
24086
+ const selfShootingPopup = await getDialogInstance();
24087
+ const hasCustomContent = shootingDate || shootingLocation;
24088
+ if (shootingLocation) await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation.name);
24089
+ if (shootingDate) await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
24090
+ await selfShootingPopup.locator("footer button").filter({
24091
+ hasText: hasCustomContent ? "确认" : "取消"
24092
+ }).click({
24093
+ timeout: clickTimeout
24094
+ });
24095
+ } else if ("transshipment" === params.selfDeclaration.childType) {
24096
+ await selfDeclarationSecondaryMenuInstance.filter({
24097
+ hasText: "来源转载"
24098
+ }).click({
24099
+ timeout: clickTimeout
24100
+ });
24101
+ const selfShootingPopup = await getDialogInstance();
24102
+ const sourceMedia = params.selfDeclaration.sourceMedia;
24103
+ if (sourceMedia) await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
24104
+ await selfShootingPopup.locator("footer button").filter({
24105
+ hasText: sourceMedia ? "确认" : "取消"
24106
+ }).click({
24107
+ timeout: clickTimeout
24108
+ });
24109
+ }
24110
+ }
24111
+ }
24112
+ if ("public" !== params.visibleRange) {
24113
+ await page.locator(".media-settings .flexbox").filter({
24114
+ hasText: "可见范围"
24115
+ }).locator(".d-select-wrapper").click({
24116
+ timeout: clickTimeout
24117
+ });
24118
+ const poperInstance = await getPoperInstance();
24119
+ const visibleText = "friends" === params.visibleRange ? "好友可见" : "仅自己可见";
24120
+ await poperInstance.locator(".d-options .custom-option").filter({
24121
+ hasText: visibleText
24122
+ }).click({
24123
+ timeout: clickTimeout
24124
+ });
24125
+ }
24126
+ async function setSwitch(page, label, target) {
24127
+ const item = page.locator(".d-new-form-item", {
24128
+ has: page.locator(".d-form-item__label", {
24129
+ hasText: label
24130
+ })
24131
+ });
24132
+ const switchUI = item.locator(".d-switch-simulator");
24133
+ const cls = await switchUI.getAttribute("class");
24134
+ const isChecked = cls?.includes("checked") || true;
24135
+ if (isChecked !== target) await switchUI.click({
24136
+ timeout: clickTimeout
24137
+ });
24138
+ }
24139
+ if (!params.coProduceBind) await setSwitch(page, "允许合拍", false);
24140
+ if (!params.noteCopyBind) await setSwitch(page, "允许正文复制", false);
24141
+ const releaseTimeInstance = page.locator("label").filter({
24142
+ hasText: params.isImmediatelyPublish ? "立即发布" : "定时发布"
24143
+ });
24144
+ await releaseTimeInstance.click({
24145
+ timeout: clickTimeout
24146
+ });
24147
+ if (params.scheduledPublish) await selectDate(".date-picker input", params.scheduledPublish);
24148
+ const imgPreviewArea = page.locator(".img-preview-area");
24149
+ try {
24150
+ await imgPreviewArea.locator(".mask.uploading").waitFor({
24151
+ state: "hidden",
24152
+ timeout: 50000
24153
+ });
24154
+ } catch (error) {
24155
+ throw new Error("上传图片超时,请重试!");
24156
+ }
24157
+ if (MockPublish) {
24158
+ const message = "文章模拟发布成功";
24159
+ const data = "123456789";
24160
+ await updateTaskState?.({
24161
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24162
+ result: {
24163
+ response: data
24164
+ }
24165
+ });
24166
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
24167
+ }
24168
+ const response = await new Promise((resolve)=>{
24169
+ const handleResponse = async (response)=>{
24170
+ if (response.url().includes("/web_api/sns/v2/note")) {
24171
+ const jsonResponse = await response.json();
24172
+ page.off("response", handleResponse);
24173
+ resolve(jsonResponse);
24174
+ }
24175
+ };
24176
+ page.on("response", handleResponse);
24177
+ page.locator(".submit .publishBtn").click({
24178
+ timeout: clickTimeout
24179
+ });
24180
+ page.waitForSelector(".d-toast-icon-danger", {
24181
+ state: "visible",
24182
+ timeout: 2000
24183
+ }).then(async ()=>{
24184
+ await page.waitForTimeout(300);
24185
+ const toastDesc = await page.locator(".d-toast-description").textContent();
24186
+ const desc = toastDesc?.trim();
24187
+ page.off("response", handleResponse);
24188
+ resolve({
24189
+ success: false,
24190
+ msg: desc || "未知错误"
24191
+ });
24192
+ }).catch(()=>{});
24193
+ setTimeout(()=>{
24194
+ page.off("response", handleResponse);
24195
+ resolve({
24196
+ success: false,
24197
+ msg: "发布超时"
24198
+ });
24199
+ }, 7000);
24200
+ });
24201
+ if (!response?.success) {
24202
+ const msg = `发布失败:${response?.msg || "未知错误"}`;
24203
+ await updateTaskState?.({
24204
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.FAILED,
24205
+ error: msg
24206
+ });
24207
+ await page.close();
24208
+ return {
24209
+ code: 414,
24210
+ message: msg,
24211
+ data: ""
24212
+ };
24213
+ }
24214
+ await updateTaskState?.({
24215
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24216
+ result: {
24217
+ response: response?.data?.id || ""
24218
+ }
24219
+ });
24220
+ await page.close();
24221
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(response?.data?.id || "");
24222
+ };
24223
+ const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
24224
+ function Md5(input) {
24225
+ return __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(input).digest("hex");
23521
24226
  }
23522
- const xiaohongshuWebNoteFeed_xsEncrypt = new xhs_ob_feed_Xhshow();
23523
- const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
23524
- const xiaohongshuWebNoteFeed = async (_task, params)=>{
23525
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "获取指定文章详情失败", {});
24227
+ const rpa_server_mock_errnoMap = {
24228
+ "-1": "未知拦截器错误,请稍后重试。",
24229
+ 915: "所属C端账号手机号被修改,请重新登录",
24230
+ 914: "所属C端账号密码被修改,请重新登录",
24231
+ 903: "账户已登出,需重新登陆重试!",
24232
+ 902: "登录已过期,请重新登录!",
24233
+ 906: "账号存在风险,请重新登录!",
24234
+ "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
24235
+ };
24236
+ const rpa_server_mock_xsEncrypt = new Xhshow();
24237
+ const rpaAction_Server_Mock = async (task, params)=>{
24238
+ const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
24239
+ const tmpCachePath = task.getTmpPath();
24240
+ if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
24241
+ code: 414,
24242
+ message: "原创声明与转载声明互斥,请重新选择后发布!",
24243
+ data: ""
24244
+ };
24245
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24246
+ if (!a1Cookie) return {
24247
+ code: 414,
24248
+ message: "账号数据异常,请重新绑定账号后重试。",
24249
+ data: ""
24250
+ };
24251
+ const defaultPage = task.steelBrowserContext?.pages()[0];
24252
+ if (defaultPage) {
24253
+ if (!defaultPage._routeRegistered) {
24254
+ defaultPage._routeRegistered = true;
24255
+ const blockedPatterns = [
24256
+ "**/ffmpeg-core.wasm*",
24257
+ "**/apm-fe.xiaohongshu.com*",
24258
+ "**/t2.xiaohongshu.com*",
24259
+ "**/fe-video-qc.xhscdn.com*"
24260
+ ].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
24261
+ await defaultPage.route("**/*", async (route)=>{
24262
+ const req = route.request();
24263
+ const url = req.url();
24264
+ const blocked = blockedPatterns.some((regex)=>regex.test(url));
24265
+ if (!blocked) return route.continue();
24266
+ if ("OPTIONS" === req.method()) {
24267
+ console.log("处理 OPTIONS 预检:", url);
24268
+ await route.fulfill({
24269
+ status: 204,
24270
+ headers: {
24271
+ "access-control-allow-origin": "*",
24272
+ "access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
24273
+ "access-control-allow-headers": "*"
24274
+ },
24275
+ body: ""
24276
+ });
24277
+ return;
24278
+ }
24279
+ await route.fulfill({
24280
+ status: 204,
24281
+ body: ""
24282
+ });
24283
+ });
24284
+ }
24285
+ }
24286
+ const pagePromise = task.createPage({
24287
+ show: task.debug,
24288
+ cookies: params.cookies,
24289
+ url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
24290
+ });
24291
+ await updateTaskState?.({
24292
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.ACTION
24293
+ });
23526
24294
  const headers = {
23527
24295
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23528
- referer: "https://www.xiaohongshu.com/",
23529
- origin: "https://www.xiaohongshu.com/"
24296
+ origin: "https://creator.xiaohongshu.com",
24297
+ referer: "https://creator.xiaohongshu.com/",
24298
+ "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"
23530
24299
  };
24300
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24301
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24302
+ return acc;
24303
+ }, {});
23531
24304
  const args = [
23532
24305
  {
23533
24306
  headers
23534
24307
  },
23535
- _task.logger,
24308
+ task.logger,
23536
24309
  params.proxyLoc,
23537
24310
  params.localIP,
23538
24311
  params.accountId
23539
24312
  ];
23540
- const http = new Http(...args);
23541
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23542
- if (!a1Cookie) return {
24313
+ const http = new Http({
24314
+ headers
24315
+ });
24316
+ const proxyHttp = new Http(...args);
24317
+ proxyHttp.addResponseInterceptor((response)=>{
24318
+ const responseData = response.data;
24319
+ if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
24320
+ const errmsg = rpa_server_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
24321
+ return {
24322
+ code: rpa_server_mock_errnoMap[responseData.code] ? 414 : 500,
24323
+ message: errmsg,
24324
+ data: responseData
24325
+ };
24326
+ }
24327
+ });
24328
+ const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
24329
+ const fetchCoverParams = {
24330
+ biz_name: "spectrum",
24331
+ scene: "image",
24332
+ file_count: params.banners.length,
24333
+ version: 1,
24334
+ source: "web"
24335
+ };
24336
+ const fetchCoverXsHeader = rpa_server_mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
24337
+ const uploadInfos = [];
24338
+ if (params.banners.length > 18) {
24339
+ let num = Math.ceil(params.banners.length / 14);
24340
+ for(let i = 0; i < num; i++){
24341
+ const start = 14 * i;
24342
+ params.banners.length;
24343
+ ({
24344
+ ...fetchCoverParams
24345
+ });
24346
+ const batchCoverIdInfo = await proxyHttp.api({
24347
+ method: "get",
24348
+ baseURL: "https://creator.xiaohongshu.com",
24349
+ url: fetchCoverUrl,
24350
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24351
+ headers: fetchCoverXsHeader,
24352
+ params: fetchCoverParams
24353
+ }, {
24354
+ retries: 3,
24355
+ retryDelay: 20,
24356
+ timeout: 3000
24357
+ });
24358
+ for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24359
+ bucket: item.bucket || "",
24360
+ uploadAddr: item.uploadAddr || "",
24361
+ fileIds: fileId,
24362
+ token: item.token || ""
24363
+ });
24364
+ }
24365
+ } else {
24366
+ const coverIdInfo = await proxyHttp.api({
24367
+ method: "get",
24368
+ baseURL: "https://creator.xiaohongshu.com",
24369
+ url: fetchCoverUrl,
24370
+ defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
24371
+ headers: fetchCoverXsHeader,
24372
+ params: fetchCoverParams
24373
+ }, {
24374
+ retries: 3,
24375
+ retryDelay: 20,
24376
+ timeout: 3000
24377
+ });
24378
+ for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24379
+ bucket: item.bucket || "",
24380
+ uploadAddr: item.uploadAddr || "",
24381
+ fileIds: fileId,
24382
+ token: item.token || ""
24383
+ });
24384
+ }
24385
+ if (uploadInfos.length < params.banners.length) return {
23543
24386
  code: 414,
23544
- message: "账号数据异常,请重新绑定账号后重试。",
23545
- data: {}
24387
+ message: "可用 OSS bucket 数量不足,无法上传所有图片!",
24388
+ data: ""
23546
24389
  };
23547
- if (!params.source_note_id && !params.xsec_token) return {
24390
+ if (0 === uploadInfos.length) return {
23548
24391
  code: 414,
23549
- message: "参数缺失,请检查后重试!",
23550
- data: {}
24392
+ message: "图片上传失败,请稍后重试!",
24393
+ data: ""
24394
+ };
24395
+ const availableBuckets = Array.from({
24396
+ length: uploadInfos.length
24397
+ }, (_, i)=>i);
24398
+ const uploadFile = async (url, index)=>{
24399
+ const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
24400
+ const localUrl = await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
24401
+ const fileBuffer = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(localUrl);
24402
+ const MAX_RETRIES = uploadInfos.length;
24403
+ task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
24404
+ let attempt = 0;
24405
+ while(attempt < MAX_RETRIES){
24406
+ const ossBucketIndex = availableBuckets.shift();
24407
+ if (void 0 === ossBucketIndex) break;
24408
+ const currentInfo = uploadInfos[ossBucketIndex];
24409
+ const ossFileId = currentInfo.fileIds;
24410
+ const ossToken = currentInfo.token;
24411
+ const ossDomain = currentInfo.uploadAddr;
24412
+ try {
24413
+ await http.api({
24414
+ method: "put",
24415
+ url: `https://${ossDomain}/${ossFileId}`,
24416
+ data: fileBuffer,
24417
+ headers: {
24418
+ "x-cos-security-token": ossToken
24419
+ },
24420
+ defaultErrorMsg: "图片上传异常,请稍后重试发布。"
24421
+ });
24422
+ return {
24423
+ ossFileId,
24424
+ ossToken
24425
+ };
24426
+ } catch (error) {
24427
+ task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
24428
+ attempt++;
24429
+ }
24430
+ }
24431
+ return {
24432
+ ossFileId: "",
24433
+ ossToken: ""
24434
+ };
24435
+ };
24436
+ const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
24437
+ const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
24438
+ if (invalidUpload) return {
24439
+ code: 414,
24440
+ message: "图片上传异常,请稍后重试发布。",
24441
+ data: ""
24442
+ };
24443
+ if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
24444
+ if (!topic.id) {
24445
+ const topicData = {
24446
+ topic_names: topic.name
24447
+ };
24448
+ const topicXsHeader = rpa_server_mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
24449
+ const createTopic = await proxyHttp.api({
24450
+ method: "POST",
24451
+ url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
24452
+ headers: topicXsHeader,
24453
+ data: topicData,
24454
+ defaultErrorMsg: "话题创建异常,请稍后重试。"
24455
+ }, {
24456
+ retries: 3,
24457
+ retryDelay: 20,
24458
+ timeout: 3000
24459
+ });
24460
+ Object.assign(topic, createTopic.data.topic_infos[0]);
24461
+ }
24462
+ }));
24463
+ const visibleRangeMap = {
24464
+ public: 0,
24465
+ private: 1,
24466
+ friends: 4
23551
24467
  };
23552
- const feedParams = {
23553
- source_note_id: params.source_note_id,
23554
- image_formats: [
23555
- "jpg",
23556
- "webp",
23557
- "avif"
23558
- ],
23559
- extra: {
23560
- need_body_topic: "1"
24468
+ const publishData = {
24469
+ common: {
24470
+ ats: [],
24471
+ biz_relations: [],
24472
+ desc: params?.content,
24473
+ goods_info: {},
24474
+ hash_tag: params.topic || [],
24475
+ note_id: "",
24476
+ source: JSON.stringify({
24477
+ type: "web",
24478
+ ids: "",
24479
+ extraInfo: '{"systemId":"web"}'
24480
+ }),
24481
+ title: params?.title,
24482
+ type: "normal",
24483
+ privacy_info: {
24484
+ op_type: 1,
24485
+ type: visibleRangeMap[params.visibleRange]
24486
+ },
24487
+ post_loc: params.address ? {
24488
+ name: params.address?.name,
24489
+ poi_id: params.address?.poi_id,
24490
+ poi_type: params.address?.poi_type,
24491
+ subname: params.address?.full_address
24492
+ } : null,
24493
+ business_binds: ""
23561
24494
  },
23562
- xsec_source: "pc_feed",
23563
- xsec_token: params.xsec_token
24495
+ image_info: {
24496
+ images: coverInfos.map((it)=>({
24497
+ extra_info_json: '{"mimeType":"image/png"}',
24498
+ file_id: it.ossFileId,
24499
+ metadata: {
24500
+ source: -1
24501
+ },
24502
+ stickers: {
24503
+ floating: [],
24504
+ version: 2
24505
+ }
24506
+ }))
24507
+ },
24508
+ video_info: null
23564
24509
  };
23565
- const fatchFeed = "/api/sns/web/v1/feed";
23566
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23567
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23568
- return acc;
23569
- }, {});
23570
- const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
23571
- const xT = Date.now().toString();
23572
- const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
23573
- _task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
23574
- _task.logger.info(`X-S: ${xsHeader["X-S"]}`);
23575
- _task.logger.info(`x-s-common: ${xsCommon}`);
23576
- const res = await http.api({
23577
- method: "post",
23578
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
23579
- data: feedParams,
23580
- headers: {
23581
- "X-S": xsHeader["X-S"],
23582
- "X-S-Common": xsCommon,
23583
- "X-T": xT
24510
+ const userDeclarationBind = {
24511
+ origin: 2,
24512
+ photoInfo: {},
24513
+ repostInfo: {}
24514
+ };
24515
+ if (params.selfDeclaration?.type === "fictional-rendition") userDeclarationBind.origin = 1;
24516
+ else if (params.selfDeclaration?.type === "ai-generated") userDeclarationBind.origin = 2;
24517
+ else if (params.selfDeclaration?.type === "source-statement") {
24518
+ if ("self-labeling" === params.selfDeclaration.childType) userDeclarationBind.origin = 3;
24519
+ else if ("self-shooting" === params.selfDeclaration.childType) {
24520
+ userDeclarationBind.origin = 4;
24521
+ const photoInfo = {};
24522
+ if (params.selfDeclaration.shootingLocation) photoInfo.photoPlace = {
24523
+ name: params.selfDeclaration.shootingLocation.name,
24524
+ poiId: params.selfDeclaration.shootingLocation.poi_id,
24525
+ poiType: params.selfDeclaration.shootingLocation.poi_type,
24526
+ subname: params.selfDeclaration.shootingLocation.full_address
24527
+ };
24528
+ if (params.selfDeclaration.shootingDate) photoInfo.photoTime = params.selfDeclaration.shootingDate;
24529
+ userDeclarationBind.photoInfo = photoInfo;
24530
+ } else if ("transshipment" === params.selfDeclaration.childType) {
24531
+ userDeclarationBind.origin = 5;
24532
+ if (params.selfDeclaration.sourceMedia) userDeclarationBind.repostInfo = {
24533
+ source: params.selfDeclaration.sourceMedia
24534
+ };
23584
24535
  }
24536
+ }
24537
+ const bizId = params?.originalBind && (params.cookies.find((it)=>"x-user-id-creator.xiaohongshu.com" === it.name)?.value || await proxyHttp.api({
24538
+ method: "get",
24539
+ url: "https://creator.xiaohongshu.com/api/galaxy/user/my-info"
23585
24540
  }, {
23586
24541
  retries: 3,
23587
24542
  retryDelay: 20,
23588
24543
  timeout: 3000
24544
+ }).then((userData)=>userData.data?.userDetail?.id));
24545
+ const business_binds = {
24546
+ version: 1,
24547
+ bizType: "",
24548
+ noteId: "",
24549
+ noteOrderBind: {},
24550
+ notePostTiming: params.isImmediatelyPublish ? {} : {
24551
+ postTime: params.scheduledPublish
24552
+ },
24553
+ coProduceBind: {
24554
+ enable: !!params?.coProduceBind
24555
+ },
24556
+ noteCopyBind: {
24557
+ copyable: !!params?.noteCopyBind
24558
+ },
24559
+ optionRelationList: params.originalBind ? [
24560
+ {
24561
+ type: "ORIGINAL_STATEMENT",
24562
+ relationList: [
24563
+ {
24564
+ bizId,
24565
+ bizType: "ORIGINAL_STATEMENT",
24566
+ extraInfo: "{}"
24567
+ }
24568
+ ]
24569
+ }
24570
+ ] : [],
24571
+ ...params?.groupBind ? {
24572
+ groupBind: {
24573
+ groupId: params?.groupBind?.group_id,
24574
+ groupName: params.groupBind?.group_name,
24575
+ desc: params.groupBind?.desc,
24576
+ avatar: params.groupBind?.avatar
24577
+ }
24578
+ } : {
24579
+ groupBind: {}
24580
+ },
24581
+ ...params.selfDeclaration ? {
24582
+ userDeclarationBind
24583
+ } : {},
24584
+ ...params?.collectionBind?.id ? {
24585
+ noteCollectionBind: {
24586
+ id: params.collectionBind.id
24587
+ }
24588
+ } : {}
24589
+ };
24590
+ publishData.common.business_binds = JSON.stringify(business_binds);
24591
+ task._timerRecord.PrePublish = Date.now();
24592
+ const page = await pagePromise;
24593
+ await updateTaskState?.({
24594
+ sessionId: task.sessionId
23589
24595
  });
23590
- _task.logger.info(`API 响应: ${JSON.stringify(res)}`);
23591
- const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
23592
- const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23593
- const data = isSuccess ? res.data?.items[0].note_card || {} : {};
23594
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
24596
+ const publishXsHeader = {
24597
+ "x-s": "",
24598
+ "x-t": Date.now().toString()
24599
+ };
24600
+ await page.waitForFunction(()=>"function" == typeof window.mnsv2, {
24601
+ timeout: 10000
24602
+ });
24603
+ const encodeData = `/web_api/sns/v2/note${JSON.stringify(publishData)}`;
24604
+ const ticket_mnsv2 = await page.evaluate(({ c, d })=>{
24605
+ if ("function" == typeof window.mnsv2) return window.mnsv2(c, d);
24606
+ return "mnsv2 未定义";
24607
+ }, {
24608
+ c: encodeData,
24609
+ d: Md5(encodeData)
24610
+ });
24611
+ publishXsHeader["x-s"] = rpa_server_mock_encode_mnsv2(ticket_mnsv2, "Windows", "object");
24612
+ publishXsHeader["x-t"] = Date.now().toString();
24613
+ if (MockPublish) {
24614
+ const message = `文章模拟发布成功 ${http.proxyInfo}`;
24615
+ const data = "123456789";
24616
+ await updateTaskState?.({
24617
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24618
+ result: {
24619
+ response: data
24620
+ }
24621
+ });
24622
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
24623
+ }
24624
+ const publishResult = await proxyHttp.api({
24625
+ method: "post",
24626
+ url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
24627
+ data: publishData,
24628
+ headers: publishXsHeader,
24629
+ defaultErrorMsg: "文章发布异常,请稍后重试。"
24630
+ }, {
24631
+ retries: 2,
24632
+ retryDelay: 500,
24633
+ timeout: 12000
24634
+ });
24635
+ const isSuccess = publishResult.success;
24636
+ const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
24637
+ const data = isSuccess ? publishResult.data?.id || "" : "";
24638
+ if (!isSuccess) {
24639
+ await updateTaskState?.({
24640
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.FAILED,
24641
+ error: message
24642
+ });
24643
+ return {
24644
+ code: 414,
24645
+ data,
24646
+ message
24647
+ };
24648
+ }
24649
+ await updateTaskState?.({
24650
+ state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24651
+ result: {
24652
+ response: data
24653
+ }
24654
+ });
24655
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
24656
+ };
24657
+ const FictionalRendition = schemas_object({
24658
+ type: literal("fictional-rendition")
24659
+ });
24660
+ const AIGenerated = schemas_object({
24661
+ type: literal("ai-generated")
24662
+ });
24663
+ const SourceStatement = schemas_object({
24664
+ type: literal("source-statement"),
24665
+ childType: schemas_enum([
24666
+ "self-labeling",
24667
+ "self-shooting",
24668
+ "transshipment"
24669
+ ]),
24670
+ shootingLocation: custom().optional(),
24671
+ shootingDate: schemas_string().optional(),
24672
+ sourceMedia: schemas_string().optional()
24673
+ });
24674
+ union([
24675
+ FictionalRendition,
24676
+ AIGenerated,
24677
+ SourceStatement
24678
+ ]);
24679
+ const XiaohongshuPublishParamsSchema = ActionCommonParamsSchema.extend({
24680
+ banners: schemas_array(schemas_string()),
24681
+ title: schemas_string(),
24682
+ content: schemas_string(),
24683
+ address: custom().optional(),
24684
+ selfDeclaration: custom().optional(),
24685
+ topic: schemas_array(custom()).optional(),
24686
+ proxyLoc: schemas_string().optional(),
24687
+ localIP: schemas_string().optional(),
24688
+ huiwenToken: schemas_string().optional(),
24689
+ visibleRange: schemas_enum([
24690
+ "public",
24691
+ "private",
24692
+ "friends"
24693
+ ]),
24694
+ isImmediatelyPublish: schemas_boolean().optional(),
24695
+ scheduledPublish: schemas_string().optional(),
24696
+ collectionId: schemas_string().optional(),
24697
+ collectionBind: custom().optional(),
24698
+ groupBind: custom().optional(),
24699
+ noteCopyBind: schemas_boolean().optional(),
24700
+ coProduceBind: schemas_boolean().optional(),
24701
+ originalBind: schemas_boolean().optional()
24702
+ });
24703
+ const xiaohongshuPublish = async (task, params)=>{
24704
+ if (DisabledReq) return {
24705
+ code: 414,
24706
+ data: "",
24707
+ message: "临时维护:小红书发布政策调整,本平台小红书发布功能临时暂停服务并进行维护调整,暂时无法正常发布,敬请理解知悉。"
24708
+ };
24709
+ if ("rpa" === params.actionType) return xiaohongshuPublish_rpa_rpaAction(task, params);
24710
+ if ("mockApi" === params.actionType) return xiaohongshuPublish_mock_mockAction(task, params);
24711
+ if ("server" === params.actionType) return xiaohongshuPublish_rpa_server_rpaAction_Server(task, params);
24712
+ return executeAction(xiaohongshuPublish_mock_mockAction, rpaAction_Server_Mock, xiaohongshuPublish_rpa_server_rpaAction_Server)(task, params);
23595
24713
  };
23596
- const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
23597
- const xiaohongshuWebRelationAction = async (_task, params)=>{
23598
- if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "用户关系操作失败", {});
24714
+ const xiaohongshuWebCommentAction_xsEncrypt = new Xhshow();
24715
+ const xiaohongshuWebCommentAction = async (_task, params)=>{
24716
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "点赞相关操作失败", {});
23599
24717
  const headers = {
23600
24718
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23601
24719
  referer: "https://www.xiaohongshu.com/",
@@ -23615,47 +24733,52 @@ const xiaohongshuWebRelationAction = async (_task, params)=>{
23615
24733
  if (!a1Cookie) return {
23616
24734
  code: 414,
23617
24735
  message: "账号数据异常,请重新绑定账号后重试。",
23618
- data: {}
24736
+ data: []
23619
24737
  };
23620
- if (!params.action || !params.target_user_id) return {
24738
+ if (!params.note_id && !params.comment_id && !params.action) return {
23621
24739
  code: 414,
23622
24740
  message: "参数缺失,请检查后重试!",
23623
24741
  data: {}
23624
24742
  };
23625
- const relationParams = {
23626
- target_user_id: params.target_user_id
24743
+ const actionParams = {
24744
+ note_id: params.note_id,
24745
+ comment_id: params.comment_id
24746
+ };
24747
+ let likeActionRes = {
24748
+ code: 500,
24749
+ success: false,
24750
+ msg: ""
23627
24751
  };
23628
- let relationActionRes;
23629
24752
  const recordCookie = params.cookies.reduce((acc, cookie)=>{
23630
24753
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23631
24754
  return acc;
23632
24755
  }, {});
23633
24756
  switch(params.action){
23634
- case "follow":
24757
+ case "like":
23635
24758
  {
23636
- const followMentions = "/api/sns/web/v1/user/follow";
23637
- const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
23638
- relationActionRes = await http.api({
24759
+ const likeAction = "/api/sns/web/v1/comment/like";
24760
+ const likeActionXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(likeAction, recordCookie, "xhs-pc-web", actionParams);
24761
+ likeActionRes = await http.api({
23639
24762
  method: "post",
23640
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
23641
- data: relationParams,
23642
- headers: followXsHeader
24763
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/like",
24764
+ data: actionParams,
24765
+ headers: likeActionXsHeader
23643
24766
  }, {
23644
24767
  retries: 3,
23645
- retryDelay: 500,
24768
+ retryDelay: 20,
23646
24769
  timeout: 3000
23647
24770
  });
23648
24771
  break;
23649
24772
  }
23650
- case "unfollow":
24773
+ case "dislike":
23651
24774
  {
23652
- const unfllowMentions = "/api/sns/web/v1/user/unfollow";
23653
- const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
23654
- relationActionRes = await http.api({
24775
+ const dislikeMentions = "/api/sns/web/v1/comment/dislike";
24776
+ const dislikeXsHeader = xiaohongshuWebCommentAction_xsEncrypt.signHeadersPost(dislikeMentions, recordCookie, "xhs-pc-web", actionParams);
24777
+ likeActionRes = await http.api({
23655
24778
  method: "post",
23656
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
23657
- data: relationParams,
23658
- headers: unfllowXsHeader
24779
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/dislike",
24780
+ data: actionParams,
24781
+ headers: dislikeXsHeader
23659
24782
  }, {
23660
24783
  retries: 3,
23661
24784
  retryDelay: 20,
@@ -23670,40 +24793,17 @@ const xiaohongshuWebRelationAction = async (_task, params)=>{
23670
24793
  data: {}
23671
24794
  };
23672
24795
  }
23673
- const isSuccess = 0 === relationActionRes.code;
23674
- const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23675
- const data = isSuccess ? relationActionRes.data : {
23676
- fstatus: null
23677
- };
24796
+ const isSuccess = 0 === likeActionRes.code;
24797
+ const message = `点赞相关操作${isSuccess ? "成功" : `失败,原因:${likeActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24798
+ const data = isSuccess ? likeActionRes.success : {};
23678
24799
  return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
23679
24800
  };
23680
- const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
23681
- const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
23682
- keyword: schemas_string(),
23683
- page: schemas_number(),
23684
- page_size: schemas_number(),
23685
- sort_type: schemas_enum([
23686
- "general",
23687
- "time_descending",
23688
- "popular_descending"
23689
- ]),
23690
- time_filter: schemas_enum([
23691
- "不限",
23692
- "一周内"
23693
- ])
23694
- });
23695
- const createSearchId = ()=>{
23696
- let r = BigInt(Date.now());
23697
- const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
23698
- r <<= BigInt(64);
23699
- r += o;
23700
- return r.toString(36);
23701
- };
23702
- const xiaohongshuWebSearch = async (_task, params)=>{
24801
+ const xiaohongshuWebIntimacySearch = async (_task, params)=>{
24802
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(0, "搜索@列表数据成功", []);
23703
24803
  const headers = {
23704
24804
  cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23705
24805
  referer: "https://www.xiaohongshu.com/",
23706
- origin: "https://www.xiaohongshu.com/"
24806
+ origin: "https://www.xiaohongshu.com"
23707
24807
  };
23708
24808
  const args = [
23709
24809
  {
@@ -23715,569 +24815,461 @@ const xiaohongshuWebSearch = async (_task, params)=>{
23715
24815
  params.accountId
23716
24816
  ];
23717
24817
  const http = new Http(...args);
23718
- const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23719
- if (!a1Cookie) return {
23720
- code: 414,
23721
- message: "账号数据异常,请重新绑定账号后重试。",
23722
- data: {}
23723
- };
23724
- if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
23725
- if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
23726
- code: 414,
23727
- message: "排序类型参数错误,请检查后重试!",
23728
- data: {}
23729
- };
23730
- if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
23731
- code: 414,
23732
- message: "时间过滤参数错误,请检查后重试!",
23733
- data: {}
23734
- };
23735
- return {
23736
- code: 414,
23737
- message: "参数缺失,请检查后重试!",
23738
- data: {}
23739
- };
23740
- }
23741
- const filterPath = "/api/sns/web/v1/search/notes";
23742
- const filterParams = {
23743
- ext_flags: [],
23744
- geo: "",
23745
- image_formats: [
23746
- "jpg",
23747
- "webp",
23748
- "avif"
23749
- ],
23750
- filters: [
23751
- {
23752
- tags: [
23753
- params.sort_type
23754
- ],
23755
- type: "sort_type"
23756
- },
23757
- {
23758
- tags: [
23759
- "不限"
23760
- ],
23761
- type: "filter_note_type"
23762
- },
23763
- {
23764
- tags: [
23765
- params.time_filter
23766
- ],
23767
- type: "filter_note_time"
23768
- },
23769
- {
23770
- tags: [
23771
- "不限"
23772
- ],
23773
- type: "filter_note_range"
23774
- },
23775
- {
23776
- tags: [
23777
- "不限"
23778
- ],
23779
- type: "filter_pos_distance"
23780
- }
23781
- ],
23782
- keyword: params.keyword,
23783
- note_type: 0,
23784
- page: params.page,
23785
- page_size: params.page_size,
23786
- search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
23787
- sort: "general"
23788
- };
23789
- const recordCookie = params.cookies.reduce((acc, cookie)=>{
23790
- if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23791
- return acc;
23792
- }, {});
23793
- const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
24818
+ let intimacyDetail = [];
23794
24819
  const res = await http.api({
23795
- method: "post",
23796
- url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
23797
- data: filterParams,
23798
- headers: searchXsHeader
24820
+ method: "get",
24821
+ url: `https://edith.xiaohongshu.com/api/sns/web/v1/intimacy/intimacy_list${params.searchValue ? "/search" : ""}`,
24822
+ ...params.searchValue ? {
24823
+ params: {
24824
+ keyword: params.searchValue,
24825
+ page: 1,
24826
+ rows: 30
24827
+ }
24828
+ } : {}
23799
24829
  }, {
23800
24830
  retries: 3,
23801
24831
  retryDelay: 20,
23802
24832
  timeout: 3000
23803
24833
  });
23804
24834
  const isSuccess = 0 === res.code;
23805
- const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
23806
- const data = isSuccess ? res.data : {};
23807
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
23808
- };
23809
- const ttConfigDataSchema = schemas_object({
23810
- fansNum: schemas_number(),
23811
- fansNumYesterday: schemas_number().nullable(),
23812
- readNum: schemas_number(),
23813
- incomeNum: schemas_number(),
23814
- incomeNumYesterday: schemas_number().nullable(),
23815
- showNumYesterday: schemas_number().nullable(),
23816
- readNumYesterday: schemas_number().nullable(),
23817
- likeNumYesterday: schemas_number().nullable(),
23818
- commentNumYesterday: schemas_number().nullable()
23819
- });
23820
- const xhsConfigDataSchema = schemas_object({
23821
- fansNum: schemas_number(),
23822
- favedNum: schemas_number(),
23823
- watchNumLastWeek: schemas_number(),
23824
- likeNumLastWeek: schemas_number(),
23825
- collectNumLastWeek: schemas_number(),
23826
- commentNumLastWeek: schemas_number(),
23827
- fansNumLastWeek: schemas_number(),
23828
- fansNumYesterday: schemas_number()
23829
- });
23830
- const wxConfigDataSchema = schemas_object({
23831
- fansNum: schemas_number(),
23832
- fansNumYesterday: schemas_number(),
23833
- readNumYesterday: schemas_number(),
23834
- shareNumYesterday: schemas_number()
23835
- });
23836
- const bjhConfigDataSchema = schemas_object({
23837
- fansNum: schemas_number(),
23838
- fansNumYesterday: schemas_number().nullable(),
23839
- readNum: schemas_number(),
23840
- incomeNum: schemas_number(),
23841
- incomeNumYesterday: schemas_number().nullable(),
23842
- recommendNumYesterday: schemas_number().nullable(),
23843
- readNumYesterday: schemas_number().nullable(),
23844
- likeNumYesterday: schemas_number().nullable(),
23845
- commentNumYesterday: schemas_number().nullable()
23846
- });
23847
- const rpa_server_mock_encode_mnsv2 = __webpack_require__("./src/utils/xhs_ob/x_s.encoder.js");
23848
- function Md5(input) {
23849
- return __WEBPACK_EXTERNAL_MODULE_node_crypto_9ba42079__["default"].createHash("md5").update(input).digest("hex");
23850
- }
23851
- const rpa_server_mock_errnoMap = {
23852
- "-1": "未知拦截器错误,请稍后重试。",
23853
- 915: "所属C端账号手机号被修改,请重新登录",
23854
- 914: "所属C端账号密码被修改,请重新登录",
23855
- 903: "账户已登出,需重新登陆重试!",
23856
- 902: "登录已过期,请重新登录!",
23857
- 906: "账号存在风险,请重新登录!",
23858
- "-9136": "因违反社区规范禁止发笔记,请检查账号状态!"
24835
+ if (isSuccess) intimacyDetail = res.data.items;
24836
+ const message = `搜索@列表数据${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24837
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, intimacyDetail);
23859
24838
  };
23860
- const rpa_server_mock_xsEncrypt = new Xhshow();
23861
- const rpaAction_Server_Mock = async (task, params)=>{
23862
- const updateTaskState = task.taskStageStore?.update?.bind(task.taskStageStore, task.taskId || "");
23863
- const tmpCachePath = task.getTmpPath();
23864
- if (params?.selfDeclaration?.type === "source-statement" && "transshipment" === params.selfDeclaration.childType && params.originalBind) return {
23865
- code: 414,
23866
- message: "原创声明与转载声明互斥,请重新选择后发布!",
23867
- data: ""
24839
+ const xiaohongshuWebMsgRead_xsEncrypt = new Xhshow();
24840
+ const xiaohongshuWebMsgRead = async (_task, params)=>{
24841
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "Read指定Tab失败", {});
24842
+ const headers = {
24843
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24844
+ referer: "https://www.xiaohongshu.com/",
24845
+ origin: "https://www.xiaohongshu.com/"
23868
24846
  };
24847
+ const args = [
24848
+ {
24849
+ headers
24850
+ },
24851
+ _task.logger,
24852
+ params.proxyLoc,
24853
+ params.localIP,
24854
+ params.accountId
24855
+ ];
24856
+ const http = new Http(...args);
23869
24857
  const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
23870
24858
  if (!a1Cookie) return {
23871
24859
  code: 414,
23872
24860
  message: "账号数据异常,请重新绑定账号后重试。",
23873
- data: ""
24861
+ data: []
23874
24862
  };
23875
- const defaultPage = task.steelBrowserContext?.pages()[0];
23876
- if (defaultPage) {
23877
- if (!defaultPage._routeRegistered) {
23878
- defaultPage._routeRegistered = true;
23879
- const blockedPatterns = [
23880
- "**/ffmpeg-core.wasm*",
23881
- "**/apm-fe.xiaohongshu.com*",
23882
- "**/t2.xiaohongshu.com*",
23883
- "**/fe-video-qc.xhscdn.com*"
23884
- ].map((pattern)=>new RegExp(pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*")));
23885
- await defaultPage.route("**/*", async (route)=>{
23886
- const req = route.request();
23887
- const url = req.url();
23888
- const blocked = blockedPatterns.some((regex)=>regex.test(url));
23889
- if (!blocked) return route.continue();
23890
- if ("OPTIONS" === req.method()) {
23891
- console.log("处理 OPTIONS 预检:", url);
23892
- await route.fulfill({
23893
- status: 204,
23894
- headers: {
23895
- "access-control-allow-origin": "*",
23896
- "access-control-allow-methods": "GET,POST,OPTIONS,PUT,DELETE",
23897
- "access-control-allow-headers": "*"
23898
- },
23899
- body: ""
23900
- });
23901
- return;
23902
- }
23903
- await route.fulfill({
23904
- status: 204,
23905
- body: ""
23906
- });
23907
- });
23908
- }
23909
- }
23910
- const pagePromise = task.createPage({
23911
- show: task.debug,
23912
- cookies: params.cookies,
23913
- url: params.url || "https://creator.xiaohongshu.com/statistics/account/v2?source=official"
23914
- });
23915
- await updateTaskState?.({
23916
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.ACTION
23917
- });
23918
- const headers = {
23919
- cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
23920
- origin: "https://creator.xiaohongshu.com",
23921
- referer: "https://creator.xiaohongshu.com/",
23922
- "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"
24863
+ if (!params.type) return {
24864
+ code: 414,
24865
+ message: "参数缺失,请检查后重试!",
24866
+ data: {}
24867
+ };
24868
+ const replyParams = {
24869
+ type: params.type
23923
24870
  };
24871
+ const fatchMentions = "/api/sns/web/v1/message/read";
23924
24872
  const recordCookie = params.cookies.reduce((acc, cookie)=>{
23925
24873
  if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
23926
24874
  return acc;
23927
24875
  }, {});
24876
+ const fatchMentionsXsHeader = xiaohongshuWebMsgRead_xsEncrypt.signHeadersPost(fatchMentions, recordCookie, "xhs-pc-web", replyParams);
24877
+ const res = await http.api({
24878
+ method: "post",
24879
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/message/read",
24880
+ data: replyParams,
24881
+ headers: fatchMentionsXsHeader
24882
+ }, {
24883
+ retries: 3,
24884
+ retryDelay: 20,
24885
+ timeout: 3000
24886
+ });
24887
+ const isSuccess = 0 === res.code;
24888
+ const message = `Read指定Tab${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24889
+ const data = isSuccess ? res.success : {};
24890
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
24891
+ };
24892
+ const xiaohongshuWebMsgReply_xsEncrypt = new Xhshow();
24893
+ const xiaohongshuWebMsgReply = async (_task, params)=>{
24894
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "评论回复失败", {});
24895
+ const headers = {
24896
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24897
+ referer: "https://www.xiaohongshu.com/",
24898
+ origin: "https://www.xiaohongshu.com/"
24899
+ };
23928
24900
  const args = [
23929
24901
  {
23930
24902
  headers
23931
24903
  },
23932
- task.logger,
24904
+ _task.logger,
23933
24905
  params.proxyLoc,
23934
24906
  params.localIP,
23935
24907
  params.accountId
23936
24908
  ];
23937
- const http = new Http({
23938
- headers
23939
- });
23940
- const proxyHttp = new Http(...args);
23941
- proxyHttp.addResponseInterceptor((response)=>{
23942
- const responseData = response.data;
23943
- if (response && responseData?.code && 0 !== responseData.code || responseData?.code && !responseData.success) {
23944
- const errmsg = rpa_server_mock_errnoMap[responseData.code] || response.config.defaultErrorMsg || "文章发布异常,请稍后重试。";
23945
- return {
23946
- code: rpa_server_mock_errnoMap[responseData.code] ? 414 : 500,
23947
- message: errmsg,
23948
- data: responseData
23949
- };
23950
- }
23951
- });
23952
- const fetchCoverUrl = "/api/media/v1/upload/creator/permit";
23953
- const fetchCoverParams = {
23954
- biz_name: "spectrum",
23955
- scene: "image",
23956
- file_count: params.banners.length,
23957
- version: 1,
23958
- source: "web"
23959
- };
23960
- const fetchCoverXsHeader = rpa_server_mock_xsEncrypt.signHeadersGet(fetchCoverUrl, recordCookie, "ugc", fetchCoverParams);
23961
- const uploadInfos = [];
23962
- if (params.banners.length > 18) {
23963
- let num = Math.ceil(params.banners.length / 14);
23964
- for(let i = 0; i < num; i++){
23965
- const start = 14 * i;
23966
- params.banners.length;
23967
- ({
23968
- ...fetchCoverParams
23969
- });
23970
- const batchCoverIdInfo = await proxyHttp.api({
23971
- method: "get",
23972
- baseURL: "https://creator.xiaohongshu.com",
23973
- url: fetchCoverUrl,
23974
- defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23975
- headers: fetchCoverXsHeader,
23976
- params: fetchCoverParams
23977
- }, {
23978
- retries: 3,
23979
- retryDelay: 20,
23980
- timeout: 3000
23981
- });
23982
- for (const item of batchCoverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
23983
- bucket: item.bucket || "",
23984
- uploadAddr: item.uploadAddr || "",
23985
- fileIds: fileId,
23986
- token: item.token || ""
23987
- });
23988
- }
23989
- } else {
23990
- const coverIdInfo = await proxyHttp.api({
23991
- method: "get",
23992
- baseURL: "https://creator.xiaohongshu.com",
23993
- url: fetchCoverUrl,
23994
- defaultErrorMsg: "获取小红书用户信息失败,请稍后重试发布。",
23995
- headers: fetchCoverXsHeader,
23996
- params: fetchCoverParams
23997
- }, {
23998
- retries: 3,
23999
- retryDelay: 20,
24000
- timeout: 3000
24001
- });
24002
- for (const item of coverIdInfo.data.uploadTempPermits)for (const fileId of item.fileIds)uploadInfos.push({
24003
- bucket: item.bucket || "",
24004
- uploadAddr: item.uploadAddr || "",
24005
- fileIds: fileId,
24006
- token: item.token || ""
24007
- });
24008
- }
24009
- if (uploadInfos.length < params.banners.length) return {
24909
+ const http = new Http(...args);
24910
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24911
+ if (!a1Cookie) return {
24010
24912
  code: 414,
24011
- message: "可用 OSS bucket 数量不足,无法上传所有图片!",
24012
- data: ""
24913
+ message: "账号数据异常,请重新绑定账号后重试。",
24914
+ data: []
24013
24915
  };
24014
- if (0 === uploadInfos.length) return {
24916
+ if (!params.note_id || !params.target_comment_id || !params.content) return {
24015
24917
  code: 414,
24016
- message: "图片上传失败,请稍后重试!",
24017
- data: ""
24918
+ message: "参数缺失,请检查后重试!",
24919
+ data: {}
24018
24920
  };
24019
- const availableBuckets = Array.from({
24020
- length: uploadInfos.length
24021
- }, (_, i)=>i);
24022
- const uploadFile = async (url, index)=>{
24023
- const fileName = (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.getFilenameFromUrl)(url);
24024
- const localUrl = await (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.downloadImage)(url, __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(tmpCachePath, fileName));
24025
- const fileBuffer = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"].readFileSync(localUrl);
24026
- const MAX_RETRIES = uploadInfos.length;
24027
- task.logger.debug(`上传图片 ${index + 1}:尝试使用最多 ${MAX_RETRIES} 个 bucket`);
24028
- let attempt = 0;
24029
- while(attempt < MAX_RETRIES){
24030
- const ossBucketIndex = availableBuckets.shift();
24031
- if (void 0 === ossBucketIndex) break;
24032
- const currentInfo = uploadInfos[ossBucketIndex];
24033
- const ossFileId = currentInfo.fileIds;
24034
- const ossToken = currentInfo.token;
24035
- const ossDomain = currentInfo.uploadAddr;
24036
- try {
24037
- await http.api({
24038
- method: "put",
24039
- url: `https://${ossDomain}/${ossFileId}`,
24040
- data: fileBuffer,
24041
- headers: {
24042
- "x-cos-security-token": ossToken
24043
- },
24044
- defaultErrorMsg: "图片上传异常,请稍后重试发布。"
24045
- });
24046
- return {
24047
- ossFileId,
24048
- ossToken
24049
- };
24050
- } catch (error) {
24051
- task.logger.warn(`上传图片 ${index + 1}:使用 bucket ${ossDomain} 失败,尝试下一个可用 bucket。错误信息:${error.message}`);
24052
- attempt++;
24053
- }
24054
- }
24055
- return {
24056
- ossFileId: "",
24057
- ossToken: ""
24058
- };
24921
+ const replyParams = {
24922
+ at_users: params.at_users ?? [],
24923
+ content: params.content,
24924
+ note_id: params.note_id,
24925
+ target_comment_id: params.target_comment_id
24926
+ };
24927
+ const replyPath = "/api/sns/web/v1/comment/post";
24928
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24929
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24930
+ return acc;
24931
+ }, {});
24932
+ const replyXsHeader = xiaohongshuWebMsgReply_xsEncrypt.signHeadersPost(replyPath, recordCookie, "xhs-pc-web", replyParams);
24933
+ const res = await http.api({
24934
+ method: "post",
24935
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/comment/post",
24936
+ data: replyParams,
24937
+ headers: replyXsHeader
24938
+ }, {
24939
+ retries: 3,
24940
+ retryDelay: 20,
24941
+ timeout: 3000
24942
+ });
24943
+ const isSuccess = 0 === res.code;
24944
+ const message = `评论回复${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
24945
+ const data = isSuccess ? res.data : {};
24946
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
24947
+ };
24948
+ const xiaohongshuWebNoteFeed_xsEncrypt = new xhs_ob_feed_Xhshow();
24949
+ const GenXSCommon = __webpack_require__("./src/utils/XhsXsCommonEnc.js");
24950
+ const xiaohongshuWebNoteFeed = async (_task, params)=>{
24951
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "获取指定文章详情失败", {});
24952
+ const headers = {
24953
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
24954
+ referer: "https://www.xiaohongshu.com/",
24955
+ origin: "https://www.xiaohongshu.com/"
24059
24956
  };
24060
- const coverInfos = await Promise.all(params.banners.map((it, idx)=>uploadFile(it, idx)));
24061
- const invalidUpload = coverInfos.find((it)=>"" === it.ossToken || "" === it.ossFileId);
24062
- if (invalidUpload) return {
24957
+ const args = [
24958
+ {
24959
+ headers
24960
+ },
24961
+ _task.logger,
24962
+ params.proxyLoc,
24963
+ params.localIP,
24964
+ params.accountId
24965
+ ];
24966
+ const http = new Http(...args);
24967
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
24968
+ if (!a1Cookie) return {
24063
24969
  code: 414,
24064
- message: "图片上传异常,请稍后重试发布。",
24065
- data: ""
24970
+ message: "账号数据异常,请重新绑定账号后重试。",
24971
+ data: {}
24066
24972
  };
24067
- if (params.topic && params.topic.length > 0) await Promise.all(params.topic.map(async (topic)=>{
24068
- if (!topic.id) {
24069
- const topicData = {
24070
- topic_names: topic.name
24071
- };
24072
- const topicXsHeader = rpa_server_mock_xsEncrypt.signHeadersPost("/web_api/sns/capa/postgw/topic/batch_customized", recordCookie, "ugc", topicData);
24073
- const createTopic = await proxyHttp.api({
24074
- method: "POST",
24075
- url: "https://edith.xiaohongshu.com/web_api/sns/capa/postgw/topic/batch_customized",
24076
- headers: topicXsHeader,
24077
- data: topicData,
24078
- defaultErrorMsg: "话题创建异常,请稍后重试。"
24079
- }, {
24080
- retries: 3,
24081
- retryDelay: 20,
24082
- timeout: 3000
24083
- });
24084
- Object.assign(topic, createTopic.data.topic_infos[0]);
24085
- }
24086
- }));
24087
- const visibleRangeMap = {
24088
- public: 0,
24089
- private: 1,
24090
- friends: 4
24973
+ if (!params.source_note_id && !params.xsec_token) return {
24974
+ code: 414,
24975
+ message: "参数缺失,请检查后重试!",
24976
+ data: {}
24091
24977
  };
24092
- const publishData = {
24093
- common: {
24094
- ats: [],
24095
- biz_relations: [],
24096
- desc: params?.content,
24097
- goods_info: {},
24098
- hash_tag: params.topic || [],
24099
- note_id: "",
24100
- source: JSON.stringify({
24101
- type: "web",
24102
- ids: "",
24103
- extraInfo: '{"systemId":"web"}'
24104
- }),
24105
- title: params?.title,
24106
- type: "normal",
24107
- privacy_info: {
24108
- op_type: 1,
24109
- type: visibleRangeMap[params.visibleRange]
24110
- },
24111
- post_loc: params.address ? {
24112
- name: params.address?.name,
24113
- poi_id: params.address?.poi_id,
24114
- poi_type: params.address?.poi_type,
24115
- subname: params.address?.full_address
24116
- } : null,
24117
- business_binds: ""
24118
- },
24119
- image_info: {
24120
- images: coverInfos.map((it)=>({
24121
- extra_info_json: '{"mimeType":"image/png"}',
24122
- file_id: it.ossFileId,
24123
- metadata: {
24124
- source: -1
24125
- },
24126
- stickers: {
24127
- floating: [],
24128
- version: 2
24129
- }
24130
- }))
24978
+ const feedParams = {
24979
+ source_note_id: params.source_note_id,
24980
+ image_formats: [
24981
+ "jpg",
24982
+ "webp",
24983
+ "avif"
24984
+ ],
24985
+ extra: {
24986
+ need_body_topic: "1"
24131
24987
  },
24132
- video_info: null
24133
- };
24134
- const userDeclarationBind = {
24135
- origin: 2,
24136
- photoInfo: {},
24137
- repostInfo: {}
24988
+ xsec_source: "pc_feed",
24989
+ xsec_token: params.xsec_token
24138
24990
  };
24139
- if (params.selfDeclaration?.type === "fictional-rendition") userDeclarationBind.origin = 1;
24140
- else if (params.selfDeclaration?.type === "ai-generated") userDeclarationBind.origin = 2;
24141
- else if (params.selfDeclaration?.type === "source-statement") {
24142
- if ("self-labeling" === params.selfDeclaration.childType) userDeclarationBind.origin = 3;
24143
- else if ("self-shooting" === params.selfDeclaration.childType) {
24144
- userDeclarationBind.origin = 4;
24145
- const photoInfo = {};
24146
- if (params.selfDeclaration.shootingLocation) photoInfo.photoPlace = {
24147
- name: params.selfDeclaration.shootingLocation.name,
24148
- poiId: params.selfDeclaration.shootingLocation.poi_id,
24149
- poiType: params.selfDeclaration.shootingLocation.poi_type,
24150
- subname: params.selfDeclaration.shootingLocation.full_address
24151
- };
24152
- if (params.selfDeclaration.shootingDate) photoInfo.photoTime = params.selfDeclaration.shootingDate;
24153
- userDeclarationBind.photoInfo = photoInfo;
24154
- } else if ("transshipment" === params.selfDeclaration.childType) {
24155
- userDeclarationBind.origin = 5;
24156
- if (params.selfDeclaration.sourceMedia) userDeclarationBind.repostInfo = {
24157
- source: params.selfDeclaration.sourceMedia
24158
- };
24991
+ const fatchFeed = "/api/sns/web/v1/feed";
24992
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
24993
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
24994
+ return acc;
24995
+ }, {});
24996
+ const xsHeader = xiaohongshuWebNoteFeed_xsEncrypt.signHeadersPost(fatchFeed, recordCookie, "xhs-pc-web", feedParams);
24997
+ const xT = Date.now().toString();
24998
+ const xsCommon = GenXSCommon(a1Cookie, xT, xsHeader["X-S"]);
24999
+ _task.logger.info(`请求参数: ${JSON.stringify(feedParams)}`);
25000
+ _task.logger.info(`X-S: ${xsHeader["X-S"]}`);
25001
+ _task.logger.info(`x-s-common: ${xsCommon}`);
25002
+ const res = await http.api({
25003
+ method: "post",
25004
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/feed",
25005
+ data: feedParams,
25006
+ headers: {
25007
+ "X-S": xsHeader["X-S"],
25008
+ "X-S-Common": xsCommon,
25009
+ "X-T": xT
24159
25010
  }
24160
- }
24161
- const bizId = params?.originalBind && (params.cookies.find((it)=>"x-user-id-creator.xiaohongshu.com" === it.name)?.value || await proxyHttp.api({
24162
- method: "get",
24163
- url: "https://creator.xiaohongshu.com/api/galaxy/user/my-info"
24164
25011
  }, {
24165
25012
  retries: 3,
24166
25013
  retryDelay: 20,
24167
25014
  timeout: 3000
24168
- }).then((userData)=>userData.data?.userDetail?.id));
24169
- const business_binds = {
24170
- version: 1,
24171
- bizType: "",
24172
- noteId: "",
24173
- noteOrderBind: {},
24174
- notePostTiming: params.isImmediatelyPublish ? {} : {
24175
- postTime: params.scheduledPublish
24176
- },
24177
- coProduceBind: {
24178
- enable: !!params?.coProduceBind
24179
- },
24180
- noteCopyBind: {
24181
- copyable: !!params?.noteCopyBind
25015
+ });
25016
+ _task.logger.info(`API 响应: ${JSON.stringify(res)}`);
25017
+ const isSuccess = 0 === res.code && res.data && res.data.items && res.data.items.length > 0;
25018
+ const message = `获取指定文章详情${isSuccess ? "成功" : `失败,原因:${res.msg || "返回数据为空,可能笔记不存在或参数错误"}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25019
+ const data = isSuccess ? res.data?.items[0].note_card || {} : {};
25020
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
25021
+ };
25022
+ const xiaohongshuWebRelationAction_xsEncrypt = new Xhshow();
25023
+ const xiaohongshuWebRelationAction = async (_task, params)=>{
25024
+ if (DisabledReq) return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(414, "用户关系操作失败", {});
25025
+ const headers = {
25026
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25027
+ referer: "https://www.xiaohongshu.com/",
25028
+ origin: "https://www.xiaohongshu.com/"
25029
+ };
25030
+ const args = [
25031
+ {
25032
+ headers
24182
25033
  },
24183
- optionRelationList: params.originalBind ? [
25034
+ _task.logger,
25035
+ params.proxyLoc,
25036
+ params.localIP,
25037
+ params.accountId
25038
+ ];
25039
+ const http = new Http(...args);
25040
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25041
+ if (!a1Cookie) return {
25042
+ code: 414,
25043
+ message: "账号数据异常,请重新绑定账号后重试。",
25044
+ data: {}
25045
+ };
25046
+ if (!params.action || !params.target_user_id) return {
25047
+ code: 414,
25048
+ message: "参数缺失,请检查后重试!",
25049
+ data: {}
25050
+ };
25051
+ const relationParams = {
25052
+ target_user_id: params.target_user_id
25053
+ };
25054
+ let relationActionRes;
25055
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25056
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25057
+ return acc;
25058
+ }, {});
25059
+ switch(params.action){
25060
+ case "follow":
24184
25061
  {
24185
- type: "ORIGINAL_STATEMENT",
24186
- relationList: [
24187
- {
24188
- bizId,
24189
- bizType: "ORIGINAL_STATEMENT",
24190
- extraInfo: "{}"
24191
- }
24192
- ]
24193
- }
24194
- ] : [],
24195
- ...params?.groupBind ? {
24196
- groupBind: {
24197
- groupId: params?.groupBind?.group_id,
24198
- groupName: params.groupBind?.group_name,
24199
- desc: params.groupBind?.desc,
24200
- avatar: params.groupBind?.avatar
24201
- }
24202
- } : {
24203
- groupBind: {}
24204
- },
24205
- ...params.selfDeclaration ? {
24206
- userDeclarationBind
24207
- } : {},
24208
- ...params?.collectionBind?.id ? {
24209
- noteCollectionBind: {
24210
- id: params.collectionBind.id
25062
+ const followMentions = "/api/sns/web/v1/user/follow";
25063
+ const followXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(followMentions, recordCookie, "xhs-pc-web", relationParams);
25064
+ relationActionRes = await http.api({
25065
+ method: "post",
25066
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/follow",
25067
+ data: relationParams,
25068
+ headers: followXsHeader
25069
+ }, {
25070
+ retries: 3,
25071
+ retryDelay: 500,
25072
+ timeout: 3000
25073
+ });
25074
+ break;
24211
25075
  }
24212
- } : {}
24213
- };
24214
- publishData.common.business_binds = JSON.stringify(business_binds);
24215
- task._timerRecord.PrePublish = Date.now();
24216
- const page = await pagePromise;
24217
- await updateTaskState?.({
24218
- sessionId: task.sessionId
24219
- });
24220
- const publishXsHeader = {
24221
- "x-s": "",
24222
- "x-t": Date.now().toString()
24223
- };
24224
- await page.waitForFunction(()=>"function" == typeof window.mnsv2, {
24225
- timeout: 10000
24226
- });
24227
- const encodeData = `/web_api/sns/v2/note${JSON.stringify(publishData)}`;
24228
- const ticket_mnsv2 = await page.evaluate(({ c, d })=>{
24229
- if ("function" == typeof window.mnsv2) return window.mnsv2(c, d);
24230
- return "mnsv2 未定义";
24231
- }, {
24232
- c: encodeData,
24233
- d: Md5(encodeData)
24234
- });
24235
- publishXsHeader["x-s"] = rpa_server_mock_encode_mnsv2(ticket_mnsv2, "Windows", "object");
24236
- publishXsHeader["x-t"] = Date.now().toString();
24237
- if (MockPublish) {
24238
- const message = `文章模拟发布成功 ${http.proxyInfo}`;
24239
- const data = "123456789";
24240
- await updateTaskState?.({
24241
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24242
- result: {
24243
- response: data
25076
+ case "unfollow":
25077
+ {
25078
+ const unfllowMentions = "/api/sns/web/v1/user/unfollow";
25079
+ const unfllowXsHeader = xiaohongshuWebRelationAction_xsEncrypt.signHeadersPost(unfllowMentions, recordCookie, "xhs-pc-web", relationParams);
25080
+ relationActionRes = await http.api({
25081
+ method: "post",
25082
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/user/unfollow",
25083
+ data: relationParams,
25084
+ headers: unfllowXsHeader
25085
+ }, {
25086
+ retries: 3,
25087
+ retryDelay: 20,
25088
+ timeout: 3000
25089
+ });
25090
+ break;
24244
25091
  }
24245
- });
24246
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
25092
+ default:
25093
+ return {
25094
+ code: 414,
25095
+ message: "参数action错误,请重试!",
25096
+ data: {}
25097
+ };
24247
25098
  }
24248
- const publishResult = await proxyHttp.api({
24249
- method: "post",
24250
- url: "https://edith.xiaohongshu.com/web_api/sns/v2/note",
24251
- data: publishData,
24252
- headers: publishXsHeader,
24253
- defaultErrorMsg: "文章发布异常,请稍后重试。"
24254
- }, {
24255
- retries: 2,
24256
- retryDelay: 500,
24257
- timeout: 12000
24258
- });
24259
- const isSuccess = publishResult.success;
24260
- const message = `文章发布${isSuccess ? "成功" : `失败,原因:${publishResult.msg}`}${task.debug ? ` ${http.proxyInfo}` : ""}`;
24261
- const data = isSuccess ? publishResult.data?.id || "" : "";
24262
- if (!isSuccess) {
24263
- await updateTaskState?.({
24264
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.FAILED,
24265
- error: message
24266
- });
25099
+ const isSuccess = 0 === relationActionRes.code;
25100
+ const message = `用户关系操作${isSuccess ? "成功" : `失败,原因:${relationActionRes.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25101
+ const data = isSuccess ? relationActionRes.data : {
25102
+ fstatus: null
25103
+ };
25104
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
25105
+ };
25106
+ const xiaohongshuWebSearch_xsEncrypt = new Xhshow();
25107
+ const XhsWebSearchParamsSchema = ActionCommonParamsSchema.extend({
25108
+ keyword: schemas_string(),
25109
+ page: schemas_number(),
25110
+ page_size: schemas_number(),
25111
+ sort_type: schemas_enum([
25112
+ "general",
25113
+ "time_descending",
25114
+ "popular_descending"
25115
+ ]),
25116
+ time_filter: schemas_enum([
25117
+ "不限",
25118
+ "一周内"
25119
+ ])
25120
+ });
25121
+ const createSearchId = ()=>{
25122
+ let r = BigInt(Date.now());
25123
+ const o = BigInt(Math.ceil(0x7ffffffe * Math.random()));
25124
+ r <<= BigInt(64);
25125
+ r += o;
25126
+ return r.toString(36);
25127
+ };
25128
+ const xiaohongshuWebSearch = async (_task, params)=>{
25129
+ const headers = {
25130
+ cookie: params.cookies.map((it)=>`${it.name}=${it.value}`).join(";"),
25131
+ referer: "https://www.xiaohongshu.com/",
25132
+ origin: "https://www.xiaohongshu.com/"
25133
+ };
25134
+ const args = [
25135
+ {
25136
+ headers
25137
+ },
25138
+ _task.logger,
25139
+ params.proxyLoc,
25140
+ params.localIP,
25141
+ params.accountId
25142
+ ];
25143
+ const http = new Http(...args);
25144
+ const a1Cookie = params.cookies.find((it)=>"a1" === it.name)?.value;
25145
+ if (!a1Cookie) return {
25146
+ code: 414,
25147
+ message: "账号数据异常,请重新绑定账号后重试。",
25148
+ data: {}
25149
+ };
25150
+ if (!params.keyword || !params.page || !params.page_size || !params.sort_type || !params.time_filter) {
25151
+ if ("general" !== params.sort_type && "time_descending" !== params.sort_type && "popular_descending" !== params.sort_type) return {
25152
+ code: 414,
25153
+ message: "排序类型参数错误,请检查后重试!",
25154
+ data: {}
25155
+ };
25156
+ if ("不限" !== params.time_filter && "一周内" !== params.time_filter) return {
25157
+ code: 414,
25158
+ message: "时间过滤参数错误,请检查后重试!",
25159
+ data: {}
25160
+ };
24267
25161
  return {
24268
25162
  code: 414,
24269
- data,
24270
- message
25163
+ message: "参数缺失,请检查后重试!",
25164
+ data: {}
24271
25165
  };
24272
25166
  }
24273
- await updateTaskState?.({
24274
- state: __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.TaskState.SUCCESS,
24275
- result: {
24276
- response: data
24277
- }
25167
+ const filterPath = "/api/sns/web/v1/search/notes";
25168
+ const filterParams = {
25169
+ ext_flags: [],
25170
+ geo: "",
25171
+ image_formats: [
25172
+ "jpg",
25173
+ "webp",
25174
+ "avif"
25175
+ ],
25176
+ filters: [
25177
+ {
25178
+ tags: [
25179
+ params.sort_type
25180
+ ],
25181
+ type: "sort_type"
25182
+ },
25183
+ {
25184
+ tags: [
25185
+ "不限"
25186
+ ],
25187
+ type: "filter_note_type"
25188
+ },
25189
+ {
25190
+ tags: [
25191
+ params.time_filter
25192
+ ],
25193
+ type: "filter_note_time"
25194
+ },
25195
+ {
25196
+ tags: [
25197
+ "不限"
25198
+ ],
25199
+ type: "filter_note_range"
25200
+ },
25201
+ {
25202
+ tags: [
25203
+ "不限"
25204
+ ],
25205
+ type: "filter_pos_distance"
25206
+ }
25207
+ ],
25208
+ keyword: params.keyword,
25209
+ note_type: 0,
25210
+ page: params.page,
25211
+ page_size: params.page_size,
25212
+ search_id: createSearchId() + (params.sort_type || params.time_filter ? `@${createSearchId()}` : ""),
25213
+ sort: "general"
25214
+ };
25215
+ const recordCookie = params.cookies.reduce((acc, cookie)=>{
25216
+ if (cookie.name && cookie.value) acc[cookie.name] = cookie.value;
25217
+ return acc;
25218
+ }, {});
25219
+ const searchXsHeader = xiaohongshuWebSearch_xsEncrypt.signHeadersPost(filterPath, recordCookie, "xhs-pc-web", filterParams);
25220
+ const res = await http.api({
25221
+ method: "post",
25222
+ url: "https://edith.xiaohongshu.com/api/sns/web/v1/search/notes",
25223
+ data: filterParams,
25224
+ headers: searchXsHeader
25225
+ }, {
25226
+ retries: 3,
25227
+ retryDelay: 20,
25228
+ timeout: 3000
24278
25229
  });
24279
- return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.success)(data, message);
25230
+ const isSuccess = 0 === res.code;
25231
+ const message = `Web笔记搜索${isSuccess ? "成功" : `失败,原因:${res.msg}`}${_task.debug ? ` ${http.proxyInfo}` : ""}`;
25232
+ const data = isSuccess ? res.data : {};
25233
+ return (0, __WEBPACK_EXTERNAL_MODULE__iflyrpa_share_f7afdc8c__.response)(isSuccess ? 0 : 414, message, data);
24280
25234
  };
25235
+ const ttConfigDataSchema = schemas_object({
25236
+ fansNum: schemas_number(),
25237
+ fansNumYesterday: schemas_number().nullable(),
25238
+ readNum: schemas_number(),
25239
+ incomeNum: schemas_number(),
25240
+ incomeNumYesterday: schemas_number().nullable(),
25241
+ showNumYesterday: schemas_number().nullable(),
25242
+ readNumYesterday: schemas_number().nullable(),
25243
+ likeNumYesterday: schemas_number().nullable(),
25244
+ commentNumYesterday: schemas_number().nullable()
25245
+ });
25246
+ const xhsConfigDataSchema = schemas_object({
25247
+ fansNum: schemas_number(),
25248
+ favedNum: schemas_number(),
25249
+ watchNumLastWeek: schemas_number(),
25250
+ likeNumLastWeek: schemas_number(),
25251
+ collectNumLastWeek: schemas_number(),
25252
+ commentNumLastWeek: schemas_number(),
25253
+ fansNumLastWeek: schemas_number(),
25254
+ fansNumYesterday: schemas_number()
25255
+ });
25256
+ const wxConfigDataSchema = schemas_object({
25257
+ fansNum: schemas_number(),
25258
+ fansNumYesterday: schemas_number(),
25259
+ readNumYesterday: schemas_number(),
25260
+ shareNumYesterday: schemas_number()
25261
+ });
25262
+ const bjhConfigDataSchema = schemas_object({
25263
+ fansNum: schemas_number(),
25264
+ fansNumYesterday: schemas_number().nullable(),
25265
+ readNum: schemas_number(),
25266
+ incomeNum: schemas_number(),
25267
+ incomeNumYesterday: schemas_number().nullable(),
25268
+ recommendNumYesterday: schemas_number().nullable(),
25269
+ readNumYesterday: schemas_number().nullable(),
25270
+ likeNumYesterday: schemas_number().nullable(),
25271
+ commentNumYesterday: schemas_number().nullable()
25272
+ });
24281
25273
  const BetaFlag = "HuiwenCanary";
24282
25274
  class Action {
24283
25275
  constructor(task){