@dropinblog/n8n-nodes-dropinblog 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DropInBlog
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # n8n-nodes-dropinblog
2
+
3
+ This is an n8n community node. It lets you use [DropInBlog](https://dropinblog.com) in your n8n workflows.
4
+
5
+ DropInBlog is an SEO-friendly blog solution that embeds into any website.
6
+
7
+ [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
8
+
9
+ [Installation](#installation)
10
+ [Operations](#operations)
11
+ [Credentials](#credentials)
12
+ [Compatibility](#compatibility)
13
+ [Resources](#resources)
14
+
15
+ ## Installation
16
+
17
+ Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.
18
+
19
+ ## Operations
20
+
21
+ ### DropInBlog Node
22
+
23
+ - **Post**
24
+ - **Create** - Create a new blog post with title, content, and optional fields:
25
+ - Status
26
+ - Slug
27
+ - Featured image URL
28
+ - SEO title and description
29
+ - Keyword
30
+ - Author name
31
+ - Category names
32
+ - **Get** - Retrieve a post by its numeric ID or slug
33
+ - **Search** - Search blog posts with optional filters:
34
+ - Status (Draft/Published)
35
+ - Limit
36
+
37
+ ### DropInBlog Trigger Node
38
+
39
+ - **Post Published** - Triggers when a post is published in your DropInBlog
40
+
41
+ ## Credentials
42
+
43
+ This node uses OAuth2 authentication with DropInBlog. You'll need to:
44
+
45
+ 1. Contact [DropInBlog support](https://dropinblog.com/contact/) to request OAuth credentials for your account
46
+ 2. Configure the OAuth2 credentials in n8n with the Client ID and Client Secret provided
47
+ 3. Complete the OAuth authorization flow
48
+
49
+ ## Compatibility
50
+
51
+ Tested with n8n version 1.48.0 and above. Requires Node.js 18.10 or later.
52
+
53
+ ## Resources
54
+
55
+ * [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes)
56
+ * [DropInBlog API documentation](https://dropinblog.readme.io/reference/api-reference)
57
+ * [DropInBlog website](https://dropinblog.com)
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class DropInBlogOAuth2Api implements ICredentialType {
3
+ name: string;
4
+ extends: string[];
5
+ displayName: string;
6
+ documentationUrl: string;
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DropInBlogOAuth2Api = void 0;
4
+ const constants_1 = require("../nodes/DropInBlog/constants");
5
+ class DropInBlogOAuth2Api {
6
+ constructor() {
7
+ this.name = 'dropInBlogOAuth2Api';
8
+ this.extends = ['oAuth2Api'];
9
+ this.displayName = 'DropInBlog OAuth2 API';
10
+ this.documentationUrl = 'https://dropinblog.com/docs/api';
11
+ this.properties = [
12
+ {
13
+ displayName: 'Grant Type',
14
+ name: 'grantType',
15
+ type: 'hidden',
16
+ default: 'authorizationCode',
17
+ },
18
+ {
19
+ displayName: 'Authorization URL',
20
+ name: 'authUrl',
21
+ type: 'hidden',
22
+ default: 'https://app.dropinblog.com/oauth/authorize',
23
+ },
24
+ {
25
+ displayName: 'Access Token URL',
26
+ name: 'accessTokenUrl',
27
+ type: 'hidden',
28
+ default: `${constants_1.API_BASE_URL}/oauth/token`,
29
+ },
30
+ {
31
+ displayName: 'Scope',
32
+ name: 'scope',
33
+ type: 'hidden',
34
+ default: '',
35
+ },
36
+ {
37
+ displayName: 'Auth URI Query Parameters',
38
+ name: 'authQueryParameters',
39
+ type: 'hidden',
40
+ default: '',
41
+ },
42
+ {
43
+ displayName: 'Authentication',
44
+ name: 'authentication',
45
+ type: 'hidden',
46
+ default: 'body',
47
+ },
48
+ ];
49
+ this.authenticate = {
50
+ type: 'generic',
51
+ properties: {
52
+ headers: {
53
+ Authorization: '=Bearer {{$credentials.oauthTokenData.access_token}}',
54
+ },
55
+ },
56
+ };
57
+ this.test = {
58
+ request: {
59
+ baseURL: constants_1.API_BASE_URL,
60
+ url: '/v2/automations/blogs',
61
+ },
62
+ };
63
+ }
64
+ }
65
+ exports.DropInBlogOAuth2Api = DropInBlogOAuth2Api;
@@ -0,0 +1,12 @@
1
+ import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ import { getBlogs } from './GenericFunctions';
3
+ export declare class DropInBlog implements INodeType {
4
+ description: INodeTypeDescription;
5
+ methods: {
6
+ loadOptions: {
7
+ getBlogs: typeof getBlogs;
8
+ getStatuses(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
9
+ };
10
+ };
11
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
12
+ }
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DropInBlog = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const constants_1 = require("./constants");
6
+ const GenericFunctions_1 = require("./GenericFunctions");
7
+ class DropInBlog {
8
+ constructor() {
9
+ this.description = {
10
+ displayName: 'DropInBlog',
11
+ name: 'dropInBlog',
12
+ icon: 'file:logo.svg',
13
+ group: ['transform'],
14
+ version: 1,
15
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
16
+ description: 'Interact with DropInBlog',
17
+ defaults: {
18
+ name: 'DropInBlog',
19
+ },
20
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
21
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
22
+ credentials: [
23
+ {
24
+ name: 'dropInBlogOAuth2Api',
25
+ required: true,
26
+ },
27
+ ],
28
+ properties: [
29
+ {
30
+ displayName: 'Resource',
31
+ name: 'resource',
32
+ type: 'options',
33
+ noDataExpression: true,
34
+ options: [
35
+ {
36
+ name: 'Post',
37
+ value: 'post',
38
+ },
39
+ ],
40
+ default: 'post',
41
+ description: 'The resource to operate on',
42
+ },
43
+ {
44
+ displayName: 'Operation',
45
+ name: 'operation',
46
+ type: 'options',
47
+ noDataExpression: true,
48
+ displayOptions: {
49
+ show: {
50
+ resource: ['post'],
51
+ },
52
+ },
53
+ options: [
54
+ {
55
+ name: 'Create',
56
+ value: 'create',
57
+ description: 'Create a new blog post',
58
+ action: 'Create a post',
59
+ },
60
+ {
61
+ name: 'Get',
62
+ value: 'get',
63
+ description: 'Get a post by ID or slug',
64
+ action: 'Get a post',
65
+ },
66
+ {
67
+ name: 'Search',
68
+ value: 'search',
69
+ description: 'Search blog posts',
70
+ action: 'Search posts',
71
+ },
72
+ ],
73
+ default: 'create',
74
+ },
75
+ // Blog ID (shared by create, get, and search)
76
+ {
77
+ displayName: 'Blog',
78
+ name: 'blogId',
79
+ type: 'options',
80
+ typeOptions: {
81
+ loadOptionsMethod: 'getBlogs',
82
+ },
83
+ required: true,
84
+ default: '',
85
+ displayOptions: {
86
+ show: {
87
+ resource: ['post'],
88
+ operation: ['create', 'get', 'search'],
89
+ },
90
+ },
91
+ description: 'The blog to work with. Choose from the list.',
92
+ },
93
+ // Post ID or Slug (get only)
94
+ {
95
+ displayName: 'Post ID or Slug',
96
+ name: 'postIdentifier',
97
+ type: 'string',
98
+ required: true,
99
+ default: '',
100
+ displayOptions: {
101
+ show: {
102
+ resource: ['post'],
103
+ operation: ['get'],
104
+ },
105
+ },
106
+ description: 'The numeric ID or slug of the post to retrieve',
107
+ },
108
+ // Title (create only)
109
+ {
110
+ displayName: 'Title',
111
+ name: 'title',
112
+ type: 'string',
113
+ required: true,
114
+ default: '',
115
+ displayOptions: {
116
+ show: {
117
+ resource: ['post'],
118
+ operation: ['create'],
119
+ },
120
+ },
121
+ description: 'The title of the post',
122
+ },
123
+ // Content (create only)
124
+ {
125
+ displayName: 'Content',
126
+ name: 'content',
127
+ type: 'string',
128
+ typeOptions: {
129
+ rows: 10,
130
+ },
131
+ required: true,
132
+ default: '',
133
+ displayOptions: {
134
+ show: {
135
+ resource: ['post'],
136
+ operation: ['create'],
137
+ },
138
+ },
139
+ description: 'The HTML content of the post',
140
+ },
141
+ // Search Query (search only)
142
+ {
143
+ displayName: 'Search Query',
144
+ name: 'search',
145
+ type: 'string',
146
+ required: true,
147
+ default: '',
148
+ displayOptions: {
149
+ show: {
150
+ resource: ['post'],
151
+ operation: ['search'],
152
+ },
153
+ },
154
+ description: 'The search query to find posts',
155
+ },
156
+ // Additional Fields (create only)
157
+ {
158
+ displayName: 'Additional Fields',
159
+ name: 'additionalFields',
160
+ type: 'collection',
161
+ placeholder: 'Add Field',
162
+ default: {},
163
+ displayOptions: {
164
+ show: {
165
+ resource: ['post'],
166
+ operation: ['create'],
167
+ },
168
+ },
169
+ options: [
170
+ {
171
+ displayName: 'Author Name',
172
+ name: 'author_name',
173
+ type: 'string',
174
+ default: '',
175
+ description: 'The name of the author (will create or find existing author by name)',
176
+ },
177
+ {
178
+ displayName: 'Category Names',
179
+ name: 'category_names',
180
+ type: 'string',
181
+ default: '',
182
+ description: 'Comma separated list of category names to attach to your post (will create categories if they do not exist)',
183
+ },
184
+ {
185
+ displayName: 'Featured Image URL',
186
+ name: 'featured_image',
187
+ type: 'string',
188
+ default: '',
189
+ description: 'URL of the featured image',
190
+ },
191
+ {
192
+ displayName: 'Keyword',
193
+ name: 'keyword',
194
+ type: 'string',
195
+ default: '',
196
+ description: 'Primary SEO keyword for the post',
197
+ },
198
+ {
199
+ displayName: 'SEO Title',
200
+ name: 'seo_title',
201
+ type: 'string',
202
+ default: '',
203
+ description: 'Meta title for SEO (defaults to post title)',
204
+ },
205
+ {
206
+ displayName: 'SEO Description',
207
+ name: 'seo_description',
208
+ type: 'string',
209
+ typeOptions: {
210
+ rows: 3,
211
+ },
212
+ default: '',
213
+ description: 'Meta description for SEO',
214
+ },
215
+ {
216
+ displayName: 'Slug',
217
+ name: 'slug',
218
+ type: 'string',
219
+ default: '',
220
+ description: 'URL slug for the post (auto generated from title if not provided)',
221
+ },
222
+ {
223
+ displayName: 'Status',
224
+ name: 'status_id',
225
+ type: 'options',
226
+ typeOptions: {
227
+ loadOptionsMethod: 'getStatuses',
228
+ },
229
+ default: '',
230
+ description: 'The status of the post. Choose from the list.',
231
+ },
232
+ ],
233
+ },
234
+ // Search Filters (search only)
235
+ {
236
+ displayName: 'Filters',
237
+ name: 'searchFilters',
238
+ type: 'collection',
239
+ placeholder: 'Add Filter',
240
+ default: {},
241
+ displayOptions: {
242
+ show: {
243
+ resource: ['post'],
244
+ operation: ['search'],
245
+ },
246
+ },
247
+ options: [
248
+ {
249
+ displayName: 'Status',
250
+ name: 'status',
251
+ type: 'options',
252
+ options: [
253
+ {
254
+ name: 'Draft',
255
+ value: 'draft',
256
+ },
257
+ {
258
+ name: 'Published',
259
+ value: 'published',
260
+ },
261
+ ],
262
+ default: '',
263
+ description: 'Filter by post status',
264
+ },
265
+ {
266
+ displayName: 'Limit',
267
+ name: 'limit',
268
+ type: 'number',
269
+ typeOptions: {
270
+ minValue: 1,
271
+ maxValue: 50,
272
+ },
273
+ default: 20,
274
+ description: 'Max number of results to return (max 50)',
275
+ },
276
+ ],
277
+ },
278
+ ],
279
+ };
280
+ this.methods = {
281
+ loadOptions: {
282
+ getBlogs: GenericFunctions_1.getBlogs,
283
+ async getStatuses() {
284
+ const returnData = [];
285
+ const statuses = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
286
+ method: 'GET',
287
+ url: `${constants_1.API_BASE_URL}/v2/automations/statuses`,
288
+ json: true,
289
+ });
290
+ for (const status of statuses) {
291
+ returnData.push({
292
+ name: status.name,
293
+ value: status.id,
294
+ });
295
+ }
296
+ return returnData;
297
+ },
298
+ },
299
+ };
300
+ }
301
+ async execute() {
302
+ const items = this.getInputData();
303
+ const returnData = [];
304
+ for (let i = 0; i < items.length; i++) {
305
+ try {
306
+ const resource = this.getNodeParameter('resource', i);
307
+ const operation = this.getNodeParameter('operation', i);
308
+ if (resource === 'post') {
309
+ if (operation === 'create') {
310
+ const blogId = this.getNodeParameter('blogId', i);
311
+ const title = this.getNodeParameter('title', i);
312
+ const content = this.getNodeParameter('content', i);
313
+ const additionalFields = this.getNodeParameter('additionalFields', i);
314
+ const body = {
315
+ title,
316
+ content,
317
+ ...Object.fromEntries(Object.entries(additionalFields).filter(([, v]) => v !== undefined && v !== '')),
318
+ };
319
+ // the write endpoint for posts
320
+ const response = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
321
+ method: 'POST',
322
+ url: `${constants_1.API_BASE_URL}/v2/blog/${blogId}/posts`,
323
+ body,
324
+ json: true,
325
+ });
326
+ const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(response), { itemData: { item: i } });
327
+ returnData.push(...executionData);
328
+ }
329
+ else if (operation === 'get') {
330
+ const blogId = this.getNodeParameter('blogId', i);
331
+ const postIdentifier = this.getNodeParameter('postIdentifier', i);
332
+ // the read endpoint for individual posts
333
+ const response = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
334
+ method: 'GET',
335
+ url: `${constants_1.API_BASE_URL}/v2/automations/${blogId}/posts/${encodeURIComponent(postIdentifier)}`,
336
+ json: true,
337
+ });
338
+ const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(response), { itemData: { item: i } });
339
+ returnData.push(...executionData);
340
+ }
341
+ else if (operation === 'search') {
342
+ const blogId = this.getNodeParameter('blogId', i);
343
+ const search = this.getNodeParameter('search', i);
344
+ const searchFilters = this.getNodeParameter('searchFilters', i);
345
+ const qs = { search };
346
+ if (searchFilters.status) {
347
+ qs.status = searchFilters.status;
348
+ }
349
+ if (searchFilters.limit) {
350
+ qs.limit = searchFilters.limit;
351
+ }
352
+ // the read/search endpoint for posts
353
+ const response = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
354
+ method: 'GET',
355
+ url: `${constants_1.API_BASE_URL}/v2/automations/${blogId}/posts/search`,
356
+ qs,
357
+ json: true,
358
+ });
359
+ const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(response), { itemData: { item: i } });
360
+ returnData.push(...executionData);
361
+ }
362
+ }
363
+ }
364
+ catch (error) {
365
+ if (this.continueOnFail()) {
366
+ const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray({ error: error.message }), { itemData: { item: i } });
367
+ returnData.push(...executionData);
368
+ continue;
369
+ }
370
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
371
+ }
372
+ }
373
+ return [returnData];
374
+ }
375
+ }
376
+ exports.DropInBlog = DropInBlog;
@@ -0,0 +1,18 @@
1
+ import type { IHookFunctions, INodeType, INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
2
+ import { getBlogs } from './GenericFunctions';
3
+ export declare class DropInBlogTrigger implements INodeType {
4
+ description: INodeTypeDescription;
5
+ methods: {
6
+ loadOptions: {
7
+ getBlogs: typeof getBlogs;
8
+ };
9
+ };
10
+ webhookMethods: {
11
+ default: {
12
+ checkExists(this: IHookFunctions): Promise<boolean>;
13
+ create(this: IHookFunctions): Promise<boolean>;
14
+ delete(this: IHookFunctions): Promise<boolean>;
15
+ };
16
+ };
17
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
18
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DropInBlogTrigger = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const constants_1 = require("./constants");
6
+ const GenericFunctions_1 = require("./GenericFunctions");
7
+ class DropInBlogTrigger {
8
+ constructor() {
9
+ this.description = {
10
+ displayName: 'DropInBlog Trigger',
11
+ name: 'dropInBlogTrigger',
12
+ icon: 'file:logo.svg',
13
+ group: ['trigger'],
14
+ version: 1,
15
+ subtitle: '={{$parameter["event"]}}',
16
+ description: 'Starts the workflow when a DropInBlog event occurs',
17
+ defaults: {
18
+ name: 'DropInBlog Trigger',
19
+ },
20
+ inputs: [],
21
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
22
+ credentials: [
23
+ {
24
+ name: 'dropInBlogOAuth2Api',
25
+ required: true,
26
+ },
27
+ ],
28
+ webhooks: [
29
+ {
30
+ name: 'default',
31
+ httpMethod: 'POST',
32
+ responseMode: 'onReceived',
33
+ path: 'webhook',
34
+ },
35
+ ],
36
+ properties: [
37
+ {
38
+ displayName: 'Blog',
39
+ name: 'blogId',
40
+ type: 'options',
41
+ typeOptions: {
42
+ loadOptionsMethod: 'getBlogs',
43
+ },
44
+ required: true,
45
+ default: '',
46
+ description: 'The blog to listen for events from. Choose from the list.',
47
+ },
48
+ {
49
+ displayName: 'Event',
50
+ name: 'event',
51
+ type: 'options',
52
+ required: true,
53
+ default: 'post.published',
54
+ options: [
55
+ {
56
+ name: 'Post Published',
57
+ value: 'post.published',
58
+ description: 'Triggers when a post is published',
59
+ },
60
+ ],
61
+ description: 'The event to listen for',
62
+ },
63
+ ],
64
+ };
65
+ this.methods = {
66
+ loadOptions: {
67
+ getBlogs: GenericFunctions_1.getBlogs,
68
+ },
69
+ };
70
+ this.webhookMethods = {
71
+ default: {
72
+ async checkExists() {
73
+ const webhookData = this.getWorkflowStaticData('node');
74
+ if (webhookData.webhookId === undefined) {
75
+ return false;
76
+ }
77
+ return true;
78
+ },
79
+ async create() {
80
+ const webhookUrl = this.getNodeWebhookUrl('default');
81
+ const blogId = this.getNodeParameter('blogId');
82
+ const event = this.getNodeParameter('event');
83
+ const body = {
84
+ hookUrl: webhookUrl,
85
+ // The API expects events as a JSON-stringified array (intentional double-serialization)
86
+ events: JSON.stringify([event]),
87
+ source: 'n8n',
88
+ };
89
+ const response = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
90
+ method: 'POST',
91
+ url: `${constants_1.API_BASE_URL}/v2/blog/${blogId}/webhooks`,
92
+ body,
93
+ json: true,
94
+ });
95
+ if (response.hookId === undefined) {
96
+ return false;
97
+ }
98
+ const webhookData = this.getWorkflowStaticData('node');
99
+ webhookData.webhookId = response.hookId;
100
+ webhookData.blogId = blogId;
101
+ return true;
102
+ },
103
+ async delete() {
104
+ const webhookData = this.getWorkflowStaticData('node');
105
+ if (webhookData.webhookId !== undefined) {
106
+ try {
107
+ await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
108
+ method: 'DELETE',
109
+ url: `${constants_1.API_BASE_URL}/v2/blog/${webhookData.blogId}/webhooks/${webhookData.webhookId}`,
110
+ json: true,
111
+ });
112
+ delete webhookData.webhookId;
113
+ delete webhookData.blogId;
114
+ }
115
+ catch (error) {
116
+ return false;
117
+ }
118
+ }
119
+ return true;
120
+ },
121
+ },
122
+ };
123
+ }
124
+ async webhook() {
125
+ const bodyData = this.getBodyData();
126
+ return {
127
+ workflowData: [this.helpers.returnJsonArray(bodyData)],
128
+ };
129
+ }
130
+ }
131
+ exports.DropInBlogTrigger = DropInBlogTrigger;
@@ -0,0 +1,2 @@
1
+ import type { ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
2
+ export declare function getBlogs(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBlogs = getBlogs;
4
+ const constants_1 = require("./constants");
5
+ async function getBlogs() {
6
+ const returnData = [];
7
+ const blogs = await this.helpers.requestWithAuthentication.call(this, 'dropInBlogOAuth2Api', {
8
+ method: 'GET',
9
+ url: `${constants_1.API_BASE_URL}/v2/automations/blogs`,
10
+ json: true,
11
+ });
12
+ for (const blog of blogs) {
13
+ returnData.push({
14
+ name: blog.name,
15
+ value: blog.id,
16
+ });
17
+ }
18
+ return returnData;
19
+ }
@@ -0,0 +1 @@
1
+ export declare const API_BASE_URL = "https://api.dropinblog.com";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.API_BASE_URL = void 0;
4
+ exports.API_BASE_URL = 'https://api.dropinblog.com';
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="#ed254e" d="M0 0h1024v1024H0z"/><path fill="#fff" d="M245 717s232-165 493-205c-261-40-493-205-493-205h391l205 205-205 205Z"/></svg>
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ // This file is required for the package to work correctly
2
+ // The actual exports are handled by the n8n configuration in package.json
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@dropinblog/n8n-nodes-dropinblog",
3
+ "version": "1.0.0",
4
+ "description": "n8n community node for DropInBlog - Create posts and receive webhook notifications when posts are published",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "dropinblog",
9
+ "blog",
10
+ "cms"
11
+ ],
12
+ "license": "MIT",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "homepage": "https://dropinblog.com",
17
+ "author": {
18
+ "name": "DropInBlog"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/DropInBlog/n8n-nodes.git"
23
+ },
24
+ "engines": {
25
+ "node": ">=18.10",
26
+ "pnpm": ">=9.1"
27
+ },
28
+ "packageManager": "pnpm@9.1.4",
29
+ "main": "index.js",
30
+ "scripts": {
31
+ "preinstall": "npx only-allow pnpm",
32
+ "build": "tsc && gulp build:icons",
33
+ "dev": "tsc --watch",
34
+ "format": "prettier nodes/**/*.ts credentials/**/*.ts --write",
35
+ "lint": "eslint nodes/**/*.ts credentials/**/*.ts package.json",
36
+ "lintfix": "eslint nodes/**/*.ts credentials/**/*.ts package.json --fix",
37
+ "prepublishOnly": "pnpm build && pnpm lint -c .eslintrc.prepublish.js nodes/**/*.ts credentials/**/*.ts"
38
+ },
39
+ "files": [
40
+ "dist"
41
+ ],
42
+ "n8n": {
43
+ "n8nNodesApiVersion": 1,
44
+ "credentials": [
45
+ "dist/credentials/DropInBlogOAuth2Api.credentials.js"
46
+ ],
47
+ "nodes": [
48
+ "dist/nodes/DropInBlog/DropInBlog.node.js",
49
+ "dist/nodes/DropInBlog/DropInBlogTrigger.node.js"
50
+ ]
51
+ },
52
+ "devDependencies": {
53
+ "@typescript-eslint/parser": "^7.15.0",
54
+ "eslint": "^8.56.0",
55
+ "eslint-plugin-n8n-nodes-base": "^1.16.1",
56
+ "gulp": "^4.0.2",
57
+ "n8n-workflow": "^1.48.0",
58
+ "prettier": "^3.3.2",
59
+ "typescript": "^5.5.3"
60
+ },
61
+ "peerDependencies": {
62
+ "n8n-workflow": "*"
63
+ }
64
+ }