@iflyrpa/actions 1.0.3 → 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
@@ -21863,6 +21863,41 @@ const searchToutiaoTopicList = async (task, params) => {
21863
21863
  }
21864
21864
  };
21865
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
+
21866
21901
  const COVER_TYPE = {
21867
21902
  no: 1,
21868
21903
  single: 2,
@@ -22447,10 +22482,6 @@ const mockAction = async (task, params) => {
22447
22482
  return Promise.reject();
22448
22483
  };
22449
22484
 
22450
- const visibleRangeTexts = {
22451
- public: "\u516C\u5F00\u53EF\u89C1",
22452
- private: "\u4EC5\u81EA\u5DF1\u53EF\u89C1"
22453
- };
22454
22485
  const rpaAction = async (task, params) => {
22455
22486
  const commonCookies = {
22456
22487
  path: "/",
@@ -22480,6 +22511,28 @@ const rpaAction = async (task, params) => {
22480
22511
  await instance.fill(date);
22481
22512
  await instance.blur();
22482
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
+ };
22483
22536
  await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
22484
22537
  throw new Error("\u767B\u5F55\u5931\u8D25");
22485
22538
  });
@@ -22515,23 +22568,23 @@ const rpaAction = async (task, params) => {
22515
22568
  );
22516
22569
  }
