n8n-nodes-idb2b 3.2.8 → 3.3.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/IDB2BApi.credentials.d.ts +3 -1
- package/dist/credentials/IDB2BApi.credentials.js +29 -22
- package/dist/nodes/IDB2B/IDB2B.node.js +37 -17
- package/dist/nodes/IDB2B/descriptions/activityProperties.js +51 -2
- package/dist/nodes/IDB2B/utils/httpClient.d.ts +1 -0
- package/dist/nodes/IDB2B/utils/httpClient.js +5 -1
- package/package.json +4 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { ICredentialTestRequest, ICredentialType, INodeProperties } from
|
|
1
|
+
import { ICredentialTestRequest, ICredentialType, INodeProperties, IHttpRequestOptions } from "n8n-workflow";
|
|
2
2
|
export declare class IDB2BApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
5
5
|
documentationUrl: string;
|
|
6
|
+
icon: "file:IDB2B.svg";
|
|
7
|
+
authenticate: (this: any, credentials: any, requestOptions: IHttpRequestOptions) => Promise<IHttpRequestOptions>;
|
|
6
8
|
properties: INodeProperties[];
|
|
7
9
|
test: ICredentialTestRequest;
|
|
8
10
|
}
|
|
@@ -1,45 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IDB2BApi = void 0;
|
|
4
|
+
const httpClient_1 = require("../nodes/IDB2B/utils/httpClient");
|
|
4
5
|
class IDB2BApi {
|
|
5
6
|
constructor() {
|
|
6
|
-
this.name =
|
|
7
|
-
this.displayName =
|
|
8
|
-
this.documentationUrl =
|
|
7
|
+
this.name = "idb2bApi";
|
|
8
|
+
this.displayName = "IDB2B WhatsApp AI Agents";
|
|
9
|
+
this.documentationUrl = "https://idb2b.com/en";
|
|
10
|
+
this.icon = "file:IDB2B.svg";
|
|
11
|
+
this.authenticate = async function (credentials, requestOptions) {
|
|
12
|
+
const accessToken = await (0, httpClient_1.getAccessToken)(this, credentials);
|
|
13
|
+
requestOptions.headers = Object.assign(Object.assign({}, requestOptions.headers), { Authorization: `Bearer ${accessToken}` });
|
|
14
|
+
return requestOptions;
|
|
15
|
+
};
|
|
9
16
|
this.properties = [
|
|
10
17
|
{
|
|
11
|
-
displayName:
|
|
12
|
-
name:
|
|
13
|
-
type:
|
|
14
|
-
default:
|
|
18
|
+
displayName: "Email",
|
|
19
|
+
name: "email",
|
|
20
|
+
type: "string",
|
|
21
|
+
default: "",
|
|
15
22
|
required: true,
|
|
16
|
-
placeholder:
|
|
23
|
+
placeholder: "your@email.com",
|
|
17
24
|
},
|
|
18
25
|
{
|
|
19
|
-
displayName:
|
|
20
|
-
name:
|
|
21
|
-
type:
|
|
26
|
+
displayName: "Password",
|
|
27
|
+
name: "password",
|
|
28
|
+
type: "string",
|
|
22
29
|
typeOptions: { password: true },
|
|
23
|
-
default:
|
|
30
|
+
default: "",
|
|
24
31
|
required: true,
|
|
25
32
|
},
|
|
26
33
|
{
|
|
27
|
-
displayName:
|
|
28
|
-
name:
|
|
29
|
-
type:
|
|
30
|
-
default:
|
|
34
|
+
displayName: "Base URL",
|
|
35
|
+
name: "baseUrl",
|
|
36
|
+
type: "string",
|
|
37
|
+
default: "https://api.idb2b.com",
|
|
31
38
|
required: true,
|
|
32
|
-
description:
|
|
39
|
+
description: "The IDB2B API base URL. Use https://api-stage.idb2b.com for staging environment.",
|
|
33
40
|
},
|
|
34
41
|
];
|
|
35
42
|
this.test = {
|
|
36
43
|
request: {
|
|
37
|
-
baseURL:
|
|
38
|
-
url:
|
|
39
|
-
method:
|
|
44
|
+
baseURL: "={{$credentials.baseUrl}}",
|
|
45
|
+
url: "/login",
|
|
46
|
+
method: "POST",
|
|
40
47
|
body: {
|
|
41
|
-
email:
|
|
42
|
-
password:
|
|
48
|
+
email: "={{$credentials.email}}",
|
|
49
|
+
password: "={{$credentials.password}}",
|
|
43
50
|
},
|
|
44
51
|
},
|
|
45
52
|
};
|
|
@@ -25,8 +25,8 @@ class IDB2B {
|
|
|
25
25
|
defaults: {
|
|
26
26
|
name: "IDB2B",
|
|
27
27
|
},
|
|
28
|
-
inputs: [
|
|
29
|
-
outputs: [
|
|
28
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
29
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
30
30
|
credentials: [
|
|
31
31
|
{
|
|
32
32
|
name: "idb2bApi",
|
|
@@ -78,7 +78,6 @@ class IDB2B {
|
|
|
78
78
|
if (!credentialsValidation.isValid) {
|
|
79
79
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), credentialsValidation.error || "Invalid credentials");
|
|
80
80
|
}
|
|
81
|
-
const accessToken = await (0, httpClient_1.getAccessToken)(this, credentials);
|
|
82
81
|
const httpClient = new httpClient_1.HttpClient(this);
|
|
83
82
|
for (let i = 0; i < items.length; i++) {
|
|
84
83
|
try {
|
|
@@ -171,28 +170,35 @@ class IDB2B {
|
|
|
171
170
|
}
|
|
172
171
|
else if (operation === "get") {
|
|
173
172
|
method = "GET";
|
|
173
|
+
const activityScope = this.getNodeParameter("activityScope", i);
|
|
174
174
|
const activityId = this.getNodeParameter("activityId", i);
|
|
175
|
-
|
|
175
|
+
if (activityScope === "contact") {
|
|
176
|
+
const parentContactId = this.getNodeParameter("activityParentContactId", i);
|
|
177
|
+
endpoint = `/contacts/${(0, common_1.sanitizeId)(parentContactId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const parentCompanyId = this.getNodeParameter("activityParentCompanyId", i);
|
|
181
|
+
endpoint = `/leads/${(0, common_1.sanitizeId)(parentCompanyId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
182
|
+
}
|
|
176
183
|
}
|
|
177
184
|
else if (operation === "create") {
|
|
178
185
|
method = "POST";
|
|
179
|
-
endpoint = constants_1.ENDPOINTS.ACTIVITIES;
|
|
180
|
-
const subject = this.getNodeParameter("subject", i);
|
|
181
186
|
const associateWith = this.getNodeParameter("associateWith", i);
|
|
187
|
+
const subject = this.getNodeParameter("subject", i);
|
|
182
188
|
const additionalFields = this.getNodeParameter("additionalFields", i, {});
|
|
183
189
|
if (!subject || !subject.trim()) {
|
|
184
190
|
throw new Error("Subject is required to create an activity");
|
|
185
191
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
192
|
+
const formPayload = {
|
|
193
|
+
subject: subject.trim(),
|
|
194
|
+
};
|
|
189
195
|
if (associateWith === "company") {
|
|
190
196
|
const companyId = this.getNodeParameter("activityCompanyId", i);
|
|
191
|
-
|
|
197
|
+
endpoint = `/leads/${(0, common_1.sanitizeId)(companyId)}/activities`;
|
|
192
198
|
}
|
|
193
199
|
else {
|
|
194
200
|
const contactId = this.getNodeParameter("activityContactId", i);
|
|
195
|
-
|
|
201
|
+
endpoint = `/contacts/${(0, common_1.sanitizeId)(contactId)}/activities`;
|
|
196
202
|
}
|
|
197
203
|
// Merge optional additional fields
|
|
198
204
|
Object.entries(additionalFields).forEach(([key, value]) => {
|
|
@@ -206,8 +212,16 @@ class IDB2B {
|
|
|
206
212
|
}
|
|
207
213
|
else if (operation === "update") {
|
|
208
214
|
method = "PATCH";
|
|
215
|
+
const activityScope = this.getNodeParameter("activityScope", i);
|
|
209
216
|
const activityId = this.getNodeParameter("activityId", i);
|
|
210
|
-
|
|
217
|
+
if (activityScope === "contact") {
|
|
218
|
+
const parentContactId = this.getNodeParameter("activityParentContactId", i);
|
|
219
|
+
endpoint = `/contacts/${(0, common_1.sanitizeId)(parentContactId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
const parentCompanyId = this.getNodeParameter("activityParentCompanyId", i);
|
|
223
|
+
endpoint = `/leads/${(0, common_1.sanitizeId)(parentCompanyId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
224
|
+
}
|
|
211
225
|
const additionalFields = this.getNodeParameter("additionalFields", i, {});
|
|
212
226
|
const updatePayload = {};
|
|
213
227
|
Object.entries(additionalFields).forEach(([key, value]) => {
|
|
@@ -221,8 +235,16 @@ class IDB2B {
|
|
|
221
235
|
}
|
|
222
236
|
else if (operation === "delete") {
|
|
223
237
|
method = "DELETE";
|
|
238
|
+
const activityScope = this.getNodeParameter("activityScope", i);
|
|
224
239
|
const activityId = this.getNodeParameter("activityId", i);
|
|
225
|
-
|
|
240
|
+
if (activityScope === "contact") {
|
|
241
|
+
const parentContactId = this.getNodeParameter("activityParentContactId", i);
|
|
242
|
+
endpoint = `/contacts/${(0, common_1.sanitizeId)(parentContactId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
const parentCompanyId = this.getNodeParameter("activityParentCompanyId", i);
|
|
246
|
+
endpoint = `/leads/${(0, common_1.sanitizeId)(parentCompanyId)}/activities/${(0, common_1.sanitizeId)(activityId)}`;
|
|
247
|
+
}
|
|
226
248
|
}
|
|
227
249
|
}
|
|
228
250
|
else if (resource === "company") {
|
|
@@ -283,9 +305,7 @@ class IDB2B {
|
|
|
283
305
|
endpoint = `${constants_1.ENDPOINTS.COMPANIES}/${(0, common_1.sanitizeId)(companyId)}`;
|
|
284
306
|
}
|
|
285
307
|
}
|
|
286
|
-
const response = await httpClient.makeRequest(Object.assign(Object.assign({ method, url: `${credentials.baseUrl}${endpoint}
|
|
287
|
-
Authorization: `Bearer ${accessToken}`,
|
|
288
|
-
} }, (useFormData ? { formData: body } : { body })), { qs, json: true }));
|
|
308
|
+
const response = await httpClient.makeRequest(Object.assign(Object.assign({ method, url: `${credentials.baseUrl}${endpoint}` }, (useFormData ? { formData: body } : { body })), { qs, json: true }));
|
|
289
309
|
let processedResponse = (0, common_1.processResponse)(response, operation, initialBody);
|
|
290
310
|
// Apply field filtering for getAll operations
|
|
291
311
|
if (operation === "getAll") {
|
|
@@ -323,7 +343,7 @@ class IDB2B {
|
|
|
323
343
|
});
|
|
324
344
|
continue;
|
|
325
345
|
}
|
|
326
|
-
throw new n8n_workflow_1.
|
|
346
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), error, {
|
|
327
347
|
itemIndex: i,
|
|
328
348
|
});
|
|
329
349
|
}
|
|
@@ -15,8 +15,8 @@ exports.activityOperations = {
|
|
|
15
15
|
{
|
|
16
16
|
name: 'Get All',
|
|
17
17
|
value: 'getAll',
|
|
18
|
-
action: 'Get all activities
|
|
19
|
-
description: 'Retrieve all activities for a specific company
|
|
18
|
+
action: 'Get all activities',
|
|
19
|
+
description: 'Retrieve all activities for a specific company or contact',
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
name: 'Get',
|
|
@@ -46,6 +46,55 @@ exports.activityOperations = {
|
|
|
46
46
|
default: 'getAll',
|
|
47
47
|
};
|
|
48
48
|
exports.activityFields = [
|
|
49
|
+
// Scope selector for get, update, delete
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Scope',
|
|
52
|
+
name: 'activityScope',
|
|
53
|
+
type: 'options',
|
|
54
|
+
default: 'company',
|
|
55
|
+
required: true,
|
|
56
|
+
displayOptions: {
|
|
57
|
+
show: {
|
|
58
|
+
resource: ['activity'],
|
|
59
|
+
operation: ['get', 'update', 'delete'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
options: [
|
|
63
|
+
{ name: 'Company (Lead)', value: 'company' },
|
|
64
|
+
{ name: 'Contact', value: 'contact' },
|
|
65
|
+
],
|
|
66
|
+
description: 'Whether this activity belongs to a company (lead) or a contact',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
displayName: 'Company ID',
|
|
70
|
+
name: 'activityParentCompanyId',
|
|
71
|
+
type: 'string',
|
|
72
|
+
default: '',
|
|
73
|
+
required: true,
|
|
74
|
+
displayOptions: {
|
|
75
|
+
show: {
|
|
76
|
+
resource: ['activity'],
|
|
77
|
+
operation: ['get', 'update', 'delete'],
|
|
78
|
+
activityScope: ['company'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
description: 'ID of the company (lead) that owns this activity',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
displayName: 'Contact ID',
|
|
85
|
+
name: 'activityParentContactId',
|
|
86
|
+
type: 'string',
|
|
87
|
+
default: '',
|
|
88
|
+
required: true,
|
|
89
|
+
displayOptions: {
|
|
90
|
+
show: {
|
|
91
|
+
resource: ['activity'],
|
|
92
|
+
operation: ['get', 'update', 'delete'],
|
|
93
|
+
activityScope: ['contact'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
description: 'ID of the contact that owns this activity',
|
|
97
|
+
},
|
|
49
98
|
// Activity ID — required for get, update, delete
|
|
50
99
|
{
|
|
51
100
|
displayName: 'Activity ID',
|
|
@@ -28,7 +28,10 @@ class HttpClient {
|
|
|
28
28
|
let lastError;
|
|
29
29
|
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
30
30
|
try {
|
|
31
|
-
|
|
31
|
+
if (options.skipAuth) {
|
|
32
|
+
return await this.executeFunctions.helpers.httpRequest(options);
|
|
33
|
+
}
|
|
34
|
+
return await this.executeFunctions.helpers.httpRequestWithAuthentication.call(this.executeFunctions, "idb2bApi", options);
|
|
32
35
|
}
|
|
33
36
|
catch (error) {
|
|
34
37
|
lastError = error;
|
|
@@ -113,6 +116,7 @@ async function getAccessToken(executeFunctions, credentials) {
|
|
|
113
116
|
password: credentials.password,
|
|
114
117
|
},
|
|
115
118
|
json: true,
|
|
119
|
+
skipAuth: true,
|
|
116
120
|
});
|
|
117
121
|
// Try to extract token from various possible response formats
|
|
118
122
|
const accessToken = ((_b = (_a = loginResponse === null || loginResponse === void 0 ? void 0 : loginResponse.data) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.access_token) ||
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-idb2b",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "n8n community node for IDB2B - WhatsApp AI Agents",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -47,5 +47,8 @@
|
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"n8n-workflow": "*"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
50
53
|
}
|
|
51
54
|
}
|