@iflyrpa/actions 1.0.2 → 1.0.5

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.cjs CHANGED
@@ -11,8 +11,7 @@ const require$$4 = require('https');
11
11
  const require$$0 = require('url');
12
12
  const require$$6 = require('fs');
13
13
  const require$$4$1 = require('assert');
14
- const require$$1$2 = require('tty');
15
- const require$$0$1 = require('os');
14
+ const require$$0$1 = require('tty');
16
15
  const zlib = require('zlib');
17
16
  const events$1 = require('events');
18
17
 
@@ -29,7 +28,6 @@ const require$$4__default = /*#__PURE__*/_interopDefaultCompat(require$$4);
29
28
  const require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0);
30
29
  const require$$6__default = /*#__PURE__*/_interopDefaultCompat(require$$6);
31
30
  const require$$4__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$4$1);
32
- const require$$1__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$1$2);
33
31
  const require$$0__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$0$1);
34
32
  const zlib__default = /*#__PURE__*/_interopDefaultCompat(zlib);
35
33
 
@@ -14406,7 +14404,7 @@ var followRedirects$1 = {exports: {}};
14406
14404
 
14407
14405
  var src = {exports: {}};
14408
14406
 
14409
- var browser = {exports: {}};
14407
+ var browser$1 = {exports: {}};
14410
14408
 
14411
14409
  /**
14412
14410
  * Helpers.
@@ -14863,11 +14861,11 @@ function requireCommon () {
14863
14861
 
14864
14862
  /* eslint-env browser */
14865
14863
 
14866
- var hasRequiredBrowser;
14864
+ var hasRequiredBrowser$1;
14867
14865
 
