@muench-dev/n8n-nodes-bluesky 3.1.1 → 4.0.2

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.
Files changed (44) hide show
  1. package/README.md +151 -24
  2. package/dist/nodes/Bluesky/V2/BlueskyV2.node.d.ts +1 -1
  3. package/dist/nodes/Bluesky/V2/BlueskyV2.node.js +212 -128
  4. package/dist/nodes/Bluesky/V2/BlueskyV2.node.js.map +1 -1
  5. package/dist/nodes/Bluesky/V2/__tests__/analyticsOperations.test.d.ts +1 -0
  6. package/dist/nodes/Bluesky/V2/__tests__/analyticsOperations.test.js +99 -0
  7. package/dist/nodes/Bluesky/V2/__tests__/analyticsOperations.test.js.map +1 -0
  8. package/dist/nodes/Bluesky/V2/__tests__/graphOperations.test.d.ts +1 -0
  9. package/dist/nodes/Bluesky/V2/__tests__/graphOperations.test.js +19 -0
  10. package/dist/nodes/Bluesky/V2/__tests__/graphOperations.test.js.map +1 -0
  11. package/dist/nodes/Bluesky/V2/__tests__/listOperations.test.d.ts +1 -0
  12. package/dist/nodes/Bluesky/V2/__tests__/listOperations.test.js +97 -0
  13. package/dist/nodes/Bluesky/V2/__tests__/listOperations.test.js.map +1 -0
  14. package/dist/nodes/Bluesky/V2/__tests__/postOperations.test.js +70 -8
  15. package/dist/nodes/Bluesky/V2/__tests__/postOperations.test.js.map +1 -1
  16. package/dist/nodes/Bluesky/V2/__tests__/searchOperations.test.d.ts +1 -0
  17. package/dist/nodes/Bluesky/V2/__tests__/searchOperations.test.js +41 -0
  18. package/dist/nodes/Bluesky/V2/__tests__/searchOperations.test.js.map +1 -0
  19. package/dist/nodes/Bluesky/V2/analyticsOperations.d.ts +7 -0
  20. package/dist/nodes/Bluesky/V2/analyticsOperations.js +236 -0
  21. package/dist/nodes/Bluesky/V2/analyticsOperations.js.map +1 -0
  22. package/dist/nodes/Bluesky/V2/feedOperations.d.ts +3 -2
  23. package/dist/nodes/Bluesky/V2/feedOperations.js +113 -13
  24. package/dist/nodes/Bluesky/V2/feedOperations.js.map +1 -1
  25. package/dist/nodes/Bluesky/V2/graphOperations.d.ts +4 -0
  26. package/dist/nodes/Bluesky/V2/graphOperations.js +45 -0
  27. package/dist/nodes/Bluesky/V2/graphOperations.js.map +1 -0
  28. package/dist/nodes/Bluesky/V2/listOperations.d.ts +10 -0
  29. package/dist/nodes/Bluesky/V2/listOperations.js +302 -0
  30. package/dist/nodes/Bluesky/V2/listOperations.js.map +1 -0
  31. package/dist/nodes/Bluesky/V2/postOperations.d.ts +21 -9
  32. package/dist/nodes/Bluesky/V2/postOperations.js +342 -232
  33. package/dist/nodes/Bluesky/V2/postOperations.js.map +1 -1
  34. package/dist/nodes/Bluesky/V2/resources.js +18 -2
  35. package/dist/nodes/Bluesky/V2/resources.js.map +1 -1
  36. package/dist/nodes/Bluesky/V2/searchOperations.d.ts +5 -0
  37. package/dist/nodes/Bluesky/V2/searchOperations.js +95 -0
  38. package/dist/nodes/Bluesky/V2/searchOperations.js.map +1 -0
  39. package/dist/nodes/Bluesky/V2/userOperations.d.ts +2 -0
  40. package/dist/nodes/Bluesky/V2/userOperations.js +137 -34
  41. package/dist/nodes/Bluesky/V2/userOperations.js.map +1 -1
  42. package/dist/package.json +9 -4
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +80 -67
package/README.md CHANGED
@@ -2,45 +2,172 @@
2
2
 
3
3
  # n8n-nodes-bluesky
4
4
 
