n8n-nodes-idb2b 3.1.0 → 3.1.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.
@@ -106,7 +106,7 @@ class IDB2B {
106
106
  const email = this.getNodeParameter("email", i);
107
107
  const phone_number = this.getNodeParameter("phone_number", i, "");
108
108
  const additionalFields = this.getNodeParameter("additionalFields", i, {});
109
- const validation = validator.validateContactData(name, email);
109
+ const validation = validator.validateContactData(name, email, phone_number, false);
110
110
  if (!validation.isValid) {
111
111
  throw new Error(validation.error);
112
112
  }
@@ -123,40 +123,19 @@ class IDB2B {
123
123
  const email = this.getNodeParameter("email", i, "");
124
124
  const phone_number = this.getNodeParameter("phone_number", i, "");
125
125
  const additionalFields = this.getNodeParameter("additionalFields", i, {});
126
- body = {};
127
126
  if (name) {
128
127
  const validation = validator.validateContactData(name);
129
128
  if (!validation.isValid) {
130
129
  throw new Error(validation.error);
131
130
  }
132
- body.name = name.trim();
133
131
  }
134
132
  if (email) {
135
133
  const validation = validator.validateEmailField(email);
136
134
  if (!validation.isValid) {
137
135
  throw new Error(validation.error);
138
136
  }
139
- body.email = email.trim();
140
- }
141
- if (phone_number) {
142
- body.phone_number = phone_number;
143
137
  }
144
- // Add additional fields
145
- Object.keys(additionalFields).forEach((key) => {
146
- if (additionalFields[key] !== undefined &&
147
- additionalFields[key] !== "") {
148
- if (key === "tags" &&
149
- additionalFields.tags &&
150
- additionalFields.tags.tag) {
151
- body.tags = additionalFields.tags.tag.map((tag) => ({
152
- name: tag.name.trim(),
153
- }));
154
- }
155
- else {
156
- body[key] = additionalFields[key];
157
- }
158
- }
159
- });
138
+ body = (0, common_1.buildContactRequestBody)(Object.assign(Object.assign(Object.assign(Object.assign({}, (name ? { name } : {})), (email ? { email } : {})), (phone_number ? { phone_number } : {})), additionalFields), true);
160
139
  initialBody = body;
161
140
  }
162
141
  else if (operation === "delete") {
@@ -94,7 +94,6 @@ exports.contactFields = [
94
94
  name: 'email',
95
95
  type: 'string',
96
96
  default: '',
97
- required: true,
98
97
  displayOptions: {
99
98
  show: {
100
99
  resource: ['contact'],
@@ -122,6 +121,7 @@ exports.contactFields = [
122
121
  name: 'phone_number',
123
122
  type: 'string',
124
123
  default: '',
124
+ required: true,
125
125
  displayOptions: {
126
126
  show: {
127
127
  resource: ['contact'],
@@ -157,13 +157,6 @@ exports.contactFields = [
157
157
  },
158
158
  },
159
159
  options: [
160
- {
161
- displayName: 'Company',
162
- name: 'company',
163
- type: 'string',
164
- default: '',
165
- description: 'Company name (for CRM integration)',
166
- },
167
160
  {
168
161
  displayName: 'Company ID',
169
162
  name: 'company_id',
@@ -172,73 +165,32 @@ exports.contactFields = [
172
165
  description: 'ID of the company/lead to associate with this contact',
173
166
  },
174
167
  {
175
- displayName: 'Status',
176
- name: 'status',
177
- type: 'options',
178
- default: 'Lead',
179
- description: 'Contact status in sales pipeline',
180
- options: [
181
- { name: 'Lead', value: 'Lead' },
182
- { name: 'Qualified', value: 'Qualified' },
183
- { name: 'Proposal', value: 'Proposal' },
184
- { name: 'Negotiation', value: 'Negotiation' },
185
- { name: 'Closed', value: 'Closed' },
186
- { name: 'Lost', value: 'Lost' },
187
- ],
188
- },
189
- {
190
- displayName: 'Priority',
191
- name: 'priority',
192
- type: 'options',
193
- default: 'Medium',
194
- description: 'Contact priority level',
195
- options: [
196
- { name: 'High', value: 'High' },
197
- { name: 'Medium', value: 'Medium' },
198
- { name: 'Low', value: 'Low' },
199
- ],
200
- },
201
- {
202
- displayName: 'Estimated Value',
203
- name: 'estimated_value',
204
- type: 'number',
205
- default: 0,
206
- description: 'Estimated deal value',
207
- },
208
- {
209
- displayName: 'Account Owner',
210
- name: 'account_owner',
168
+ displayName: 'Status ID',
169
+ name: 'status_id',
211
170
  type: 'string',
212
171
  default: '',
213
- description: 'Sales representative or account owner',
172
+ description: 'UUID of the status to associate with this contact',
214
173
  },
215
174
  {
216
- displayName: 'Position',
217
- name: 'position',
175
+ displayName: 'Source ID',
176
+ name: 'source_id',
218
177
  type: 'string',
219
178
  default: '',
220
- description: 'Job title or position',
179
+ description: 'UUID of the source to associate with this contact',
221
180
  },
222
181
  {
223
- displayName: 'User ID',
224
- name: 'user_id',
182
+ displayName: 'Job Title',
183
+ name: 'job_title',
225
184
  type: 'string',
226
185
  default: '',
227
- description: 'ID of the user to associate with this contact',
186
+ description: 'Job title of the contact',
228
187
  },
229
188
  {
230
- displayName: 'Lead ID',
231
- name: 'lead_id',
189
+ displayName: 'Owner ID',
190
+ name: 'owner_id',
232
191
  type: 'string',
233
192
  default: '',
234
- description: 'ID of the lead to associate with this contact (optional)',
235
- },
236
- {
237
- displayName: 'Favorites',
238
- name: 'favorites',
239
- type: 'boolean',
240
- default: false,
241
- description: 'Mark contact as favorite',
193
+ description: 'UUID of the user who owns this contact',
242
194
  },
243
195
  {
244
196
  displayName: 'Tags',
@@ -58,7 +58,7 @@ class ContactHandler {
58
58
  */
59
59
  async create(params) {
60
60
  // Validate required fields
61
- const validation = this.validator.validateContactData(params.data.name, params.data.email);
61
+ const validation = this.validator.validateContactData(params.data.name, params.data.email, params.data.phone_number, false);
62
62
  if (!validation.isValid) {
63
63
  throw new Error(validation.error);
64
64
  }
@@ -101,6 +101,18 @@ function processResponse(response, operation, requestBody) {
101
101
  */
102
102
  function buildContactRequestBody(data, includesPhone = true) {
103
103
  const body = {};
104
+ const fieldAliases = {
105
+ lead_id: "company_id",
106
+ position: "job_title",
107
+ user_id: "owner_id",
108
+ };
109
+ const supportedFields = new Set([
110
+ "job_title",
111
+ "company_id",
112
+ "status_id",
113
+ "source_id",
114
+ "owner_id",
115
+ ]);
104
116
  // Always include name and email if provided
105
117
  if (data.name !== undefined) {
106
118
  body.name = typeof data.name === "string" ? data.name.trim() : data.name;
@@ -121,6 +133,32 @@ function buildContactRequestBody(data, includesPhone = true) {
121
133
  name: tag.name.trim(),
122
134
  }));
123
135
  }
136
+ if (Array.isArray(data.tags)) {
137
+ body.tags = data.tags
138
+ .filter((tag) => tag === null || tag === void 0 ? void 0 : tag.name)
139
+ .map((tag) => ({
140
+ name: typeof tag.name === "string" ? tag.name.trim() : tag.name,
141
+ }));
142
+ }
143
+ Object.entries(data).forEach(([rawKey, rawValue]) => {
144
+ var _a;
145
+ if ([
146
+ "name",
147
+ "email",
148
+ "phone_number",
149
+ "tags",
150
+ ].includes(rawKey)) {
151
+ return;
152
+ }
153
+ if (rawValue === undefined || rawValue === null || rawValue === "") {
154
+ return;
155
+ }
156
+ const key = (_a = fieldAliases[rawKey]) !== null && _a !== void 0 ? _a : rawKey;
157
+ if (!supportedFields.has(key)) {
158
+ return;
159
+ }
160
+ body[key] = typeof rawValue === "string" ? rawValue.trim() : rawValue;
161
+ });
124
162
  return body;
125
163
  }
126
164
  /**
@@ -18,7 +18,7 @@ export declare class DataValidator {
18
18
  /**
19
19
  * Validate contact creation data
20
20
  */
21
- validateContactData(name: string, email?: string): ValidationResult;
21
+ validateContactData(name: string, email?: string, phoneNumber?: string, requirePhone?: boolean): ValidationResult;
22
22
  /**
23
23
  * Validate company creation data
24
24
  */
@@ -40,7 +40,7 @@ class DataValidator {
40
40
  /**
41
41
  * Validate contact creation data
42
42
  */
43
- validateContactData(name, email) {
43
+ validateContactData(name, email, phoneNumber, requirePhone = false) {
44
44
  if (!name || typeof name !== "string" || name.trim().length === 0) {
45
45
  return {
46
46
  isValid: false,
@@ -59,6 +59,15 @@ class DataValidator {
59
59
  return emailValidation;
60
60
  }
61
61
  }
62
+ if (requirePhone &&
63
+ (!phoneNumber ||
64
+ typeof phoneNumber !== "string" ||
65
+ phoneNumber.trim().length === 0)) {
66
+ return {
67
+ isValid: false,
68
+ error: "Contact phone number is required",
69
+ };
70
+ }
62
71
  return { isValid: true };
63
72
  }
64
73
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-idb2b",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "n8n community node for IDB2B - WhatsApp AI Agents",
5
5
  "main": "index.js",
6
6
  "scripts": {