n8n-nodes-sendit 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/dist/credentials/SendItApi.credentials.d.ts +9 -0
- package/dist/credentials/SendItApi.credentials.js +38 -0
- package/dist/nodes/SendIt/SendIt.node.d.ts +5 -0
- package/dist/nodes/SendIt/SendIt.node.js +432 -0
- package/dist/nodes/SendIt/SendItTrigger.node.d.ts +12 -0
- package/dist/nodes/SendIt/SendItTrigger.node.js +150 -0
- package/package.json +58 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class SendItApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SendItApi = void 0;
|
|
4
|
+
class SendItApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'sendItApi';
|
|
7
|
+
this.displayName = 'SendIt API';
|
|
8
|
+
this.documentationUrl = 'https://sendit.infiniteappsai.com/docs/api';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'API Key',
|
|
12
|
+
name: 'apiKey',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: {
|
|
15
|
+
password: true,
|
|
16
|
+
},
|
|
17
|
+
default: '',
|
|
18
|
+
required: true,
|
|
19
|
+
description: 'Your SendIt API key (starts with sk_live_). Get it from your SendIt Dashboard.',
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
this.authenticate = {
|
|
23
|
+
type: 'generic',
|
|
24
|
+
properties: {
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: '={{"Bearer " + $credentials.apiKey}}',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
this.test = {
|
|
31
|
+
request: {
|
|
32
|
+
baseURL: 'https://sendit.infiniteappsai.com/api/v1',
|
|
33
|
+
url: '/accounts',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.SendItApi = SendItApi;
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SendIt = void 0;
|
|
4
|
+
class SendIt {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.description = {
|
|
7
|
+
displayName: 'SendIt',
|
|
8
|
+
name: 'sendIt',
|
|
9
|
+
icon: 'file:sendit.svg',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
13
|
+
description: 'Multi-platform social media publishing',
|
|
14
|
+
defaults: {
|
|
15
|
+
name: 'SendIt',
|
|
16
|
+
},
|
|
17
|
+
inputs: ['main'],
|
|
18
|
+
outputs: ['main'],
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'sendItApi',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
requestDefaults: {
|
|
26
|
+
baseURL: 'https://sendit.infiniteappsai.com/api/v1',
|
|
27
|
+
headers: {
|
|
28
|
+
Accept: 'application/json',
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
properties: [
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Resource',
|
|
35
|
+
name: 'resource',
|
|
36
|
+
type: 'options',
|
|
37
|
+
noDataExpression: true,
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: 'Post',
|
|
41
|
+
value: 'post',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Scheduled Post',
|
|
45
|
+
value: 'scheduledPost',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'Account',
|
|
49
|
+
value: 'account',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'Validation',
|
|
53
|
+
value: 'validation',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
default: 'post',
|
|
57
|
+
},
|
|
58
|
+
// Post operations
|
|
59
|
+
{
|
|
60
|
+
displayName: 'Operation',
|
|
61
|
+
name: 'operation',
|
|
62
|
+
type: 'options',
|
|
63
|
+
noDataExpression: true,
|
|
64
|
+
displayOptions: {
|
|
65
|
+
show: {
|
|
66
|
+
resource: ['post'],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
options: [
|
|
70
|
+
{
|
|
71
|
+
name: 'Publish',
|
|
72
|
+
value: 'publish',
|
|
73
|
+
description: 'Publish content to social media platforms immediately',
|
|
74
|
+
action: 'Publish a post',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
default: 'publish',
|
|
78
|
+
},
|
|
79
|
+
// Scheduled Post operations
|
|
80
|
+
{
|
|
81
|
+
displayName: 'Operation',
|
|
82
|
+
name: 'operation',
|
|
83
|
+
type: 'options',
|
|
84
|
+
noDataExpression: true,
|
|
85
|
+
displayOptions: {
|
|
86
|
+
show: {
|
|
87
|
+
resource: ['scheduledPost'],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
options: [
|
|
91
|
+
{
|
|
92
|
+
name: 'Create',
|
|
93
|
+
value: 'create',
|
|
94
|
+
description: 'Schedule a post for future publishing',
|
|
95
|
+
action: 'Schedule a post',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'Get All',
|
|
99
|
+
value: 'getAll',
|
|
100
|
+
description: 'Get all scheduled posts',
|
|
101
|
+
action: 'Get all scheduled posts',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'Delete',
|
|
105
|
+
value: 'delete',
|
|
106
|
+
description: 'Cancel a scheduled post',
|
|
107
|
+
action: 'Cancel a scheduled post',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'Trigger Now',
|
|
111
|
+
value: 'trigger',
|
|
112
|
+
description: 'Publish a scheduled post immediately',
|
|
113
|
+
action: 'Trigger scheduled post now',
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
default: 'create',
|
|
117
|
+
},
|
|
118
|
+
// Account operations
|
|
119
|
+
{
|
|
120
|
+
displayName: 'Operation',
|
|
121
|
+
name: 'operation',
|
|
122
|
+
type: 'options',
|
|
123
|
+
noDataExpression: true,
|
|
124
|
+
displayOptions: {
|
|
125
|
+
show: {
|
|
126
|
+
resource: ['account'],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
options: [
|
|
130
|
+
{
|
|
131
|
+
name: 'Get All',
|
|
132
|
+
value: 'getAll',
|
|
133
|
+
description: 'Get all connected accounts',
|
|
134
|
+
action: 'Get all accounts',
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
default: 'getAll',
|
|
138
|
+
},
|
|
139
|
+
// Validation operations
|
|
140
|
+
{
|
|
141
|
+
displayName: 'Operation',
|
|
142
|
+
name: 'operation',
|
|
143
|
+
type: 'options',
|
|
144
|
+
noDataExpression: true,
|
|
145
|
+
displayOptions: {
|
|
146
|
+
show: {
|
|
147
|
+
resource: ['validation'],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
options: [
|
|
151
|
+
{
|
|
152
|
+
name: 'Validate',
|
|
153
|
+
value: 'validate',
|
|
154
|
+
description: 'Validate content before publishing',
|
|
155
|
+
action: 'Validate content',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
default: 'validate',
|
|
159
|
+
},
|
|
160
|
+
// Platforms field
|
|
161
|
+
{
|
|
162
|
+
displayName: 'Platforms',
|
|
163
|
+
name: 'platforms',
|
|
164
|
+
type: 'multiOptions',
|
|
165
|
+
options: [
|
|
166
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
167
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
168
|
+
{ name: 'Threads', value: 'threads' },
|
|
169
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
170
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
171
|
+
],
|
|
172
|
+
default: [],
|
|
173
|
+
required: true,
|
|
174
|
+
displayOptions: {
|
|
175
|
+
show: {
|
|
176
|
+
resource: ['post', 'scheduledPost', 'validation'],
|
|
177
|
+
operation: ['publish', 'create', 'validate'],
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
description: 'Select platforms to publish to',
|
|
181
|
+
},
|
|
182
|
+
// Text content
|
|
183
|
+
{
|
|
184
|
+
displayName: 'Text',
|
|
185
|
+
name: 'text',
|
|
186
|
+
type: 'string',
|
|
187
|
+
typeOptions: {
|
|
188
|
+
rows: 4,
|
|
189
|
+
},
|
|
190
|
+
default: '',
|
|
191
|
+
required: true,
|
|
192
|
+
displayOptions: {
|
|
193
|
+
show: {
|
|
194
|
+
resource: ['post', 'scheduledPost', 'validation'],
|
|
195
|
+
operation: ['publish', 'create', 'validate'],
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
description: 'The text content of your post',
|
|
199
|
+
},
|
|
200
|
+
// Media URL
|
|
201
|
+
{
|
|
202
|
+
displayName: 'Media URL',
|
|
203
|
+
name: 'mediaUrl',
|
|
204
|
+
type: 'string',
|
|
205
|
+
default: '',
|
|
206
|
+
displayOptions: {
|
|
207
|
+
show: {
|
|
208
|
+
resource: ['post', 'scheduledPost', 'validation'],
|
|
209
|
+
operation: ['publish', 'create', 'validate'],
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
description: 'URL to an image or video (required for Instagram and TikTok)',
|
|
213
|
+
},
|
|
214
|
+
// Scheduled Time
|
|
215
|
+
{
|
|
216
|
+
displayName: 'Scheduled Time',
|
|
217
|
+
name: 'scheduledTime',
|
|
218
|
+
type: 'dateTime',
|
|
219
|
+
default: '',
|
|
220
|
+
required: true,
|
|
221
|
+
displayOptions: {
|
|
222
|
+
show: {
|
|
223
|
+
resource: ['scheduledPost'],
|
|
224
|
+
operation: ['create'],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
description: 'When to publish the post',
|
|
228
|
+
},
|
|
229
|
+
// Schedule ID
|
|
230
|
+
{
|
|
231
|
+
displayName: 'Schedule ID',
|
|
232
|
+
name: 'scheduleId',
|
|
233
|
+
type: 'string',
|
|
234
|
+
default: '',
|
|
235
|
+
required: true,
|
|
236
|
+
displayOptions: {
|
|
237
|
+
show: {
|
|
238
|
+
resource: ['scheduledPost'],
|
|
239
|
+
operation: ['delete', 'trigger'],
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
description: 'The ID of the scheduled post',
|
|
243
|
+
},
|
|
244
|
+
// Platform filter
|
|
245
|
+
{
|
|
246
|
+
displayName: 'Platform Filter',
|
|
247
|
+
name: 'platformFilter',
|
|
248
|
+
type: 'options',
|
|
249
|
+
options: [
|
|
250
|
+
{ name: 'All Platforms', value: '' },
|
|
251
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
252
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
253
|
+
{ name: 'Threads', value: 'threads' },
|
|
254
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
255
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
256
|
+
],
|
|
257
|
+
default: '',
|
|
258
|
+
displayOptions: {
|
|
259
|
+
show: {
|
|
260
|
+
resource: ['scheduledPost'],
|
|
261
|
+
operation: ['getAll'],
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
description: 'Filter scheduled posts by platform',
|
|
265
|
+
},
|
|
266
|
+
// Additional options
|
|
267
|
+
{
|
|
268
|
+
displayName: 'Additional Options',
|
|
269
|
+
name: 'additionalOptions',
|
|
270
|
+
type: 'collection',
|
|
271
|
+
placeholder: 'Add Option',
|
|
272
|
+
default: {},
|
|
273
|
+
displayOptions: {
|
|
274
|
+
show: {
|
|
275
|
+
resource: ['post', 'validation'],
|
|
276
|
+
operation: ['publish', 'validate'],
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
options: [
|
|
280
|
+
{
|
|
281
|
+
displayName: 'Media URLs (for carousel)',
|
|
282
|
+
name: 'mediaUrls',
|
|
283
|
+
type: 'string',
|
|
284
|
+
default: '',
|
|
285
|
+
description: 'Comma-separated URLs for carousel posts',
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
displayName: 'Media Type',
|
|
289
|
+
name: 'mediaType',
|
|
290
|
+
type: 'options',
|
|
291
|
+
options: [
|
|
292
|
+
{ name: 'Auto-detect', value: 'auto' },
|
|
293
|
+
{ name: 'Image', value: 'image' },
|
|
294
|
+
{ name: 'Video', value: 'video' },
|
|
295
|
+
],
|
|
296
|
+
default: 'auto',
|
|
297
|
+
description: 'Specify the media type',
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
async execute() {
|
|
305
|
+
const items = this.getInputData();
|
|
306
|
+
const returnData = [];
|
|
307
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
308
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
309
|
+
for (let i = 0; i < items.length; i++) {
|
|
310
|
+
try {
|
|
311
|
+
let response;
|
|
312
|
+
if (resource === 'post') {
|
|
313
|
+
if (operation === 'publish') {
|
|
314
|
+
const platforms = this.getNodeParameter('platforms', i);
|
|
315
|
+
const text = this.getNodeParameter('text', i);
|
|
316
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
317
|
+
const additionalOptions = this.getNodeParameter('additionalOptions', i);
|
|
318
|
+
const body = {
|
|
319
|
+
platforms,
|
|
320
|
+
content: {
|
|
321
|
+
text,
|
|
322
|
+
mediaUrl: mediaUrl || undefined,
|
|
323
|
+
mediaUrls: additionalOptions.mediaUrls
|
|
324
|
+
? additionalOptions.mediaUrls.split(',').map((u) => u.trim())
|
|
325
|
+
: undefined,
|
|
326
|
+
mediaType: additionalOptions.mediaType || 'auto',
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
330
|
+
method: 'POST',
|
|
331
|
+
url: '/publish',
|
|
332
|
+
body,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else if (resource === 'scheduledPost') {
|
|
337
|
+
if (operation === 'create') {
|
|
338
|
+
const platforms = this.getNodeParameter('platforms', i);
|
|
339
|
+
const text = this.getNodeParameter('text', i);
|
|
340
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
341
|
+
const scheduledTime = this.getNodeParameter('scheduledTime', i);
|
|
342
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
343
|
+
method: 'POST',
|
|
344
|
+
url: '/schedule',
|
|
345
|
+
body: {
|
|
346
|
+
platforms,
|
|
347
|
+
content: {
|
|
348
|
+
text,
|
|
349
|
+
mediaUrl: mediaUrl || undefined,
|
|
350
|
+
},
|
|
351
|
+
scheduledTime,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
else if (operation === 'getAll') {
|
|
356
|
+
const platformFilter = this.getNodeParameter('platformFilter', i);
|
|
357
|
+
const qs = {};
|
|
358
|
+
if (platformFilter) {
|
|
359
|
+
qs.platform = platformFilter;
|
|
360
|
+
}
|
|
361
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
362
|
+
method: 'GET',
|
|
363
|
+
url: '/scheduled',
|
|
364
|
+
qs,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
else if (operation === 'delete') {
|
|
368
|
+
const scheduleId = this.getNodeParameter('scheduleId', i);
|
|
369
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
370
|
+
method: 'DELETE',
|
|
371
|
+
url: `/scheduled/${scheduleId}`,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
else if (operation === 'trigger') {
|
|
375
|
+
const scheduleId = this.getNodeParameter('scheduleId', i);
|
|
376
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
377
|
+
method: 'POST',
|
|
378
|
+
url: `/scheduled/${scheduleId}/trigger`,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else if (resource === 'account') {
|
|
383
|
+
if (operation === 'getAll') {
|
|
384
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
385
|
+
method: 'GET',
|
|
386
|
+
url: '/accounts',
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
else if (resource === 'validation') {
|
|
391
|
+
if (operation === 'validate') {
|
|
392
|
+
const platforms = this.getNodeParameter('platforms', i);
|
|
393
|
+
const text = this.getNodeParameter('text', i);
|
|
394
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
395
|
+
const additionalOptions = this.getNodeParameter('additionalOptions', i);
|
|
396
|
+
response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
397
|
+
method: 'POST',
|
|
398
|
+
url: '/validate',
|
|
399
|
+
body: {
|
|
400
|
+
platforms,
|
|
401
|
+
content: {
|
|
402
|
+
text,
|
|
403
|
+
mediaUrl: mediaUrl || undefined,
|
|
404
|
+
mediaUrls: additionalOptions.mediaUrls
|
|
405
|
+
? additionalOptions.mediaUrls.split(',').map((u) => u.trim())
|
|
406
|
+
: undefined,
|
|
407
|
+
mediaType: additionalOptions.mediaType || 'auto',
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
returnData.push({
|
|
414
|
+
json: response,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
if (this.continueOnFail()) {
|
|
419
|
+
returnData.push({
|
|
420
|
+
json: {
|
|
421
|
+
error: error.message,
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
throw error;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return [returnData];
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
exports.SendIt = SendIt;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IHookFunctions, IWebhookFunctions, INodeType, INodeTypeDescription, IWebhookResponseData } from 'n8n-workflow';
|
|
2
|
+
export declare class SendItTrigger implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
webhookMethods: {
|
|
5
|
+
default: {
|
|
6
|
+
checkExists(this: IHookFunctions): Promise<boolean>;
|
|
7
|
+
create(this: IHookFunctions): Promise<boolean>;
|
|
8
|
+
delete(this: IHookFunctions): Promise<boolean>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SendItTrigger = void 0;
|
|
4
|
+
class SendItTrigger {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.description = {
|
|
7
|
+
displayName: 'SendIt Trigger',
|
|
8
|
+
name: 'sendItTrigger',
|
|
9
|
+
icon: 'file:sendit.svg',
|
|
10
|
+
group: ['trigger'],
|
|
11
|
+
version: 1,
|
|
12
|
+
subtitle: '={{$parameter["event"]}}',
|
|
13
|
+
description: 'Triggers when events occur in SendIt',
|
|
14
|
+
defaults: {
|
|
15
|
+
name: 'SendIt Trigger',
|
|
16
|
+
},
|
|
17
|
+
inputs: [],
|
|
18
|
+
outputs: ['main'],
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'sendItApi',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
webhooks: [
|
|
26
|
+
{
|
|
27
|
+
name: 'default',
|
|
28
|
+
httpMethod: 'POST',
|
|
29
|
+
responseMode: 'onReceived',
|
|
30
|
+
path: 'webhook',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
properties: [
|
|
34
|
+
{
|
|
35
|
+
displayName: 'Event',
|
|
36
|
+
name: 'event',
|
|
37
|
+
type: 'options',
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: 'Post Published',
|
|
41
|
+
value: 'post.published',
|
|
42
|
+
description: 'Triggered when a post is successfully published',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Post Scheduled',
|
|
46
|
+
value: 'post.scheduled',
|
|
47
|
+
description: 'Triggered when a post is scheduled',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'Post Failed',
|
|
51
|
+
value: 'post.failed',
|
|
52
|
+
description: 'Triggered when a post fails to publish',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Post Deleted',
|
|
56
|
+
value: 'post.deleted',
|
|
57
|
+
description: 'Triggered when a scheduled post is deleted',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Account Connected',
|
|
61
|
+
value: 'account.connected',
|
|
62
|
+
description: 'Triggered when a social account is connected',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Account Disconnected',
|
|
66
|
+
value: 'account.disconnected',
|
|
67
|
+
description: 'Triggered when a social account is disconnected',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
default: 'post.published',
|
|
71
|
+
required: true,
|
|
72
|
+
description: 'The event to listen for',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
this.webhookMethods = {
|
|
77
|
+
default: {
|
|
78
|
+
async checkExists() {
|
|
79
|
+
var _a;
|
|
80
|
+
const webhookUrl = this.getNodeWebhookUrl('default');
|
|
81
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
82
|
+
// If we have stored webhook data, check if it still exists
|
|
83
|
+
if (webhookData.webhookId) {
|
|
84
|
+
try {
|
|
85
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
86
|
+
method: 'GET',
|
|
87
|
+
url: `https://sendit.infiniteappsai.com/api/v1/webhooks/${webhookData.webhookId}`,
|
|
88
|
+
});
|
|
89
|
+
if (response && ((_a = response.webhook) === null || _a === void 0 ? void 0 : _a.url) === webhookUrl) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Webhook doesn't exist anymore
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
},
|
|
99
|
+
async create() {
|
|
100
|
+
var _a;
|
|
101
|
+
const webhookUrl = this.getNodeWebhookUrl('default');
|
|
102
|
+
const event = this.getNodeParameter('event');
|
|
103
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
104
|
+
const body = {
|
|
105
|
+
url: webhookUrl,
|
|
106
|
+
events: [event],
|
|
107
|
+
};
|
|
108
|
+
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
url: 'https://sendit.infiniteappsai.com/api/v1/webhooks',
|
|
111
|
+
body,
|
|
112
|
+
});
|
|
113
|
+
const webhookResponse = response;
|
|
114
|
+
if ((_a = webhookResponse.webhook) === null || _a === void 0 ? void 0 : _a.id) {
|
|
115
|
+
webhookData.webhookId = webhookResponse.webhook.id;
|
|
116
|
+
webhookData.webhookSecret = webhookResponse.webhook.secret;
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
},
|
|
121
|
+
async delete() {
|
|
122
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
123
|
+
if (webhookData.webhookId) {
|
|
124
|
+
try {
|
|
125
|
+
await this.helpers.httpRequestWithAuthentication.call(this, 'sendItApi', {
|
|
126
|
+
method: 'DELETE',
|
|
127
|
+
url: `https://sendit.infiniteappsai.com/api/v1/webhooks/${webhookData.webhookId}`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Ignore errors during deletion
|
|
132
|
+
}
|
|
133
|
+
delete webhookData.webhookId;
|
|
134
|
+
delete webhookData.webhookSecret;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async webhook() {
|
|
142
|
+
const bodyData = this.getBodyData();
|
|
143
|
+
return {
|
|
144
|
+
workflowData: [
|
|
145
|
+
this.helpers.returnJsonArray(bodyData),
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.SendItTrigger = SendItTrigger;
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-sendit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "n8n community node for SendIt - Multi-platform social media publishing",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"social-media",
|
|
8
|
+
"linkedin",
|
|
9
|
+
"instagram",
|
|
10
|
+
"threads",
|
|
11
|
+
"tiktok",
|
|
12
|
+
"twitter",
|
|
13
|
+
"publishing",
|
|
14
|
+
"scheduling"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"homepage": "https://sendit.infiniteappsai.com",
|
|
18
|
+
"author": {
|
|
19
|
+
"name": "SendIt",
|
|
20
|
+
"email": "support@infiniteappsai.com"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/infiniteappsai/sendit"
|
|
25
|
+
},
|
|
26
|
+
"main": "index.js",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc && npm run copy:icons",
|
|
29
|
+
"copy:icons": "mkdir -p dist/nodes/SendIt && cp nodes/SendIt/*.svg dist/nodes/SendIt/ 2>/dev/null || true",
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"format": "prettier nodes credentials --write",
|
|
32
|
+
"lint": "eslint nodes credentials --ext .ts --fix",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"n8n": {
|
|
39
|
+
"n8nNodesApiVersion": 1,
|
|
40
|
+
"credentials": [
|
|
41
|
+
"dist/credentials/SendItApi.credentials.js"
|
|
42
|
+
],
|
|
43
|
+
"nodes": [
|
|
44
|
+
"dist/nodes/SendIt/SendIt.node.js",
|
|
45
|
+
"dist/nodes/SendIt/SendItTrigger.node.js"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.10.0",
|
|
50
|
+
"gulp": "^4.0.2",
|
|
51
|
+
"n8n-workflow": "^1.0.0",
|
|
52
|
+
"prettier": "^3.1.0",
|
|
53
|
+
"typescript": "^5.3.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"n8n-workflow": "*"
|
|
57
|
+
}
|
|
58
|
+
}
|