5
- This repository contains the code for the n8n nodes that interact with the [Bluesky API](https://docs.bsky.app/docs/category/http-reference).
5
+ Community n8n nodes for interacting with the [Bluesky API](https://docs.bsky.app/docs/category/http-reference).
6
+
7
+ The package ships a versioned `Bluesky` node. Version 2 is the default and includes the latest features.
8
+
9
+ Some of the Version 2 feature set was backported from the `brianmoney/n8n-nodes-bluesky` fork and adapted to this repository's current codebase and packaging.
6
10
 
7
11
  ## Installation
8
12
 
13
+ Install the package in an n8n environment:
14
+
9
15
  ```bash
10
- pnpm install @muench-dev/n8n-nodes-bluesky
16
+ pnpm add @muench-dev/n8n-nodes-bluesky
11
17
  ```
12
18
 
13
- In n8n community edition, you can install the nodes in the settings page.
19
+ You can also install it from the Community Nodes section in n8n.
20
+
21
+ ## Requirements
22
+
23
+ - Node.js `>=18.10`
24
+ - pnpm `>=9.1`
25
+ - A Bluesky app password
26
+
27
+ Create an app password in Bluesky here:
28
+ `https://bsky.app/settings/app-passwords`
29
+
30
+ ## Credentials
31
+
32
+ The node uses these credential fields:
33
+
34
+ - `Identifier (Handle)`
35
+ - `App Password`
36
+ - `Service URL` with `https://bsky.social` as the default
37
+
38
+ The custom service URL is useful when you want to authenticate against a different AT Protocol service.
14
39
 
15
40
  ## Features
16
41
 
17
- - User
18
- - Block User
19
- - Get Profile
20
- - Mute User
21
- - Un-mute User
22
- - Feed
23
- - Get Author Feed
24
- - Get Timeline of current user
25
- - Post
26
- - Create Post
27
- - Like
28
- - Unlike
29
- - Repost
30
- - Delete Repost
31
-
32
- ## Screenshots
42
+ ### User
33
43
 
34
- ![images](.github/images/screenshot_20241128_174932.png)
44
+ - Get Profile
45
+ - List All Followers
46
+ - List All Follows
47
+ - Mute User
48
+ - Un-Mute User
49
+ - Block User
50
+ - Un-Block User
51
+
52
+ ### Feed
53
+
54
+ - Get Author Feed
55
+ - Get Post Thread
56
+ - Get Timeline
57
+
58
+ Feed also supports author feed filtering:
59
+
60
+ - Posts with Replies
61
+ - Posts without Replies
62
+ - Posts with Media
63
+ - Posts and Author Threads
64
+ - Posts with Video
65
+
66
+ Feed responses are normalized and include post metadata such as author details, counts, embeds, reply parent details, and repost context when available.
67
+
68
+ ### Analytics
69
+
70
+ - List Notifications
71
+ - Get Unread Notification Count
72
+ - Update Seen Notifications
73
+ - Get Post Interactions
74
+
75
+ ### Graph
76
+
77
+ - Mute Thread
78
+
79
+ ### List
80
+
81
+ - Create List
82
+ - Update List
83
+ - Delete List
84
+ - Get Lists
85
+ - Get List Feed
86
+ - Add User to List
87
+ - Remove User From List
88
+
89
+ ### Post
90
+
91
+ - Create Post
92
+ - Reply to a Post
93
+ - Quote a Post
94
+ - Delete Post
95
+ - Like a Post
96
+ - Unlike a Post
97
+ - Repost a Post
98
+ - Delete Repost
99
+
100
+ Create Post also supports:
101
+
102
+ - language tags
103
+ - automatic rich text facet detection for links and mentions
104
+ - single image upload with alt text
105
+ - multiple image uploads with alt text
106
+ - media attachments in replies
107
+ - optional image aspect ratio metadata
108
+ - automatic image resizing to stay within Bluesky upload limits
109
+ - website cards with manual title, description, and thumbnail
110
+ - website cards generated from Open Graph tags
111
+
112
+ Current behavior:
113
+
114
+ - If both an image and a website card are provided, the image embed is used.
115
+ - If media items are provided, image embeds are used instead of website cards.
116
+ - Open Graph website cards can optionally fetch title, description, and preview image from the target URL.
35
117
 
36
- ## Use Cases
118
+ ### Search
119
+
120
+ - Search Users
121
+ - Search Posts
122
+
123
+ ## Example Use Cases
37
124
 
38
125
  ### RSS Feed to Bluesky
39
126
 
40
- You can use the RSS Trigger node to get the latest posts from an RSS feed and then use the Create Post node to post them to Bluesky.
127
+ Use the RSS Trigger node to fetch new posts from an RSS feed and pass the result into the Bluesky node with the `Create Post` operation.
41
128
 
42
- ![images](.github/images/use_case_rss_trigger_overview.png)
129
+ For link posts, you can enable website cards and fetch Open Graph tags to enrich the preview automatically.
130
+
131
+ ### Community and Monitoring
43
132
 
44
- Use Open Graph Tags to get the image and description of the post.
133
+ Use the additional resources to automate Bluesky workflows such as:
134
+
135
+ - monitoring unread notifications and post interactions
136
+ - searching users and posts for mentions or discovery
137
+ - managing curated or moderation lists
138
+ - exporting full follower and following sets with pagination
139
+ - replying to posts or quoting them in follow-up automations
140
+
141
+ ![images](.github/images/use_case_rss_trigger_overview.png)
45
142
 
46
143
  ![images](.github/images/use_case_rss_trigger_node_details.png)
144
+
145
+ ## Screenshot
146
+
147
+ ![images](.github/images/screenshot_20241128_174932.png)
148
+
149
+ ## Development
150
+
151
+ Install dependencies:
152
+
153
+ ```bash
154
+ pnpm install
155
+ ```
156
+
157
+ Run tests:
158
+
159
+ ```bash
160
+ pnpm test
161
+ ```
162
+
163
+ Run linting:
164
+
165
+ ```bash
166
+ pnpm lint
167
+ ```
168
+
169
+ Build the package:
170
+
171
+ ```bash
172
+ pnpm build
173
+ ```
@@ -1,4 +1,4 @@
1
- import { INodeExecutionData, IExecuteFunctions, INodeType, INodeTypeDescription, INodeTypeBaseDescription } from 'n8n-workflow';
1
+ import { INodeExecutionData, IExecuteFunctions, INodeType, INodeTypeBaseDescription, INodeTypeDescription } from 'n8n-workflow';
2
2
  export declare class BlueskyV2 implements INodeType {
3
3
  description: INodeTypeDescription;
4
4
  constructor(baseDescription: INodeTypeBaseDescription);
@@ -7,6 +7,101 @@ const resources_1 = require("./resources");
7
7
  const postOperations_1 = require("./postOperations");
8
8
  const userOperations_1 = require("./userOperations");
9
9
  const feedOperations_1 = require("./feedOperations");
10
+ const analyticsOperations_1 = require("./analyticsOperations");
11
+ const graphOperations_1 = require("./graphOperations");
12
+ const listOperations_1 = require("./listOperations");
13
+ const searchOperations_1 = require("./searchOperations");
14
+ async function getWebsiteCardPayload(context, itemIndex) {
15
+ var _a, _b, _c;
16
+ const websiteCardRaw = context.getNodeParameter('websiteCard', itemIndex, {});
17
+ let websiteCard = websiteCardRaw;
18
+ if (websiteCardRaw && typeof websiteCardRaw === 'object' && 'details' in websiteCardRaw) {
19
+ if (Array.isArray(websiteCardRaw.details) && websiteCardRaw.details.length > 0) {
20
+ websiteCard = websiteCardRaw.details[0];
21
+ }
22
+ else if (typeof websiteCardRaw.details === 'object') {
23
+ websiteCard = websiteCardRaw.details;
24
+ }
25
+ }
26
+ let thumbnailBinary;
27
+ if ((websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.thumbnailBinaryProperty) && websiteCard.fetchOpenGraphTags === false) {
28
+ thumbnailBinary = await context.helpers.getBinaryDataBuffer(itemIndex, websiteCard.thumbnailBinaryProperty);
29
+ }
30
+ let websiteCardUri = websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.uri;
31
+ try {
32
+ if (websiteCardUri) {
33
+ new URL(websiteCardUri);
34
+ }
35
+ }
36
+ catch {
37
+ websiteCardUri = undefined;
38
+ }
39
+ if (!websiteCardUri &&
40
+ !(websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.title) &&
41
+ !(websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.description) &&
42
+ !thumbnailBinary &&
43
+ (websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.fetchOpenGraphTags) === undefined) {
44
+ return undefined;
45
+ }
46
+ return {
47
+ uri: websiteCardUri !== null && websiteCardUri !== void 0 ? websiteCardUri : undefined,
48
+ title: (_a = websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.title) !== null && _a !== void 0 ? _a : undefined,
49
+ description: (_b = websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.description) !== null && _b !== void 0 ? _b : undefined,
50
+ thumbnailBinary,
51
+ fetchOpenGraphTags: (_c = websiteCard === null || websiteCard === void 0 ? void 0 : websiteCard.fetchOpenGraphTags) !== null && _c !== void 0 ? _c : undefined,
52
+ };
53
+ }
54
+ async function getLegacyImagePayload(context, itemIndex) {
55
+ const imageParamRaw = context.getNodeParameter('image', itemIndex, {});
56
+ const imageParam = imageParamRaw && imageParamRaw.details ? imageParamRaw.details : imageParamRaw;
57
+ if (!imageParam || (!imageParam.binary && !imageParam.alt && !imageParam.mimeType)) {
58
+ return undefined;
59
+ }
60
+ let imageBuffer;
61
+ if (imageParam.binary) {
62
+ imageBuffer = await context.helpers.getBinaryDataBuffer(itemIndex, imageParam.binary);
63
+ }
64
+ return {
65
+ alt: imageParam.alt,
66
+ mimeType: imageParam.mimeType,
67
+ binary: imageBuffer,
68
+ width: imageParam.width,
69
+ height: imageParam.height,
70
+ };
71
+ }
72
+ async function getMediaItemsPayload(context, itemIndex) {
73
+ var _a;
74
+ const includeMedia = context.getNodeParameter('includeMedia', itemIndex, false);
75
+ if (!includeMedia) {
76
+ return [];
77
+ }
78
+ const mediaItemsRaw = context.getNodeParameter('mediaItems', itemIndex, {});
79
+ const mediaItems = Array.isArray(mediaItemsRaw)
80
+ ? mediaItemsRaw
81
+ : Array.isArray(mediaItemsRaw.media)
82
+ ? mediaItemsRaw.media
83
+ : Array.isArray(mediaItemsRaw.mediaItems)
84
+ ? mediaItemsRaw.mediaItems
85
+ : mediaItemsRaw.media && typeof mediaItemsRaw.media === 'object'
86
+ ? [{ media: mediaItemsRaw.media }]
87
+ : [];
88
+ const payload = [];
89
+ for (const item of mediaItems) {
90
+ const mediaEntry = 'media' in item ? ((_a = item.media) !== null && _a !== void 0 ? _a : {}) : item;
91
+ const binaryPropertyName = mediaEntry.binaryPropertyName;
92
+ if (!binaryPropertyName) {
93
+ continue;
94
+ }
95
+ const binaryData = await context.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
96
+ const binaryMeta = context.helpers.assertBinaryData(itemIndex, binaryPropertyName);
97
+ payload.push({
98
+ alt: mediaEntry.altText,
99
+ mimeType: binaryMeta.mimeType,
100
+ binary: binaryData,
101
+ });
102
+ }
103
+ return payload;
104
+ }
10
105
  class BlueskyV2 {
11
106
  constructor(baseDescription) {
12
107
  this.description = {
@@ -23,11 +118,19 @@ class BlueskyV2 {
23
118
  required: true,
24
119
  },
25
120
  ],
26
- properties: [resources_1.resourcesProperty, ...userOperations_1.userProperties, ...postOperations_1.postProperties, ...feedOperations_1.feedProperties],
121
+ properties: [
122
+ resources_1.resourcesProperty,
123
+ ...analyticsOperations_1.analyticsProperties,
124
+ ...graphOperations_1.graphProperties,
125
+ ...listOperations_1.listProperties,
126
+ ...userOperations_1.userProperties,
127
+ ...postOperations_1.postProperties,
128
+ ...feedOperations_1.feedProperties,
129
+ ...searchOperations_1.searchProperties,
130
+ ],
27
131
  };
28
132
  }
29
133
  async execute() {
30
- var _a, _b, _c;
31
134
  const items = this.getInputData();
32
135
  const returnData = [];
33
136
  const credentials = (await this.getCredentials('blueskyApi'));
@@ -50,167 +153,144 @@ class BlueskyV2 {
50
153
  case 'post': {
51
154
  const postText = this.getNodeParameter('postText', i);
52
155
  const langs = this.getNodeParameter('langs', i);
53
- let websiteCardRaw = this.getNodeParameter('websiteCard', i, {});
54
- let websiteCard = websiteCardRaw;
55
- if (websiteCardRaw &&
56
- typeof websiteCardRaw === 'object' &&
57
- 'details' in websiteCardRaw) {
58
- if (Array.isArray(websiteCardRaw.details) && websiteCardRaw.details.length > 0) {
59
- websiteCard = websiteCardRaw.details[0];
60
- }
61
- else if (typeof websiteCardRaw.details === 'object') {
62
- websiteCard = websiteCardRaw.details;
63
- }
64
- }
65
- let thumbnailBinary;
66
- if (websiteCard.thumbnailBinaryProperty && websiteCard.fetchOpenGraphTags === false) {
67
- thumbnailBinary = await this.helpers.getBinaryDataBuffer(i, websiteCard.thumbnailBinaryProperty);
68
- }
69
- let websiteCardUri = websiteCard.uri;
70
- try {
71
- if (websiteCardUri)
72
- new URL(websiteCardUri);
73
- }
74
- catch {
75
- websiteCardUri = undefined;
76
- }
77
- let websiteCardPayload;
78
- if (websiteCardUri ||
79
- websiteCard.title ||
80
- websiteCard.description ||
81
- thumbnailBinary ||
82
- websiteCard.fetchOpenGraphTags !== undefined) {
83
- websiteCardPayload = {
84
- uri: websiteCardUri !== null && websiteCardUri !== void 0 ? websiteCardUri : undefined,
85
- title: (_a = websiteCard.title) !== null && _a !== void 0 ? _a : undefined,
86
- description: (_b = websiteCard.description) !== null && _b !== void 0 ? _b : undefined,
87
- thumbnailBinary: thumbnailBinary !== null && thumbnailBinary !== void 0 ? thumbnailBinary : undefined,
88
- fetchOpenGraphTags: (_c = websiteCard.fetchOpenGraphTags) !== null && _c !== void 0 ? _c : undefined,
89
- };
90
- }
91
- n8n_workflow_1.LoggerProxy.debug('Prepared websiteCard payload', {
92
- ...itemMeta,
93
- hasWebsiteCard: Boolean(websiteCardPayload),
94
- hasThumbnailBinary: Boolean(thumbnailBinary),
95
- websiteCardUri: websiteCardPayload === null || websiteCardPayload === void 0 ? void 0 : websiteCardPayload.uri,
96
- });
97
- const imageParamRaw = this.getNodeParameter('image', i, {});
98
- const imageParam = (imageParamRaw && imageParamRaw.details) ? imageParamRaw.details : imageParamRaw;
99
- let imagePayload;
100
- if (imageParam && (imageParam.binary || imageParam.alt || imageParam.mimeType)) {
101
- let imageBuffer;
102
- if (imageParam.binary) {
103
- imageBuffer = await this.helpers.getBinaryDataBuffer(i, imageParam.binary);
104
- }
105
- imagePayload = {
106
- alt: imageParam.alt,
107
- mimeType: imageParam.mimeType,
108
- binary: imageBuffer,
109
- width: imageParam.width,
110
- height: imageParam.height,
111
- };
112
- }
113
- n8n_workflow_1.LoggerProxy.info('Posting to Bluesky', {
114
- ...itemMeta,
115
- hasImage: Boolean(imagePayload === null || imagePayload === void 0 ? void 0 : imagePayload.binary),
116
- hasAltText: Boolean(imagePayload === null || imagePayload === void 0 ? void 0 : imagePayload.alt),
117
- langs,
118
- postTextPreview: postText === null || postText === void 0 ? void 0 : postText.slice(0, 60),
119
- });
120
- const postData = await (0, postOperations_1.postOperation)(agent, postText, langs, websiteCardPayload, imagePayload);
121
- n8n_workflow_1.LoggerProxy.debug('Post operation completed', { ...itemMeta, itemsReturned: postData.length });
122
- returnData.push(...postData);
156
+ const websiteCardPayload = await getWebsiteCardPayload(this, i);
157
+ const imagePayload = await getLegacyImagePayload(this, i);
158
+ const mediaItemsPayload = await getMediaItemsPayload(this, i);
159
+ returnData.push(...(await (0, postOperations_1.postOperation)(agent, postText, langs, websiteCardPayload, imagePayload, mediaItemsPayload)));
160
+ break;
161
+ }
162
+ case 'reply': {
163
+ const replyText = this.getNodeParameter('replyText', i);
164
+ const replyLangs = this.getNodeParameter('replyLangs', i);
165
+ const uri = this.getNodeParameter('uri', i);
166
+ const cid = this.getNodeParameter('cid', i);
167
+ const websiteCardPayload = await getWebsiteCardPayload(this, i);
168
+ const mediaItemsPayload = await getMediaItemsPayload(this, i);
169
+ returnData.push(...(await (0, postOperations_1.replyOperation)(agent, replyText, replyLangs, uri, cid, websiteCardPayload, mediaItemsPayload)));
170
+ break;
171
+ }
172
+ case 'quote': {
173
+ const quoteText = this.getNodeParameter('quoteText', i);
174
+ const quoteLangs = this.getNodeParameter('quoteLangs', i);
175
+ const uri = this.getNodeParameter('uri', i);
176
+ const cid = this.getNodeParameter('cid', i);
177
+ returnData.push(...(await (0, postOperations_1.quoteOperation)(agent, quoteText, quoteLangs, uri, cid)));
123
178
  break;
124
179
  }
125
180
  case 'deletePost': {
126
- const uriDeletePost = this.getNodeParameter('uri', i);
127
- n8n_workflow_1.LoggerProxy.info('Deleting post', { ...itemMeta, uri: uriDeletePost });
128
- const deletePostData = await (0, postOperations_1.deletePostOperation)(agent, uriDeletePost);
129
- returnData.push(...deletePostData);
181
+ returnData.push(...(await (0, postOperations_1.deletePostOperation)(agent, this.getNodeParameter('uri', i))));
130
182
  break;
131
183
  }
132
184
  case 'like': {
133
- const uriLike = this.getNodeParameter('uri', i);
134
- const cidLike = this.getNodeParameter('cid', i);
135
- n8n_workflow_1.LoggerProxy.debug('Liking post', { ...itemMeta, uri: uriLike, cidPresent: Boolean(cidLike) });
136
- const likeData = await (0, postOperations_1.likeOperation)(agent, uriLike, cidLike);
137
- returnData.push(...likeData);
185
+ returnData.push(...(await (0, postOperations_1.likeOperation)(agent, this.getNodeParameter('uri', i), this.getNodeParameter('cid', i))));
138
186
  break;
139
187
  }
140
188
  case 'deleteLike': {
141
- const uriDeleteLike = this.getNodeParameter('uri', i);
142
- n8n_workflow_1.LoggerProxy.debug('Deleting like', { ...itemMeta, uri: uriDeleteLike });
143
- const deleteLikeData = await (0, postOperations_1.deleteLikeOperation)(agent, uriDeleteLike);
144
- returnData.push(...deleteLikeData);
189
+ returnData.push(...(await (0, postOperations_1.deleteLikeOperation)(agent, this.getNodeParameter('uri', i))));
145
190
  break;
146
191
  }
147
192
  case 'repost': {
148
- const uriRepost = this.getNodeParameter('uri', i);
149
- const cidRepost = this.getNodeParameter('cid', i);
150
- n8n_workflow_1.LoggerProxy.debug('Reposting', { ...itemMeta, uri: uriRepost, cidPresent: Boolean(cidRepost) });
151
- const repostData = await (0, postOperations_1.repostOperation)(agent, uriRepost, cidRepost);
152
- returnData.push(...repostData);
193
+ returnData.push(...(await (0, postOperations_1.repostOperation)(agent, this.getNodeParameter('uri', i), this.getNodeParameter('cid', i))));
153
194
  break;
154
195
  }
155
196
  case 'deleteRepost': {
156
- const uriDeleteRepost = this.getNodeParameter('uri', i);
157
- n8n_workflow_1.LoggerProxy.debug('Deleting repost', { ...itemMeta, uri: uriDeleteRepost });
158
- const deleteRepostData = await (0, postOperations_1.deleteRepostOperation)(agent, uriDeleteRepost);
159
- returnData.push(...deleteRepostData);
197
+ returnData.push(...(await (0, postOperations_1.deleteRepostOperation)(agent, this.getNodeParameter('uri', i))));
160
198
  break;
161
199
  }
162
200
  case 'getAuthorFeed': {
163
- const authorFeedActor = this.getNodeParameter('actor', i);
164
- const authorFeedPostLimit = this.getNodeParameter('limit', i);
165
- n8n_workflow_1.LoggerProxy.debug('Fetching author feed', {
166
- ...itemMeta,
167
- actor: authorFeedActor,
168
- limit: authorFeedPostLimit,
169
- });
170
- const feedData = await (0, feedOperations_1.getAuthorFeed)(agent, authorFeedActor, authorFeedPostLimit);
171
- returnData.push(...feedData);
201
+ returnData.push(...(await (0, feedOperations_1.getAuthorFeed)(agent, this.getNodeParameter('actor', i), this.getNodeParameter('limit', i), this.getNodeParameter('filter', i, '') || undefined)));
202
+ break;
203
+ }
204
+ case 'getPostThread': {
205
+ returnData.push(...(await (0, feedOperations_1.getPostThread)(agent, this.getNodeParameter('uri', i), this.getNodeParameter('depth', i), this.getNodeParameter('parentHeight', i))));
172
206
  break;
173
207
  }
174
208
  case 'getTimeline': {
175
- const timelinePostLimit = this.getNodeParameter('limit', i);
176
- n8n_workflow_1.LoggerProxy.debug('Fetching timeline', { ...itemMeta, limit: timelinePostLimit });
177
- const timelineData = await (0, feedOperations_1.getTimeline)(agent, timelinePostLimit);
178
- returnData.push(...timelineData);
209
+ returnData.push(...(await (0, feedOperations_1.getTimeline)(agent, this.getNodeParameter('limit', i))));
179
210
  break;
180
211
  }
181
212
  case 'getProfile': {
182
- const actor = this.getNodeParameter('actor', i);
183
- n8n_workflow_1.LoggerProxy.debug('Getting profile', { ...itemMeta, actor });
184
- const profileData = await (0, userOperations_1.getProfileOperation)(agent, actor);
185
- returnData.push(...profileData);
213
+ returnData.push(...(await (0, userOperations_1.getProfileOperation)(agent, this.getNodeParameter('actor', i))));
214
+ break;
215
+ }
216
+ case 'listAllFollowers': {
217
+ returnData.push(...(await (0, userOperations_1.listAllFollowersOperation)(agent, this.getNodeParameter('handle', i), this.getNodeParameter('maxResults', i), this.getNodeParameter('pageSize', i))));
218
+ break;
219
+ }
220
+ case 'listAllFollows': {
221
+ returnData.push(...(await (0, userOperations_1.listAllFollowsOperation)(agent, this.getNodeParameter('handle', i), this.getNodeParameter('maxResults', i), this.getNodeParameter('pageSize', i))));
186
222
  break;
187
223
  }
188
224
  case 'mute': {
189
- const didMute = this.getNodeParameter('did', i);
190
- n8n_workflow_1.LoggerProxy.info('Muting user', { ...itemMeta, did: didMute });
191
- const muteData = await (0, userOperations_1.muteOperation)(agent, didMute);
192
- returnData.push(...muteData);
225
+ returnData.push(...(await (0, userOperations_1.muteOperation)(agent, this.getNodeParameter('did', i))));
193
226
  break;
194
227
  }
195
228
  case 'unmute': {
196
- const didUnmute = this.getNodeParameter('did', i);
197
- n8n_workflow_1.LoggerProxy.info('Unmuting user', { ...itemMeta, did: didUnmute });
198
- const unmuteData = await (0, userOperations_1.unmuteOperation)(agent, didUnmute);
199
- returnData.push(...unmuteData);
229
+ returnData.push(...(await (0, userOperations_1.unmuteOperation)(agent, this.getNodeParameter('did', i))));
200
230
  break;
201
231
  }
202
232
  case 'block': {
203
- const didBlock = this.getNodeParameter('did', i);
204
- n8n_workflow_1.LoggerProxy.warn('Blocking user', { ...itemMeta, did: didBlock });
205
- const blockData = await (0, userOperations_1.blockOperation)(agent, didBlock);
206
- returnData.push(...blockData);
233
+ returnData.push(...(await (0, userOperations_1.blockOperation)(agent, this.getNodeParameter('did', i))));
207
234
  break;
208
235
  }
209
236
  case 'unblock': {
210
- const uriUnblock = this.getNodeParameter('uri', i);
211
- n8n_workflow_1.LoggerProxy.warn('Unblocking user', { ...itemMeta, uri: uriUnblock });
212
- const unblockData = await (0, userOperations_1.unblockOperation)(agent, uriUnblock);
213
- returnData.push(...unblockData);
237
+ returnData.push(...(await (0, userOperations_1.unblockOperation)(agent, this.getNodeParameter('uri', i))));
238
+ break;
239
+ }
240
+ case 'searchUsers': {
241
+ returnData.push(...(await (0, searchOperations_1.searchUsersOperation)(agent, this.getNodeParameter('q', i), this.getNodeParameter('limit', i))));
242
+ break;
243
+ }
244
+ case 'searchPosts': {
245
+ returnData.push(...(await (0, searchOperations_1.searchPostsOperation)(agent, this.getNodeParameter('q', i), this.getNodeParameter('limit', i), this.getNodeParameter('author', i, '') || undefined)));
246
+ break;
247
+ }
248
+ case 'muteThread': {
249
+ returnData.push(...(await (0, graphOperations_1.muteThreadOperation)(agent, this.getNodeParameter('uri', i))));
250
+ break;
251
+ }
252
+ case 'listNotifications': {
253
+ returnData.push(...(await (0, analyticsOperations_1.listNotificationsOperation)(agent, this.getNodeParameter('limit', i), this.getNodeParameter('unreadOnly', i), this.getNodeParameter('markRetrievedAsRead', i))));
254
+ break;
255
+ }
256
+ case 'getUnreadCount': {
257
+ returnData.push(...(await (0, analyticsOperations_1.getUnreadCountOperation)(agent)));
258
+ break;
259
+ }
260
+ case 'updateSeenNotifications': {
261
+ returnData.push(...(await (0, analyticsOperations_1.updateSeenNotificationsOperation)(agent, this.getNodeParameter('seenAt', i, '') || undefined)));
262
+ break;
263
+ }
264
+ case 'getPostInteractions': {
265
+ returnData.push(...(await (0, analyticsOperations_1.getPostInteractionsOperation)(agent, this.getNodeParameter('uri', i), this.getNodeParameter('interactionTypes', i), this.getNodeParameter('interactionLimit', i))));
266
+ break;
267
+ }
268
+ case 'createList': {
269
+ returnData.push(...(await (0, listOperations_1.createListOperation)(agent, this.getNodeParameter('name', i), this.getNodeParameter('purpose', i), this.getNodeParameter('description', i, '') || undefined)));
270
+ break;
271
+ }
272
+ case 'updateList': {
273
+ returnData.push(...(await (0, listOperations_1.updateListOperation)(agent, this.getNodeParameter('listUri', i), this.getNodeParameter('name', i), this.getNodeParameter('purpose', i), this.getNodeParameter('description', i, '') || undefined)));
274
+ break;
275
+ }
276
+ case 'deleteList': {
277
+ returnData.push(...(await (0, listOperations_1.deleteListOperation)(agent, this.getNodeParameter('listUri', i))));
278
+ break;
279
+ }
280
+ case 'getLists': {
281
+ returnData.push(...(await (0, listOperations_1.getListsOperation)(agent, this.getNodeParameter('actor', i), this.getNodeParameter('limit', i))));
282
+ break;
283
+ }
284
+ case 'getListFeed': {
285
+ returnData.push(...(await (0, listOperations_1.getListFeedOperation)(agent, this.getNodeParameter('listUri', i), this.getNodeParameter('limit', i))));
286
+ break;
287
+ }
288
+ case 'addUserToList': {
289
+ returnData.push(...(await (0, listOperations_1.addUserToListOperation)(agent, this.getNodeParameter('listUri', i), this.getNodeParameter('userDid', i))));
290
+ break;
291
+ }
292
+ case 'removeUserFromList': {
293
+ returnData.push(...(await (0, listOperations_1.removeUserFromListOperation)(agent, this.getNodeParameter('listItemUri', i))));
214
294
  break;
215
295
  }
216
296
  default:
@@ -229,7 +309,11 @@ class BlueskyV2 {
229
309
  throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
230
310
  }
231
311
  }
232
- n8n_workflow_1.LoggerProxy.info('Node execution finished', { ...nodeMeta, itemsProcessed: items.length, itemsReturned: returnData.length });
312
+ n8n_workflow_1.LoggerProxy.info('Node execution finished', {
313
+ ...nodeMeta,
314
+ itemsProcessed: items.length,
315
+ itemsReturned: returnData.length,
316
+ });
233
317
  return [returnData];
234
318
  }
235
319
  }