14868
- function requireBrowser () {
14869
- if (hasRequiredBrowser) return browser.exports;
14870
- hasRequiredBrowser = 1;
14866
+ function requireBrowser$1 () {
14867
+ if (hasRequiredBrowser$1) return browser$1.exports;
14868
+ hasRequiredBrowser$1 = 1;
14871
14869
  (function (module, exports) {
14872
14870
  /**
14873
14871
  * This is the web browser implementation of `debug()`.
@@ -15138,169 +15136,43 @@ function requireBrowser () {
15138
15136
  return '[UnexpectedJSONParseError]: ' + error.message;
15139
15137
  }
15140
15138
  };
15141
- } (browser, browser.exports));
15142
- return browser.exports;
15139
+ } (browser$1, browser$1.exports));
15140
+ return browser$1.exports;
15143
15141
  }
15144
15142
 
15145
15143
  var node = {exports: {}};
15146
15144
 
15147
- var hasFlag;
15148
- var hasRequiredHasFlag;
15149
-
15150
- function requireHasFlag () {
15151
- if (hasRequiredHasFlag) return hasFlag;
15152
- hasRequiredHasFlag = 1;
15153
-
15154
- hasFlag = (flag, argv = process.argv) => {
15155
- const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
15156
- const position = argv.indexOf(prefix + flag);
15157
- const terminatorPosition = argv.indexOf('--');
15158
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
15159
- };
15160
- return hasFlag;
15161
- }
15162
-
15163
- var supportsColor_1;
15164
- var hasRequiredSupportsColor;
15165
-
15166
- function requireSupportsColor () {
15167
- if (hasRequiredSupportsColor) return supportsColor_1;
15168
- hasRequiredSupportsColor = 1;
15169
- const os = require$$0__default$1;
15170
- const tty = require$$1__default$2;
15171
- const hasFlag = requireHasFlag();
15172
-
15173
- const {env} = process;
15174
-
15175
- let forceColor;
15176
- if (hasFlag('no-color') ||
15177
- hasFlag('no-colors') ||
15178
- hasFlag('color=false') ||
15179
- hasFlag('color=never')) {
15180
- forceColor = 0;
15181
- } else if (hasFlag('color') ||
15182
- hasFlag('colors') ||
15183
- hasFlag('color=true') ||
15184
- hasFlag('color=always')) {
15185
- forceColor = 1;
15186
- }
15187
-
15188
- if ('FORCE_COLOR' in env) {
15189
- if (env.FORCE_COLOR === 'true') {
15190
- forceColor = 1;
15191
- } else if (env.FORCE_COLOR === 'false') {
15192
- forceColor = 0;
15193
- } else {
15194
- forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
15195
- }
15196
- }
15197
-
15198
- function translateLevel(level) {
15199
- if (level === 0) {
15200
- return false;
15201
- }
15202
-
15203
- return {
15204
- level,
15205
- hasBasic: true,
15206
- has256: level >= 2,
15207
- has16m: level >= 3
15208
- };
15209
- }
15210
-
15211
- function supportsColor(haveStream, streamIsTTY) {
15212
- if (forceColor === 0) {
15213
- return 0;
15214
- }
15215
-
15216
- if (hasFlag('color=16m') ||
15217
- hasFlag('color=full') ||
15218
- hasFlag('color=truecolor')) {
15219
- return 3;
15220
- }
15221
-
15222
- if (hasFlag('color=256')) {
15223
- return 2;
15224
- }
15225
-
15226
- if (haveStream && !streamIsTTY && forceColor === undefined) {
15227
- return 0;
15228
- }
15229
-
15230
- const min = forceColor || 0;
15231
-
15232
- if (env.TERM === 'dumb') {
15233
- return min;
15234
- }
15235
-
15236
- if (process.platform === 'win32') {
15237
- // Windows 10 build 10586 is the first Windows release that supports 256 colors.
15238
- // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
15239
- const osRelease = os.release().split('.');
15240
- if (
15241
- Number(osRelease[0]) >= 10 &&
15242
- Number(osRelease[2]) >= 10586
15243
- ) {
15244
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
15245
- }
15246
-
15247
- return 1;
15248
- }
15249
-
15250
- if ('CI' in env) {
15251
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
15252
- return 1;
15253
- }
15254
-
15255
- return min;
15256
- }
15257
-
15258
- if ('TEAMCITY_VERSION' in env) {
15259
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
15260
- }
15261
-
15262
- if (env.COLORTERM === 'truecolor') {
15263
- return 3;
15264
- }
15265
-
15266
- if ('TERM_PROGRAM' in env) {
15267
- const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
15145
+ /* eslint-env browser */
15268
15146
 
15269
- switch (env.TERM_PROGRAM) {
15270
- case 'iTerm.app':
15271
- return version >= 3 ? 3 : 2;
15272
- case 'Apple_Terminal':
15273
- return 2;
15274
- // No default
15275
- }
15276
- }
15147
+ var browser;
15148
+ var hasRequiredBrowser;
15277
15149
 
15278
- if (/-256(color)?$/i.test(env.TERM)) {
15279
- return 2;
15280
- }
15150
+ function requireBrowser () {
15151
+ if (hasRequiredBrowser) return browser;
15152
+ hasRequiredBrowser = 1;
15281
15153
 
15282
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
15283
- return 1;
15284
- }
15154
+ function getChromeVersion() {
15155
+ const matches = /(Chrome|Chromium)\/(?<chromeVersion>\d+)\./.exec(navigator.userAgent);
15285
15156
 
15286
- if ('COLORTERM' in env) {
15287
- return 1;
15157
+ if (!matches) {
15158
+ return;
15288
15159
  }
15289
15160
 
15290
- return min;
15161
+ return Number.parseInt(matches.groups.chromeVersion, 10);
15291
15162
  }
15292
15163
 
15293
- function getSupportLevel(stream) {
15294
- const level = supportsColor(stream, stream && stream.isTTY);
15295
- return translateLevel(level);
15296
- }
15164
+ const colorSupport = getChromeVersion() >= 69 ? {
15165
+ level: 1,
15166
+ hasBasic: true,
15167
+ has256: false,
15168
+ has16m: false
15169
+ } : false;
15297
15170
 
15298
- supportsColor_1 = {
15299
- supportsColor: getSupportLevel,
15300
- stdout: translateLevel(supportsColor(true, tty.isatty(1))),
15301
- stderr: translateLevel(supportsColor(true, tty.isatty(2)))
15171
+ browser = {
15172
+ stdout: colorSupport,
15173
+ stderr: colorSupport
15302
15174
  };
15303
- return supportsColor_1;
15175
+ return browser;
15304
15176
  }
15305
15177
 
15306
15178
  /**
@@ -15313,7 +15185,7 @@ function requireNode () {
15313
15185
  if (hasRequiredNode) return node.exports;
15314
15186
  hasRequiredNode = 1;
15315
15187
  (function (module, exports) {
15316
- const tty = require$$1__default$2;
15188
+ const tty = require$$0__default$1;
15317
15189
  const util = require$$1__default;
15318
15190
 
15319
15191
  /**
@@ -15340,7 +15212,7 @@ function requireNode () {
15340
15212
  try {
15341
15213
  // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
15342
15214
  // eslint-disable-next-line import/no-extraneous-dependencies
15343
- const supportsColor = requireSupportsColor();
15215
+ const supportsColor = requireBrowser();
15344
15216
 
15345
15217
  if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
15346
15218
  exports.colors = [
@@ -15587,7 +15459,7 @@ function requireSrc () {
15587
15459
  if (hasRequiredSrc) return src.exports;
15588
15460
  hasRequiredSrc = 1;
15589
15461
  if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
15590
- src.exports = requireBrowser();
15462
+ src.exports = requireBrowser$1();
15591
15463
  } else {
15592
15464
  src.exports = requireNode();
15593
15465
  }
@@ -21798,7 +21670,8 @@ const mockAction$5 = async (task, params) => {
21798
21670
  defaultErrorMsg: "\u83B7\u53D6\u767E\u5BB6\u53F7appid\u63A5\u53E3\u62A5\u9519"
21799
21671
  });
21800
21672
  const appId = appIdInfo.data.data.user.app_id;
21801
- const uploadImages = async (images) => {
21673
+ const uploadImages = async (_images) => {
21674
+ const images = _images.filter((url) => !!url && url.trim() !== "");
21802
21675
  const localImages = await Promise.all(
21803
21676
  images.map((url) => {
21804
21677
  const fileName = getFilenameFromUrl(url);
@@ -21990,6 +21863,41 @@ const searchToutiaoTopicList = async (task, params) => {
21990
21863
  }
21991
21864
  };
21992
21865
 
21866
+ const searchXiaohongshuLocation = async (task, params) => {
21867
+ task.logger.info("\u641C\u7D22\u5C0F\u7EA2\u4E66\u5730\u5740");
21868
+ const api = axios$1.create({
21869
+ headers: {
21870
+ cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
21871
+ referer: "https://creator.xiaohongshu.com",
21872
+ origin: "https://creator.xiaohongshu.com"
21873
+ }
21874
+ });
21875
+ try {
21876
+ const { data } = await api({
21877
+ method: "post",
21878
+ url: "https://edith.xiaohongshu.com/web_api/sns/v1/local/poi/creator/search",
21879
+ data: {
21880
+ keyword: params.searchValue,
21881
+ latitude: params.latitude ?? 0,
21882
+ longitude: params.longitude ?? 0,
21883
+ page: params.page ?? 1,
21884
+ size: params.size ?? 10,
21885
+ source: "WEB",
21886
+ type: 3
21887
+ }
21888
+ });
21889
+ if (data.code === 0) {
21890
+ return data.data.poi_list.map((it) => ({
21891
+ label: it.name,
21892
+ value: it.poi_id
21893
+ }));
21894
+ }
21895
+ return [];
21896
+ } catch (error) {
21897
+ return [];
21898
+ }
21899
+ };
21900
+
21993
21901
  const COVER_TYPE = {
21994
21902
  no: 1,
21995
21903
  single: 2,
@@ -22574,10 +22482,6 @@ const mockAction = async (task, params) => {
22574
22482
  return Promise.reject();
22575
22483
  };
22576
22484
 
22577
- const visibleRangeTexts = {
22578
- public: "\u516C\u5F00",
22579
- private: "\u79C1\u5BC6"
22580
- };
22581
22485
  const rpaAction = async (task, params) => {
22582
22486
  const commonCookies = {
22583
22487
  path: "/",
@@ -22597,9 +22501,7 @@ const rpaAction = async (task, params) => {
22597
22501
  const instance = typeof selector === "string" ? page.locator(selector) : selector;
22598
22502
  await instance.click();
22599
22503
  await instance.locator("input").fill(address);
22600
- const poperInstance = page.locator(
22601
- '.d-popover:not([style*="display: none"]) .d-options .d-grid-item'
22602
- );
22504
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
22603
22505
  await poperInstance.first().waitFor();
22604
22506
  await poperInstance.first().click();
22605
22507
  };
@@ -22609,6 +22511,28 @@ const rpaAction = async (task, params) => {
22609
22511
  await instance.fill(date);
22610
22512
  await instance.blur();
22611
22513
  };
22514
+ const getPoperInstance = async () => {
22515
+ await page.waitForTimeout(500);
22516
+ const elements = page.locator(".d-popover");
22517
+ const count = await elements.count();
22518
+ const visibleElements = [];
22519
+ for (let i = 0; i < count; i++) {
22520
+ const element = elements.nth(i);
22521
+ const style = await element.getAttribute("style");
22522
+ if (style && !style.includes("display: none")) {
22523
+ visibleElements.push(element);
22524
+ }
22525
+ }
22526
+ if (visibleElements.length > 0) {
22527
+ return visibleElements[visibleElements.length - 1];
22528
+ }
22529
+ throw new Error("\u672A\u627E\u5230 popover \u5F39\u7A97");
22530
+ };
22531
+ const getDialogInstance = async () => {
22532
+ await page.waitForTimeout(1e3);
22533
+ const elements = page.locator(".el-dialog");
22534
+ return elements.last();
22535
+ };
22612
22536
  await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
22613
22537
  throw new Error("\u767B\u5F55\u5931\u8D25");
22614
22538
  });
@@ -22631,7 +22555,7 @@ const rpaAction = async (task, params) => {
22631
22555
  const titleInstance = page.locator(".input.titleInput input");
22632
22556
  await titleInstance.click();
22633
22557
  await titleInstance.fill(params.title);
22634
- const descInstance = page.locator("#post-textarea");
22558
+ const descInstance = page.locator(".editor-container #quillEditor .ql-editor");
22635
22559
  await descInstance.click();
22636
22560
  await descInstance.fill(params.content);
22637
22561
  const container = page.locator(".creator-container .content .scroll-content");
@@ -22644,43 +22568,34 @@ const rpaAction = async (task, params) => {
22644
22568
  );
22645
22569
  }
22646
22570
  if (params.selfDeclaration) {
22647
- await page.locator(".declaration-wrapper").click();
22648
- const selfDeclarationInstance = page.locator(
22649
- ".el-popper[aria-hidden=false] ul li[role=menuitem]"
22650
- );
22571
+ await page.locator(".media-settings .flexbox").filter({ hasText: "\u81EA\u4E3B\u58F0\u660E" }).locator(".d-select-wrapper").click();
22572
+ const poperInstance = await getPoperInstance();
22573
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
22651
22574
  if (params.selfDeclaration.type === "fictional-rendition") {
22652
22575
  await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
22653
22576
  } else if (params.selfDeclaration.type === "ai-generated") {
22654
22577
  await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
22655
22578
  } else if (params.selfDeclaration.type === "source-statement") {
22656
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
22657
- const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
22579
+ await selfDeclarationInstance.filter({ hasText: /内容来源声明/ }).click();
22580
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
22658
22581
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
22659
22582
  if (params.selfDeclaration.childType === "self-labeling") {
22660
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
22583
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u5728\u6B63\u6587\u4E2D\u81EA\u4E3B\u6807\u6CE8" }).click();
22661
22584
  } else if (params.selfDeclaration.childType === "self-shooting") {
22662
22585
  const { shootingDate, shootingLocation } = params.selfDeclaration;
22663
22586
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
22664
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
22665
- await selfShootingPopup.waitFor();
22587
+ const selfShootingPopup = await getDialogInstance();
22666
22588
  const hasCustomContent = shootingDate || shootingLocation;
22667
22589
  if (shootingLocation) {
22668
- await selectAddress(
22669
- selfShootingPopup.locator(".address-input"),
22670
- shootingLocation
22671
- );
22590
+ await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation);
22672
22591
  }
22673
22592
  if (shootingDate) {
22674
- await selectDate(
22675
- selfShootingPopup.locator(".date-picker input"),
22676
- shootingDate
22677
- );
22593
+ await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
22678
22594
  }
22679
22595
  await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
22680
22596
  } else if (params.selfDeclaration.childType === "transshipment") {
22681
22597
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
22682
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
22683
- await selfShootingPopup.waitFor();
22598
+ const selfShootingPopup = await getDialogInstance();
22684
22599
  const sourceMedia = params.selfDeclaration.sourceMedia;
22685
22600
  if (sourceMedia) {
22686
22601
  await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
@@ -22689,14 +22604,17 @@ const rpaAction = async (task, params) => {
22689
22604
  }
22690
22605
  }
22691
22606
  }
22692
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
22693
- await publicLabelInstance.click();
22607
+ if (params.visibleRange === "private") {
22608
+ await page.locator(".media-settings .flexbox").filter({ hasText: "\u53EF\u89C1\u8303\u56F4" }).locator(".d-select-wrapper").click();
22609
+ const poperInstance = await getPoperInstance();
22610
+ await poperInstance.locator(".d-options .custom-option").filter({ hasText: "\u4EC5\u81EA\u5DF1\u53EF\u89C1" }).click();
22611
+ }
22694
22612
  const releaseTimeInstance = page.locator("label").filter({ hasText: params.isImmediatelyPublish ? "\u7ACB\u5373\u53D1\u5E03" : "\u5B9A\u65F6\u53D1\u5E03" });
22695
22613
  await releaseTimeInstance.click();
22696
22614
  if (params.scheduledPublish) {
22697
22615
  await selectDate(".date-picker input", params.scheduledPublish);
22698
22616
  }
22699
- const response = await new Promise((resolve) => {
22617
+ await new Promise((resolve) => {
22700
22618
  const handleResponse = async (response2) => {
22701
22619
  if (response2.url().includes("/web_api/sns/v2/note")) {
22702
22620
  const jsonResponse = await response2.json();
@@ -22708,7 +22626,7 @@ const rpaAction = async (task, params) => {
22708
22626
  page.locator(".submit .publishBtn").click();
22709
22627
  });
22710
22628
  await page.close();
22711
- return response;
22629
+ return "response";
22712
22630
  };
22713
22631
 
22714
22632
  const executeAction = (task, params) => {
@@ -22753,6 +22671,10 @@ class Action {
22753
22671
  xiaohongshuPublish(params) {
22754
22672
  return xiaohongshuPublish(this.task, params);
22755
22673
  }
22674
+ // 搜索小红书地址
22675
+ searchXiaohongshuLocation(params) {
22676
+ return searchXiaohongshuLocation(this.task, params);
22677
+ }
22756
22678
  // 小绿书发布
22757
22679
  weixinmpPublish(params) {
22758
22680
  return weixinmpPublish(this.task, params);
package/dist/index.mjs CHANGED
@@ -9,8 +9,7 @@ import require$$4 from 'https';
9
9
  import require$$0 from 'url';
10
10
  import require$$6 from 'fs';
11
11
  import require$$4$1 from 'assert';
12
- import require$$1$2 from 'tty';
13
- import require$$0$1 from 'os';
12
+ import require$$0$1 from 'tty';
14
13
  import zlib from 'zlib';
15
14
  import { EventEmitter } from 'events';
16
15
 
@@ -14387,7 +14386,7 @@ var followRedirects$1 = {exports: {}};
14387
14386
 
14388
14387
  var src = {exports: {}};
14389
14388
 
14390
- var browser = {exports: {}};
14389
+ var browser$1 = {exports: {}};
14391
14390
 
14392
14391
  /**
14393
14392
  * Helpers.
@@ -14844,11 +14843,11 @@ function requireCommon () {
14844
14843
 
14845
14844
  /* eslint-env browser */
14846
14845
 
14847
- var hasRequiredBrowser;
14846
+ var hasRequiredBrowser$1;
14848
14847
 
14849
- function requireBrowser () {
14850
- if (hasRequiredBrowser) return browser.exports;
14851
- hasRequiredBrowser = 1;
14848
+ function requireBrowser$1 () {
14849
+ if (hasRequiredBrowser$1) return browser$1.exports;
14850
+ hasRequiredBrowser$1 = 1;
14852
14851
  (function (module, exports) {
14853
14852
  /**
14854
14853
  * This is the web browser implementation of `debug()`.
@@ -15119,169 +15118,43 @@ function requireBrowser () {
15119
15118
  return '[UnexpectedJSONParseError]: ' + error.message;
15120
15119
  }
15121
15120
  };
15122
- } (browser, browser.exports));
15123
- return browser.exports;
15121
+ } (browser$1, browser$1.exports));
15122
+ return browser$1.exports;
15124
15123
  }
15125
15124
 
15126
15125
  var node = {exports: {}};
15127
15126
 
15128
- var hasFlag;
15129
- var hasRequiredHasFlag;
15130
-
15131
- function requireHasFlag () {
15132
- if (hasRequiredHasFlag) return hasFlag;
15133
- hasRequiredHasFlag = 1;
15134
-
15135
- hasFlag = (flag, argv = process.argv) => {
15136
- const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
15137
- const position = argv.indexOf(prefix + flag);
15138
- const terminatorPosition = argv.indexOf('--');
15139
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
15140
- };
15141
- return hasFlag;
15142
- }
15143
-
15144
- var supportsColor_1;
15145
- var hasRequiredSupportsColor;
15146
-
15147
- function requireSupportsColor () {
15148
- if (hasRequiredSupportsColor) return supportsColor_1;
15149
- hasRequiredSupportsColor = 1;
15150
- const os = require$$0$1;
15151
- const tty = require$$1$2;
15152
- const hasFlag = requireHasFlag();
15153
-
15154
- const {env} = process;
15155
-
15156
- let forceColor;
15157
- if (hasFlag('no-color') ||
15158
- hasFlag('no-colors') ||
15159
- hasFlag('color=false') ||
15160
- hasFlag('color=never')) {
15161
- forceColor = 0;
15162
- } else if (hasFlag('color') ||
15163
- hasFlag('colors') ||
15164
- hasFlag('color=true') ||
15165
- hasFlag('color=always')) {
15166
- forceColor = 1;
15167
- }
15168
-
15169
- if ('FORCE_COLOR' in env) {
15170
- if (env.FORCE_COLOR === 'true') {
15171
- forceColor = 1;
15172
- } else if (env.FORCE_COLOR === 'false') {
15173
- forceColor = 0;
15174
- } else {
15175
- forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
15176
- }
15177
- }
15178
-
15179
- function translateLevel(level) {
15180
- if (level === 0) {
15181
- return false;
15182
- }
15183
-
15184
- return {
15185
- level,
15186
- hasBasic: true,
15187
- has256: level >= 2,
15188
- has16m: level >= 3
15189
- };
15190
- }
15191
-
15192
- function supportsColor(haveStream, streamIsTTY) {
15193
- if (forceColor === 0) {
15194
- return 0;
15195
- }
15196
-
15197
- if (hasFlag('color=16m') ||
15198
- hasFlag('color=full') ||
15199
- hasFlag('color=truecolor')) {
15200
- return 3;
15201
- }
15202
-
15203
- if (hasFlag('color=256')) {
15204
- return 2;
15205
- }
15206
-
15207
- if (haveStream && !streamIsTTY && forceColor === undefined) {
15208
- return 0;
15209
- }
15210
-
15211
- const min = forceColor || 0;
15212
-
15213
- if (env.TERM === 'dumb') {
15214
- return min;
15215
- }
15216
-
15217
- if (process.platform === 'win32') {
15218
- // Windows 10 build 10586 is the first Windows release that supports 256 colors.
15219
- // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
15220
- const osRelease = os.release().split('.');
15221
- if (
15222
- Number(osRelease[0]) >= 10 &&
15223
- Number(osRelease[2]) >= 10586
15224
- ) {
15225
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
15226
- }
15227
-
15228
- return 1;
15229
- }
15230
-
15231
- if ('CI' in env) {
15232
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
15233
- return 1;
15234
- }
15235
-
15236
- return min;
15237
- }
15238
-
15239
- if ('TEAMCITY_VERSION' in env) {
15240
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
15241
- }
15242
-
15243
- if (env.COLORTERM === 'truecolor') {
15244
- return 3;
15245
- }
15246
-
15247
- if ('TERM_PROGRAM' in env) {
15248
- const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
15127
+ /* eslint-env browser */
15249
15128
 
15250
- switch (env.TERM_PROGRAM) {
15251
- case 'iTerm.app':
15252
- return version >= 3 ? 3 : 2;
15253
- case 'Apple_Terminal':
15254
- return 2;
15255
- // No default
15256
- }
15257
- }
15129
+ var browser;
15130
+ var hasRequiredBrowser;
15258
15131
 
15259
- if (/-256(color)?$/i.test(env.TERM)) {
15260
- return 2;
15261
- }
15132
+ function requireBrowser () {
15133
+ if (hasRequiredBrowser) return browser;
15134
+ hasRequiredBrowser = 1;
15262
15135
 
15263
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
15264
- return 1;
15265
- }
15136
+ function getChromeVersion() {
15137
+ const matches = /(Chrome|Chromium)\/(?<chromeVersion>\d+)\./.exec(navigator.userAgent);
15266
15138
 
15267
- if ('COLORTERM' in env) {
15268
- return 1;
15139
+ if (!matches) {
15140
+ return;
15269
15141
  }
15270
15142
 
15271
- return min;
15143
+ return Number.parseInt(matches.groups.chromeVersion, 10);
15272
15144
  }
15273
15145
 
15274
- function getSupportLevel(stream) {
15275
- const level = supportsColor(stream, stream && stream.isTTY);
15276
- return translateLevel(level);
15277
- }
15146
+ const colorSupport = getChromeVersion() >= 69 ? {
15147
+ level: 1,
15148
+ hasBasic: true,
15149
+ has256: false,
15150
+ has16m: false
15151
+ } : false;
15278
15152
 
15279
- supportsColor_1 = {
15280
- supportsColor: getSupportLevel,
15281
- stdout: translateLevel(supportsColor(true, tty.isatty(1))),
15282
- stderr: translateLevel(supportsColor(true, tty.isatty(2)))
15153
+ browser = {
15154
+ stdout: colorSupport,
15155
+ stderr: colorSupport
15283
15156
  };
15284
- return supportsColor_1;
15157
+ return browser;
15285
15158
  }
15286
15159
 
15287
15160
  /**
@@ -15294,7 +15167,7 @@ function requireNode () {
15294
15167
  if (hasRequiredNode) return node.exports;
15295
15168
  hasRequiredNode = 1;
15296
15169
  (function (module, exports) {
15297
- const tty = require$$1$2;
15170
+ const tty = require$$0$1;
15298
15171
  const util = require$$1;
15299
15172
 
15300
15173
  /**
@@ -15321,7 +15194,7 @@ function requireNode () {
15321
15194
  try {
15322
15195
  // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
15323
15196
  // eslint-disable-next-line import/no-extraneous-dependencies
15324
- const supportsColor = requireSupportsColor();
15197
+ const supportsColor = requireBrowser();
15325
15198
 
15326
15199
  if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
15327
15200
  exports.colors = [
@@ -15568,7 +15441,7 @@ function requireSrc () {
15568
15441
  if (hasRequiredSrc) return src.exports;
15569
15442
  hasRequiredSrc = 1;
15570
15443
  if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
15571
- src.exports = requireBrowser();
15444
+ src.exports = requireBrowser$1();
15572
15445
  } else {
15573
15446
  src.exports = requireNode();
15574
15447
  }
@@ -21779,7 +21652,8 @@ const mockAction$5 = async (task, params) => {
21779
21652
  defaultErrorMsg: "\u83B7\u53D6\u767E\u5BB6\u53F7appid\u63A5\u53E3\u62A5\u9519"
21780
21653
  });
21781
21654
  const appId = appIdInfo.data.data.user.app_id;
21782
- const uploadImages = async (images) => {
21655
+ const uploadImages = async (_images) => {
21656
+ const images = _images.filter((url) => !!url && url.trim() !== "");
21783
21657
  const localImages = await Promise.all(
21784
21658
  images.map((url) => {
21785
21659
  const fileName = getFilenameFromUrl(url);
@@ -21971,6 +21845,41 @@ const searchToutiaoTopicList = async (task, params) => {
21971
21845
  }
21972
21846
  };
21973
21847
 
21848
+ const searchXiaohongshuLocation = async (task, params) => {
21849
+ task.logger.info("\u641C\u7D22\u5C0F\u7EA2\u4E66\u5730\u5740");
21850
+ const api = axios$1.create({
21851
+ headers: {
21852
+ cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
21853
+ referer: "https://creator.xiaohongshu.com",
21854
+ origin: "https://creator.xiaohongshu.com"
21855
+ }
21856
+ });
21857
+ try {
21858
+ const { data } = await api({
21859
+ method: "post",
21860
+ url: "https://edith.xiaohongshu.com/web_api/sns/v1/local/poi/creator/search",
21861
+ data: {
21862
+ keyword: params.searchValue,
21863
+ latitude: params.latitude ?? 0,
21864
+ longitude: params.longitude ?? 0,
21865
+ page: params.page ?? 1,
21866
+ size: params.size ?? 10,
21867
+ source: "WEB",
21868
+ type: 3
21869
+ }
21870
+ });
21871
+ if (data.code === 0) {
21872
+ return data.data.poi_list.map((it) => ({
21873
+ label: it.name,
21874
+ value: it.poi_id
21875
+ }));
21876
+ }
21877
+ return [];
21878
+ } catch (error) {
21879
+ return [];
21880
+ }
21881
+ };
21882
+
21974
21883
  const COVER_TYPE = {
21975
21884
  no: 1,
21976
21885
  single: 2,
@@ -22555,10 +22464,6 @@ const mockAction = async (task, params) => {
22555
22464
  return Promise.reject();
22556
22465
  };
22557
22466
 
22558
- const visibleRangeTexts = {
22559
- public: "\u516C\u5F00",
22560
- private: "\u79C1\u5BC6"
22561
- };
22562
22467
  const rpaAction = async (task, params) => {
22563
22468
  const commonCookies = {
22564
22469
  path: "/",
@@ -22578,9 +22483,7 @@ const rpaAction = async (task, params) => {
22578
22483
  const instance = typeof selector === "string" ? page.locator(selector) : selector;
22579
22484
  await instance.click();
22580
22485
  await instance.locator("input").fill(address);
22581
- const poperInstance = page.locator(
22582
- '.d-popover:not([style*="display: none"]) .d-options .d-grid-item'
22583
- );
22486
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
22584
22487
  await poperInstance.first().waitFor();
22585
22488
  await poperInstance.first().click();
22586
22489
  };
@@ -22590,6 +22493,28 @@ const rpaAction = async (task, params) => {
22590
22493
  await instance.fill(date);
22591
22494
  await instance.blur();
22592
22495
  };
22496
+ const getPoperInstance = async () => {
22497
+ await page.waitForTimeout(500);
22498
+ const elements = page.locator(".d-popover");
22499
+ const count = await elements.count();
22500
+ const visibleElements = [];
22501
+ for (let i = 0; i < count; i++) {
22502
+ const element = elements.nth(i);
22503
+ const style = await element.getAttribute("style");
22504
+ if (style && !style.includes("display: none")) {
22505
+ visibleElements.push(element);
22506
+ }
22507
+ }
22508
+ if (visibleElements.length > 0) {
22509
+ return visibleElements[visibleElements.length - 1];
22510
+ }
22511
+ throw new Error("\u672A\u627E\u5230 popover \u5F39\u7A97");
22512
+ };
22513
+ const getDialogInstance = async () => {
22514
+ await page.waitForTimeout(1e3);
22515
+ const elements = page.locator(".el-dialog");
22516
+ return elements.last();
22517
+ };
22593
22518
  await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
22594
22519
  throw new Error("\u767B\u5F55\u5931\u8D25");
22595
22520
  });
@@ -22612,7 +22537,7 @@ const rpaAction = async (task, params) => {
22612
22537
  const titleInstance = page.locator(".input.titleInput input");
22613
22538
  await titleInstance.click();
22614
22539
  await titleInstance.fill(params.title);
22615
- const descInstance = page.locator("#post-textarea");
22540
+ const descInstance = page.locator(".editor-container #quillEditor .ql-editor");
22616
22541
  await descInstance.click();
22617
22542
  await descInstance.fill(params.content);
22618
22543
  const container = page.locator(".creator-container .content .scroll-content");
@@ -22625,43 +22550,34 @@ const rpaAction = async (task, params) => {
22625
22550
  );
22626
22551
  }
22627
22552
  if (params.selfDeclaration) {
22628
- await page.locator(".declaration-wrapper").click();
22629
- const selfDeclarationInstance = page.locator(
22630
- ".el-popper[aria-hidden=false] ul li[role=menuitem]"
22631
- );
22553
+ await page.locator(".media-settings .flexbox").filter({ hasText: "\u81EA\u4E3B\u58F0\u660E" }).locator(".d-select-wrapper").click();
22554
+ const poperInstance = await getPoperInstance();
22555
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
22632
22556
  if (params.selfDeclaration.type === "fictional-rendition") {
22633
22557
  await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
22634
22558
  } else if (params.selfDeclaration.type === "ai-generated") {
22635
22559
  await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
22636
22560
  } else if (params.selfDeclaration.type === "source-statement") {
22637
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
22638
- const selfDeclarationSecondaryMenuInstance = page.locator(".el-popper[aria-hidden=false] .el-cascader-menu").nth(1).locator("ul li[role=menuitem]");
22561
+ await selfDeclarationInstance.filter({ hasText: /内容来源声明/ }).click();
22562
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
22639
22563
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
22640
22564
  if (params.selfDeclaration.childType === "self-labeling") {
22641
- await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u81EA\u4E3B\u6807\u6CE8" }).click();
22565
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u5728\u6B63\u6587\u4E2D\u81EA\u4E3B\u6807\u6CE8" }).click();
22642
22566
  } else if (params.selfDeclaration.childType === "self-shooting") {
22643
22567
  const { shootingDate, shootingLocation } = params.selfDeclaration;
22644
22568
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
22645
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
22646
- await selfShootingPopup.waitFor();
22569
+ const selfShootingPopup = await getDialogInstance();
22647
22570
  const hasCustomContent = shootingDate || shootingLocation;
22648
22571
  if (shootingLocation) {
22649
- await selectAddress(
22650
- selfShootingPopup.locator(".address-input"),
22651
- shootingLocation
22652
- );
22572
+ await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation);
22653
22573
  }
22654
22574
  if (shootingDate) {
22655
- await selectDate(
22656
- selfShootingPopup.locator(".date-picker input"),
22657
- shootingDate
22658
- );
22575
+ await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
22659
22576
  }
22660
22577
  await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
22661
22578
  } else if (params.selfDeclaration.childType === "transshipment") {
22662
22579
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
22663
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
22664
- await selfShootingPopup.waitFor();
22580
+ const selfShootingPopup = await getDialogInstance();
22665
22581
  const sourceMedia = params.selfDeclaration.sourceMedia;
22666
22582
  if (sourceMedia) {
22667
22583
  await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
@@ -22670,14 +22586,17 @@ const rpaAction = async (task, params) => {
22670
22586
  }
22671
22587
  }
22672
22588
  }
22673
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
22674
- await publicLabelInstance.click();
22589
+ if (params.visibleRange === "private") {
22590
+ await page.locator(".media-settings .flexbox").filter({ hasText: "\u53EF\u89C1\u8303\u56F4" }).locator(".d-select-wrapper").click();
22591
+ const poperInstance = await getPoperInstance();
22592
+ await poperInstance.locator(".d-options .custom-option").filter({ hasText: "\u4EC5\u81EA\u5DF1\u53EF\u89C1" }).click();
22593
+ }
22675
22594
  const releaseTimeInstance = page.locator("label").filter({ hasText: params.isImmediatelyPublish ? "\u7ACB\u5373\u53D1\u5E03" : "\u5B9A\u65F6\u53D1\u5E03" });
22676
22595
  await releaseTimeInstance.click();
22677
22596
  if (params.scheduledPublish) {
22678
22597
  await selectDate(".date-picker input", params.scheduledPublish);
22679
22598
  }
22680
- const response = await new Promise((resolve) => {
22599
+ await new Promise((resolve) => {
22681
22600
  const handleResponse = async (response2) => {
22682
22601
  if (response2.url().includes("/web_api/sns/v2/note")) {
22683
22602
  const jsonResponse = await response2.json();
@@ -22689,7 +22608,7 @@ const rpaAction = async (task, params) => {
22689
22608
  page.locator(".submit .publishBtn").click();
22690
22609
  });
22691
22610
  await page.close();
22692
- return response;
22611
+ return "response";
22693
22612
  };
22694
22613
 
22695
22614
  const executeAction = (task, params) => {
@@ -22734,6 +22653,10 @@ class Action {
22734
22653
  xiaohongshuPublish(params) {
22735
22654
  return xiaohongshuPublish(this.task, params);
22736
22655
  }
22656
+ // 搜索小红书地址
22657
+ searchXiaohongshuLocation(params) {
22658
+ return searchXiaohongshuLocation(this.task, params);
22659
+ }
22737
22660
  // 小绿书发布
22738
22661
  weixinmpPublish(params) {
22739
22662
  return weixinmpPublish(this.task, params);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iflyrpa/actions",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -81,7 +81,10 @@ export const mockAction: PublishAction = async (task, params) => {
81
81
 
82
82
  const appId = appIdInfo.data.data.user.app_id;
83
83
 
84
- const uploadImages = async (images: string[]) => {
84
+ const uploadImages = async (_images: string[]) => {
85
+ // 过滤掉空字符串
86
+ const images = _images.filter((url) => !!url && url.trim() !== "");
87
+
85
88
  // 下载图片到本地
86
89
  const localImages = await Promise.all(
87
90
  images.map((url) => {
@@ -0,0 +1,54 @@
1
+ import axios from "axios";
2
+
3
+ import type { CommonAction, CookiesSetDetails } from "@iflyrpa/share";
4
+ import type { ActiomCommonParams, Xiaohongshu } from "../../types";
5
+
6
+ export interface searchXiaohongshuLocationParams extends Omit<ActiomCommonParams, "cookies"> {
7
+ cookies: Partial<CookiesSetDetails>[];
8
+ searchValue: string;
9
+ latitude?: number;
10
+ longitude?: number;
11
+ size?: number;
12
+ page?: number;
13
+ }
14
+
15
+ export type PublishAction = CommonAction<searchXiaohongshuLocationParams, { label: string; value: string }[]>;
16
+
17
+ export const searchXiaohongshuLocation: PublishAction = async (task, params) => {
18
+ task.logger.info("搜索小红书地址");
19
+
20
+ const api = axios.create({
21
+ headers: {
22
+ cookie: params.cookies.map((it) => `${it.name}=${it.value}`).join(";"),
23
+ referer: "https://creator.xiaohongshu.com",
24
+ origin: "https://creator.xiaohongshu.com",
25
+ },
26
+ });
27
+
28
+ try {
29
+ const { data } = await api<{ code: number; data: { poi_list: Xiaohongshu.Location[] } }>({
30
+ method: "post",
31
+ url: "https://edith.xiaohongshu.com/web_api/sns/v1/local/poi/creator/search",
32
+ data: {
33
+ keyword: params.searchValue,
34
+ latitude: params.latitude ?? 0,
35
+ longitude: params.longitude ?? 0,
36
+ page: params.page ?? 1,
37
+ size: params.size ?? 10,
38
+ source: "WEB",
39
+ type: 3,
40
+ },
41
+ });
42
+
43
+ if (data.code === 0) {
44
+ return data.data.poi_list.map((it) => ({
45
+ label: it.name,
46
+ value: it.poi_id,
47
+ }));
48
+ }
49
+
50
+ return [];
51
+ } catch (error) {
52
+ return [];
53
+ }
54
+ };
@@ -22,8 +22,7 @@ interface SourceStatement {
22
22
 
23
23
  type SelfDeclaration = FictionalRendition | AIGenerated | SourceStatement;
24
24
 
25
- export interface XiaohongshuPublishParams
26
- extends Omit<ActiomCommonParams, "cookies"> {
25
+ export interface XiaohongshuPublishParams extends Omit<ActiomCommonParams, "cookies"> {
27
26
  cookies: Partial<CookiesSetDetails>[];
28
27
  banners: string[]; // 图片
29
28
  title: string; // 标题
@@ -2,15 +2,7 @@ import path from "node:path";
2
2
  import type { CookieMap, Locator, Response } from "@iflyrpa/share";
3
3
  import { downloadImage, getFilenameFromUrl } from "@iflyrpa/share";
4
4
 
5
- import type { PublishAction, XiaohongshuPublishParams } from "./index";
6
-
7
- const visibleRangeTexts: Record<
8
- XiaohongshuPublishParams["visibleRange"],
9
- string
10
- > = {
11
- public: "公开",
12
- private: "私密",
13
- };
5
+ import type { PublishAction } from "./index";
14
6
 
15
7
  export const rpaAction: PublishAction = async (task, params) => {
16
8
  const commonCookies: CookieMap[number] = {
@@ -32,34 +24,58 @@ export const rpaAction: PublishAction = async (task, params) => {
32
24
 
33
25
  // 通用的选择地点
34
26
  const selectAddress = async (selector: Locator, address: string) => {
35
- const instance =
36
- typeof selector === "string" ? page.locator(selector) : selector;
27
+ const instance = typeof selector === "string" ? page.locator(selector) : selector;
37
28
  await instance.click();
38
29
  await instance.locator("input").fill(address);
39
- const poperInstance = page.locator(
40
- '.d-popover:not([style*="display: none"]) .d-options .d-grid-item',
41
- );
30
+ const poperInstance = page.locator('.d-popover:not([style*="display: none"]) .d-options .d-grid-item');
42
31
  await poperInstance.first().waitFor();
43
32
  await poperInstance.first().click();
44
33
  };
34
+
45
35
  // 通用的选择日期
46
36
  const selectDate = async (selector: string | Locator, date: string) => {
47
- const instance =
48
- typeof selector === "string" ? page.locator(selector) : selector;
37
+ const instance = typeof selector === "string" ? page.locator(selector) : selector;
49
38
  await instance.click();
50
39
  await instance.fill(date);
51
40
  await instance.blur();
52
41
  };
53
42
 
43
+ // 查找显示的 popover 弹窗
44
+ const getPoperInstance = async (): Promise<Locator> => {
45
+ await page.waitForTimeout(500);
46
+ const elements = page.locator(".d-popover");
47
+ const count = await elements.count();
48
+ const visibleElements: (typeof elements)[] = [];
49
+
50
+ for (let i = 0; i < count; i++) {
51
+ const element = elements.nth(i);
52
+ const style = await element.getAttribute("style");
53
+ if (style && !style.includes("display: none")) {
54
+ visibleElements.push(element);
55
+ }
56
+ }
57
+
58
+ if (visibleElements.length > 0) {
59
+ return visibleElements[visibleElements.length - 1];
60
+ }
61
+
62
+ throw new Error("未找到 popover 弹窗");
63
+ };
64
+
65
+ // 查找显示的 dialog 弹窗
66
+ const getDialogInstance = async (): Promise<Locator> => {
67
+ await page.waitForTimeout(1000);
68
+ const elements = page.locator(".el-dialog");
69
+ return elements.last();
70
+ };
71
+
54
72
  // 自动化脚本
55
73
  // ----------------------------------------------------------------------------------
56
74
 
57
75
  // 等待登录成功
58
- await page
59
- .waitForSelector("#CreatorPlatform", { state: "visible" })
60
- .catch(() => {
61
- throw new Error("登录失败");
62
- });
76
+ await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
77
+ throw new Error("登录失败");
78
+ });
63
79
 
64
80
  // 跳转到发布页面
65
81
  await page
@@ -98,7 +114,7 @@ export const rpaAction: PublishAction = async (task, params) => {
98
114
  await titleInstance.fill(params.title);
99
115
 
100
116
  // 填写正文
101
- const descInstance = page.locator("#post-textarea");
117
+ const descInstance = page.locator(".editor-container #quillEditor .ql-editor");
102
118
  await descInstance.click();
103
119
  await descInstance.fill(params.content);
104
120
 
@@ -110,67 +126,42 @@ export const rpaAction: PublishAction = async (task, params) => {
110
126
  if (params.address) {
111
127
  // 填写地点
112
128
  await selectAddress(
113
- page
114
- .locator(".media-extension .address-input")
115
- .filter({ hasText: "添加地点" }),
129
+ page.locator(".media-extension .address-input").filter({ hasText: "添加地点" }),
116
130
  params.address,
117
131
  );
118
132
  }
119
133
 
120
134
  if (params.selfDeclaration) {
121
135
  // 自主声明
122
- await page.locator(".declaration-wrapper").click();
123
- const selfDeclarationInstance = page.locator(
124
- ".el-popper[aria-hidden=false] ul li[role=menuitem]",
125
- );
136
+ await page.locator(".media-settings .flexbox").filter({ hasText: "自主声明" }).locator(".d-select-wrapper").click();
137
+ const poperInstance = await getPoperInstance();
138
+ const selfDeclarationInstance = poperInstance.locator(".d-options .d-option");
126
139
  if (params.selfDeclaration.type === "fictional-rendition") {
127
- await selfDeclarationInstance
128
- .filter({ hasText: "虚构演绎,仅供娱乐" })
129
- .click();
140
+ await selfDeclarationInstance.filter({ hasText: "虚构演绎,仅供娱乐" }).click();
130
141
  } else if (params.selfDeclaration.type === "ai-generated") {
131
- await selfDeclarationInstance
132
- .filter({ hasText: "笔记含AI合成内容" })
133
- .click();
142
+ await selfDeclarationInstance.filter({ hasText: "笔记含AI合成内容" }).click();
134
143
  } else if (params.selfDeclaration.type === "source-statement") {
135
- await selfDeclarationInstance.filter({ hasText: "内容来源声明" }).click();
144
+ await selfDeclarationInstance.filter({ hasText: /内容来源声明/ }).click();
136
145
  // 内容来源声明二级菜单
137
- const selfDeclarationSecondaryMenuInstance = page
138
- .locator(".el-popper[aria-hidden=false] .el-cascader-menu")
139
- .nth(1)
140
- .locator("ul li[role=menuitem]");
146
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
141
147
  // 等待元素出现
142
148
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
143
149
  if (params.selfDeclaration.childType === "self-labeling") {
144
- await selfDeclarationSecondaryMenuInstance
145
- .filter({ hasText: "已自主标注" })
146
- .click();
150
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "已在正文中自主标注" }).click();
147
151
  } else if (params.selfDeclaration.childType === "self-shooting") {
148
152
  const { shootingDate, shootingLocation } = params.selfDeclaration;
149
- await selfDeclarationSecondaryMenuInstance
150
- .filter({ hasText: "自主拍摄" })
151
- .click();
152
-
153
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "自主拍摄" }).click();
153
154
  // 自主拍摄弹窗
154
- const selfShootingPopup = page
155
- .locator(".el-overlay-dialog[aria-modal=true][role=dialog]")
156
- .filter({ hasText: "自主拍摄" });
157
- await selfShootingPopup.waitFor();
158
-
155
+ const selfShootingPopup = await getDialogInstance();
159
156
  const hasCustomContent = shootingDate || shootingLocation;
160
157
 
161
158
  // 选择拍摄地点
162
159
  if (shootingLocation) {
163
- await selectAddress(
164
- selfShootingPopup.locator(".address-input"),
165
- shootingLocation,
166
- );
160
+ await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation);
167
161
  }
168
162
  // 选择拍摄日期
169
163
  if (shootingDate) {
170
- await selectDate(
171
- selfShootingPopup.locator(".date-picker input"),
172
- shootingDate,
173
- );
164
+ await selectDate(selfShootingPopup.locator(".date-picker input"), shootingDate);
174
165
  }
175
166
 
176
167
  await selfShootingPopup
@@ -178,14 +169,9 @@ export const rpaAction: PublishAction = async (task, params) => {
178
169
  .filter({ hasText: hasCustomContent ? "确认" : "取消" })
179
170
  .click();
180
171
  } else if (params.selfDeclaration.childType === "transshipment") {
181
- await selfDeclarationSecondaryMenuInstance
182
- .filter({ hasText: "来源转载" })
183
- .click();
172
+ await selfDeclarationSecondaryMenuInstance.filter({ hasText: "来源转载" }).click();
184
173
  // 来源媒体弹窗
185
- const selfShootingPopup = page
186
- .locator(".el-overlay-dialog[aria-modal=true][role=dialog]")
187
- .filter({ hasText: "来源媒体" });
188
- await selfShootingPopup.waitFor();
174
+ const selfShootingPopup = await getDialogInstance();
189
175
 
190
176
  const sourceMedia = params.selfDeclaration.sourceMedia;
191
177
  if (sourceMedia) {
@@ -200,11 +186,12 @@ export const rpaAction: PublishAction = async (task, params) => {
200
186
  }
201
187
  }
202
188
 
203
- // 可见范围
204
- const publicLabelInstance = page
205
- .locator("label")
206
- .filter({ hasText: visibleRangeTexts[params.visibleRange] });
207
- await publicLabelInstance.click();
189
+ // 可见范围 - 仅自己可见
190
+ if (params.visibleRange === "private") {
191
+ await page.locator(".media-settings .flexbox").filter({ hasText: "可见范围" }).locator(".d-select-wrapper").click();
192
+ const poperInstance = await getPoperInstance();
193
+ await poperInstance.locator(".d-options .custom-option").filter({ hasText: "仅自己可见" }).click();
194
+ }
208
195
 
209
196
  const releaseTimeInstance = page
210
197
  .locator("label")
@@ -235,5 +222,5 @@ export const rpaAction: PublishAction = async (task, params) => {
235
222
  // 关闭页面
236
223
  await page.close();
237
224
 
238
- return response;
225
+ return "response";
239
226
  };
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ import { type BaijiahaoPublishParams, baijiahaoPublish } from "./actions/baijiah
3
3
  import { type GetBaijiahaoActivityParams, getBaijiahaoActivity } from "./actions/getBaijiahaoActivity";
4
4
  import { type GetToutiaoConfigParams, getToutiaoConfig } from "./actions/getToutiaoConfig";
5
5
  import { type SearchToutiaoTopicListParams, searchToutiaoTopicList } from "./actions/searchToutiaoTopicList";
6
+ import { searchXiaohongshuLocation, type searchXiaohongshuLocationParams } from "./actions/searchXiaohongshuLocation";
6
7
  import { type ToutiaoPublishParams, toutiaoPublish } from "./actions/toutiaoPublish";
7
8
  import { type WeitoutiaoPublishParams, weitoutiaoPublish } from "./actions/weitoutiaoPublish";
8
9
  import { type WeixinPublishParams, weixinPublish } from "./actions/weixinPublish";
@@ -37,6 +38,11 @@ export class Action {
37
38
  return xiaohongshuPublish(this.task, params);
38
39
  }
39
40
 
41
+ // 搜索小红书地址
42
+ searchXiaohongshuLocation(params: searchXiaohongshuLocationParams) {
43
+ return searchXiaohongshuLocation(this.task, params);
44
+ }
45
+
40
46
  // 小绿书发布
41
47
  weixinmpPublish(params: WeixinmpPublishParams) {
42
48
  return weixinmpPublish(this.task, params);
package/src/types.ts CHANGED
@@ -55,3 +55,17 @@ export namespace Toutiao {
55
55
  image_mime_type: string;
56
56
  }
57
57
  }
58
+
59
+ export namespace Xiaohongshu {
60
+ export interface Location {
61
+ address: string;
62
+ city_name: string;
63
+ full_address: string;
64
+ latitude: number;
65
+ longitude: number;
66
+ name: string;
67
+ poi_id: string;
68
+ poi_type: number;
69
+ type: "location";
70
+ }
71
+ }