22517
22570
  if (params.selfDeclaration) {
22518
- await page.locator(".declaration-wrapper").click();
22519
- const selfDeclarationInstance = page.locator(".el-popper[aria-hidden=false] ul li[role=menuitem]");
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");
22520
22574
  if (params.selfDeclaration.type === "fictional-rendition") {
22521
22575
  await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
22522
22576
  } else if (params.selfDeclaration.type === "ai-generated") {
22523
22577
  await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
22524
22578
  } else if (params.selfDeclaration.type === "source-statement") {
22525
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
22526
- 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");
22527
22581
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
22528
22582
  if (params.selfDeclaration.childType === "self-labeling") {
22529
22583
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u5728\u6B63\u6587\u4E2D\u81EA\u4E3B\u6807\u6CE8" }).click();
22530
22584
  } else if (params.selfDeclaration.childType === "self-shooting") {
22531
22585
  const { shootingDate, shootingLocation } = params.selfDeclaration;
22532
22586
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
22533
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
22534
- await selfShootingPopup.waitFor();
22587
+ const selfShootingPopup = await getDialogInstance();
22535
22588
  const hasCustomContent = shootingDate || shootingLocation;
22536
22589
  if (shootingLocation) {
22537
22590
  await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation);
@@ -22542,8 +22595,7 @@ const rpaAction = async (task, params) => {
22542
22595
  await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
22543
22596
  } else if (params.selfDeclaration.childType === "transshipment") {
22544
22597
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
22545
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
22546
- await selfShootingPopup.waitFor();
22598
+ const selfShootingPopup = await getDialogInstance();
22547
22599
  const sourceMedia = params.selfDeclaration.sourceMedia;
22548
22600
  if (sourceMedia) {
22549
22601
  await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
@@ -22552,14 +22604,17 @@ const rpaAction = async (task, params) => {
22552
22604
  }
22553
22605
  }
22554
22606
  }
22555
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
22556
- 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
+ }
22557
22612
  const releaseTimeInstance = page.locator("label").filter({ hasText: params.isImmediatelyPublish ? "\u7ACB\u5373\u53D1\u5E03" : "\u5B9A\u65F6\u53D1\u5E03" });
22558
22613
  await releaseTimeInstance.click();
22559
22614
  if (params.scheduledPublish) {
22560
22615
  await selectDate(".date-picker input", params.scheduledPublish);
22561
22616
  }
22562
- const response = await new Promise((resolve) => {
22617
+ await new Promise((resolve) => {
22563
22618
  const handleResponse = async (response2) => {
22564
22619
  if (response2.url().includes("/web_api/sns/v2/note")) {
22565
22620
  const jsonResponse = await response2.json();
@@ -22571,7 +22626,7 @@ const rpaAction = async (task, params) => {
22571
22626
  page.locator(".submit .publishBtn").click();
22572
22627
  });
22573
22628
  await page.close();
22574
- return response;
22629
+ return "response";
22575
22630
  };
22576
22631
 
22577
22632
  const executeAction = (task, params) => {
@@ -22616,6 +22671,10 @@ class Action {
22616
22671
  xiaohongshuPublish(params) {
22617
22672
  return xiaohongshuPublish(this.task, params);
22618
22673
  }
22674
+ // 搜索小红书地址
22675
+ searchXiaohongshuLocation(params) {
22676
+ return searchXiaohongshuLocation(this.task, params);
22677
+ }
22619
22678
  // 小绿书发布
22620
22679
  weixinmpPublish(params) {
22621
22680
  return weixinmpPublish(this.task, params);
package/dist/index.mjs CHANGED
@@ -21845,6 +21845,41 @@ const searchToutiaoTopicList = async (task, params) => {
21845
21845
  }
21846
21846
  };
21847
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
+
21848
21883
  const COVER_TYPE = {
21849
21884
  no: 1,
21850
21885
  single: 2,
@@ -22429,10 +22464,6 @@ const mockAction = async (task, params) => {
22429
22464
  return Promise.reject();
22430
22465
  };
22431
22466
 
22432
- const visibleRangeTexts = {
22433
- public: "\u516C\u5F00\u53EF\u89C1",
22434
- private: "\u4EC5\u81EA\u5DF1\u53EF\u89C1"
22435
- };
22436
22467
  const rpaAction = async (task, params) => {
22437
22468
  const commonCookies = {
22438
22469
  path: "/",
@@ -22462,6 +22493,28 @@ const rpaAction = async (task, params) => {
22462
22493
  await instance.fill(date);
22463
22494
  await instance.blur();
22464
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
+ };
22465
22518
  await page.waitForSelector("#CreatorPlatform", { state: "visible" }).catch(() => {
22466
22519
  throw new Error("\u767B\u5F55\u5931\u8D25");
22467
22520
  });
@@ -22497,23 +22550,23 @@ const rpaAction = async (task, params) => {
22497
22550
  );
22498
22551
  }
22499
22552
  if (params.selfDeclaration) {
22500
- await page.locator(".declaration-wrapper").click();
22501
- const selfDeclarationInstance = page.locator(".el-popper[aria-hidden=false] ul li[role=menuitem]");
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");
22502
22556
  if (params.selfDeclaration.type === "fictional-rendition") {
22503
22557
  await selfDeclarationInstance.filter({ hasText: "\u865A\u6784\u6F14\u7ECE\uFF0C\u4EC5\u4F9B\u5A31\u4E50" }).click();
22504
22558
  } else if (params.selfDeclaration.type === "ai-generated") {
22505
22559
  await selfDeclarationInstance.filter({ hasText: "\u7B14\u8BB0\u542BAI\u5408\u6210\u5185\u5BB9" }).click();
22506
22560
  } else if (params.selfDeclaration.type === "source-statement") {
22507
- await selfDeclarationInstance.filter({ hasText: "\u5185\u5BB9\u6765\u6E90\u58F0\u660E" }).click();
22508
- 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");
22509
22563
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
22510
22564
  if (params.selfDeclaration.childType === "self-labeling") {
22511
22565
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u5DF2\u5728\u6B63\u6587\u4E2D\u81EA\u4E3B\u6807\u6CE8" }).click();
22512
22566
  } else if (params.selfDeclaration.childType === "self-shooting") {
22513
22567
  const { shootingDate, shootingLocation } = params.selfDeclaration;
22514
22568
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" }).click();
22515
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u81EA\u4E3B\u62CD\u6444" });
22516
- await selfShootingPopup.waitFor();
22569
+ const selfShootingPopup = await getDialogInstance();
22517
22570
  const hasCustomContent = shootingDate || shootingLocation;
22518
22571
  if (shootingLocation) {
22519
22572
  await selectAddress(selfShootingPopup.locator(".address-input"), shootingLocation);
@@ -22524,8 +22577,7 @@ const rpaAction = async (task, params) => {
22524
22577
  await selfShootingPopup.locator("footer button").filter({ hasText: hasCustomContent ? "\u786E\u8BA4" : "\u53D6\u6D88" }).click();
22525
22578
  } else if (params.selfDeclaration.childType === "transshipment") {
22526
22579
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "\u6765\u6E90\u8F6C\u8F7D" }).click();
22527
- const selfShootingPopup = page.locator(".el-overlay-dialog[aria-modal=true][role=dialog]").filter({ hasText: "\u6765\u6E90\u5A92\u4F53" });
22528
- await selfShootingPopup.waitFor();
22580
+ const selfShootingPopup = await getDialogInstance();
22529
22581
  const sourceMedia = params.selfDeclaration.sourceMedia;
22530
22582
  if (sourceMedia) {
22531
22583
  await selfShootingPopup.locator(".el-input input").fill(sourceMedia);
@@ -22534,14 +22586,17 @@ const rpaAction = async (task, params) => {
22534
22586
  }
22535
22587
  }
22536
22588
  }
22537
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
22538
- 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
+ }
22539
22594
  const releaseTimeInstance = page.locator("label").filter({ hasText: params.isImmediatelyPublish ? "\u7ACB\u5373\u53D1\u5E03" : "\u5B9A\u65F6\u53D1\u5E03" });
22540
22595
  await releaseTimeInstance.click();
22541
22596
  if (params.scheduledPublish) {
22542
22597
  await selectDate(".date-picker input", params.scheduledPublish);
22543
22598
  }
22544
- const response = await new Promise((resolve) => {
22599
+ await new Promise((resolve) => {
22545
22600
  const handleResponse = async (response2) => {
22546
22601
  if (response2.url().includes("/web_api/sns/v2/note")) {
22547
22602
  const jsonResponse = await response2.json();
@@ -22553,7 +22608,7 @@ const rpaAction = async (task, params) => {
22553
22608
  page.locator(".submit .publishBtn").click();
22554
22609
  });
22555
22610
  await page.close();
22556
- return response;
22611
+ return "response";
22557
22612
  };
22558
22613
 
22559
22614
  const executeAction = (task, params) => {
@@ -22598,6 +22653,10 @@ class Action {
22598
22653
  xiaohongshuPublish(params) {
22599
22654
  return xiaohongshuPublish(this.task, params);
22600
22655
  }
22656
+ // 搜索小红书地址
22657
+ searchXiaohongshuLocation(params) {
22658
+ return searchXiaohongshuLocation(this.task, params);
22659
+ }
22601
22660
  // 小绿书发布
22602
22661
  weixinmpPublish(params) {
22603
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.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -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
+ };
@@ -2,12 +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<XiaohongshuPublishParams["visibleRange"], string> = {
8
- public: "公开可见",
9
- private: "仅自己可见",
10
- };
5
+ import type { PublishAction } from "./index";
11
6
 
12
7
  export const rpaAction: PublishAction = async (task, params) => {
13
8
  const commonCookies: CookieMap[number] = {
@@ -36,6 +31,7 @@ export const rpaAction: PublishAction = async (task, params) => {
36
31
  await poperInstance.first().waitFor();
37
32
  await poperInstance.first().click();
38
33
  };
34
+
39
35
  // 通用的选择日期
40
36
  const selectDate = async (selector: string | Locator, date: string) => {
41
37
  const instance = typeof selector === "string" ? page.locator(selector) : selector;
@@ -44,6 +40,35 @@ export const rpaAction: PublishAction = async (task, params) => {
44
40
  await instance.blur();
45
41
  };
46
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
+
47
72
  // 自动化脚本
48
73
  // ----------------------------------------------------------------------------------
49
74
 
@@ -108,19 +133,17 @@ export const rpaAction: PublishAction = async (task, params) => {
108
133
 
109
134
  if (params.selfDeclaration) {
110
135
  // 自主声明
111
- await page.locator(".declaration-wrapper").click();
112
- const selfDeclarationInstance = page.locator(".el-popper[aria-hidden=false] ul li[role=menuitem]");
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");
113
139
  if (params.selfDeclaration.type === "fictional-rendition") {
114
140
  await selfDeclarationInstance.filter({ hasText: "虚构演绎,仅供娱乐" }).click();
115
141
  } else if (params.selfDeclaration.type === "ai-generated") {
116
142
  await selfDeclarationInstance.filter({ hasText: "笔记含AI合成内容" }).click();
117
143
  } else if (params.selfDeclaration.type === "source-statement") {
118
- await selfDeclarationInstance.filter({ hasText: "内容来源声明" }).click();
144
+ await selfDeclarationInstance.filter({ hasText: /内容来源声明/ }).click();
119
145
  // 内容来源声明二级菜单
120
- const selfDeclarationSecondaryMenuInstance = page
121
- .locator(".el-popper[aria-hidden=false] .el-cascader-menu")
122
- .nth(1)
123
- .locator("ul li[role=menuitem]");
146
+ const selfDeclarationSecondaryMenuInstance = (await getPoperInstance()).locator(".d-options .d-option");
124
147
  // 等待元素出现
125
148
  await selfDeclarationSecondaryMenuInstance.first().waitFor();
126
149
  if (params.selfDeclaration.childType === "self-labeling") {
@@ -128,13 +151,8 @@ export const rpaAction: PublishAction = async (task, params) => {
128
151
  } else if (params.selfDeclaration.childType === "self-shooting") {
129
152
  const { shootingDate, shootingLocation } = params.selfDeclaration;
130
153
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "自主拍摄" }).click();
131
-
132
154
  // 自主拍摄弹窗
133
- const selfShootingPopup = page
134
- .locator(".el-overlay-dialog[aria-modal=true][role=dialog]")
135
- .filter({ hasText: "自主拍摄" });
136
- await selfShootingPopup.waitFor();
137
-
155
+ const selfShootingPopup = await getDialogInstance();
138
156
  const hasCustomContent = shootingDate || shootingLocation;
139
157
 
140
158
  // 选择拍摄地点
@@ -153,10 +171,7 @@ export const rpaAction: PublishAction = async (task, params) => {
153
171
  } else if (params.selfDeclaration.childType === "transshipment") {
154
172
  await selfDeclarationSecondaryMenuInstance.filter({ hasText: "来源转载" }).click();
155
173
  // 来源媒体弹窗
156
- const selfShootingPopup = page
157
- .locator(".el-overlay-dialog[aria-modal=true][role=dialog]")
158
- .filter({ hasText: "来源媒体" });
159
- await selfShootingPopup.waitFor();
174
+ const selfShootingPopup = await getDialogInstance();
160
175
 
161
176
  const sourceMedia = params.selfDeclaration.sourceMedia;
162
177
  if (sourceMedia) {
@@ -171,9 +186,12 @@ export const rpaAction: PublishAction = async (task, params) => {
171
186
  }
172
187
  }
173
188
 
174
- // 可见范围
175
- const publicLabelInstance = page.locator("label").filter({ hasText: visibleRangeTexts[params.visibleRange] });
176
- 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
+ }
177
195
 
178
196
  const releaseTimeInstance = page
179
197
  .locator("label")
@@ -204,5 +222,5 @@ export const rpaAction: PublishAction = async (task, params) => {
204
222
  // 关闭页面
205
223
  await page.close();
206
224
 
207
- return response;
225
+ return "response";
208
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
+ }