n8n-nodes-aivencerealtycrm 1.0.10 → 1.2.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/nodes/AivenceRealty/AivenceRealty.node.js +14 -14
- package/dist/nodes/AivenceRealtyTrigger/AivenceRealtyTrigger.node.d.ts +12 -0
- package/dist/nodes/AivenceRealtyTrigger/AivenceRealtyTrigger.node.js +271 -0
- package/dist/nodes/AivenceRealtyTrigger/aivencerealty.png +0 -0
- package/package.json +3 -2
|
@@ -128,7 +128,7 @@ class AivenceRealty {
|
|
|
128
128
|
},
|
|
129
129
|
// Lead Create/Update: JSON from previous node
|
|
130
130
|
{
|
|
131
|
-
displayName: '
|
|
131
|
+
displayName: 'Modo de entrada',
|
|
132
132
|
name: 'useJsonInput',
|
|
133
133
|
type: 'boolean',
|
|
134
134
|
displayOptions: {
|
|
@@ -138,7 +138,7 @@ class AivenceRealty {
|
|
|
138
138
|
},
|
|
139
139
|
},
|
|
140
140
|
default: false,
|
|
141
|
-
description: '
|
|
141
|
+
description: 'Usar JSON del nodo anterior (true) o campos individuales (false). Por defecto muestra campos individuales para mayor claridad.',
|
|
142
142
|
},
|
|
143
143
|
// ============================================
|
|
144
144
|
// LEAD CREATE/UPDATE FIELDS (Structured)
|
|
@@ -664,7 +664,7 @@ class AivenceRealty {
|
|
|
664
664
|
},
|
|
665
665
|
// Email Ingest: JSON from previous node
|
|
666
666
|
{
|
|
667
|
-
displayName: '
|
|
667
|
+
displayName: 'Modo de entrada',
|
|
668
668
|
name: 'useJsonInput',
|
|
669
669
|
type: 'boolean',
|
|
670
670
|
displayOptions: {
|
|
@@ -674,7 +674,7 @@ class AivenceRealty {
|
|
|
674
674
|
},
|
|
675
675
|
},
|
|
676
676
|
default: true,
|
|
677
|
-
description: '
|
|
677
|
+
description: 'Usar JSON del nodo anterior (true) o campos individuales (false). Por defecto muestra campos individuales para mayor claridad.',
|
|
678
678
|
},
|
|
679
679
|
// ============================================
|
|
680
680
|
// MAINTENANCE REQUEST OPERATIONS
|
|
@@ -760,7 +760,7 @@ class AivenceRealty {
|
|
|
760
760
|
description: 'ID del contratista a asignar',
|
|
761
761
|
},
|
|
762
762
|
{
|
|
763
|
-
displayName: '
|
|
763
|
+
displayName: 'Modo de entrada',
|
|
764
764
|
name: 'useJsonInput',
|
|
765
765
|
type: 'boolean',
|
|
766
766
|
displayOptions: {
|
|
@@ -769,8 +769,8 @@ class AivenceRealty {
|
|
|
769
769
|
operation: ['create', 'update', 'addMessage'],
|
|
770
770
|
},
|
|
771
771
|
},
|
|
772
|
-
default:
|
|
773
|
-
description: '
|
|
772
|
+
default: false,
|
|
773
|
+
description: 'Usar JSON del nodo anterior (true) o campos individuales (false). Por defecto muestra campos individuales para mayor claridad.',
|
|
774
774
|
},
|
|
775
775
|
// ============================================
|
|
776
776
|
// CONTRACTOR OPERATIONS
|
|
@@ -830,7 +830,7 @@ class AivenceRealty {
|
|
|
830
830
|
},
|
|
831
831
|
// Contractor Create: JSON from previous node
|
|
832
832
|
{
|
|
833
|
-
displayName: '
|
|
833
|
+
displayName: 'Modo de entrada',
|
|
834
834
|
name: 'useJsonInput',
|
|
835
835
|
type: 'boolean',
|
|
836
836
|
displayOptions: {
|
|
@@ -839,7 +839,7 @@ class AivenceRealty {
|
|
|
839
839
|
operation: ['create'],
|
|
840
840
|
},
|
|
841
841
|
},
|
|
842
|
-
default:
|
|
842
|
+
default: false,
|
|
843
843
|
description: 'Si está activado, usará el JSON completo del nodo anterior con campos: name, email, phone, specialties, rating, availability',
|
|
844
844
|
},
|
|
845
845
|
// ============================================
|
|
@@ -894,7 +894,7 @@ class AivenceRealty {
|
|
|
894
894
|
},
|
|
895
895
|
// Tenant Create: JSON from previous node
|
|
896
896
|
{
|
|
897
|
-
displayName: '
|
|
897
|
+
displayName: 'Modo de entrada',
|
|
898
898
|
name: 'useJsonInput',
|
|
899
899
|
type: 'boolean',
|
|
900
900
|
displayOptions: {
|
|
@@ -903,7 +903,7 @@ class AivenceRealty {
|
|
|
903
903
|
operation: ['create'],
|
|
904
904
|
},
|
|
905
905
|
},
|
|
906
|
-
default:
|
|
906
|
+
default: false,
|
|
907
907
|
description: 'Si está activado, usará el JSON completo del nodo anterior con campos: name, email, phone, property_id, lease_start, lease_end, monthly_rent',
|
|
908
908
|
},
|
|
909
909
|
// ============================================
|
|
@@ -954,7 +954,7 @@ class AivenceRealty {
|
|
|
954
954
|
default: 'list',
|
|
955
955
|
},
|
|
956
956
|
{
|
|
957
|
-
displayName: '
|
|
957
|
+
displayName: 'Modo de entrada',
|
|
958
958
|
name: 'useJsonInput',
|
|
959
959
|
type: 'boolean',
|
|
960
960
|
displayOptions: {
|
|
@@ -963,8 +963,8 @@ class AivenceRealty {
|
|
|
963
963
|
operation: ['create'],
|
|
964
964
|
},
|
|
965
965
|
},
|
|
966
|
-
default:
|
|
967
|
-
description: '
|
|
966
|
+
default: false,
|
|
967
|
+
description: 'Usar JSON del nodo anterior (true) o campos individuales (false). Por defecto muestra campos individuales para mayor claridad.',
|
|
968
968
|
},
|
|
969
969
|
// Appointment ID para get, updateStatus y delete
|
|
970
970
|
{
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IHookFunctions, IWebhookFunctions, INodeType, INodeTypeDescription, IWebhookResponseData } from 'n8n-workflow';
|
|
2
|
+
export declare class AivenceRealtyTrigger 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,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AivenceRealtyTrigger = void 0;
|
|
4
|
+
class AivenceRealtyTrigger {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.description = {
|
|
7
|
+
displayName: 'AivenceRealty Trigger',
|
|
8
|
+
name: 'aivenceRealtyTrigger',
|
|
9
|
+
icon: 'file:aivencerealty.png',
|
|
10
|
+
group: ['trigger'],
|
|
11
|
+
version: 1,
|
|
12
|
+
subtitle: '={{$parameter["event"]}}',
|
|
13
|
+
description: 'Trigger de eventos desde AivenceRealty CRM',
|
|
14
|
+
defaults: {
|
|
15
|
+
name: 'AivenceRealty Trigger',
|
|
16
|
+
},
|
|
17
|
+
inputs: [],
|
|
18
|
+
outputs: ['main'],
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'aivenceRealtyApi',
|
|
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: 'Evento',
|
|
36
|
+
name: 'event',
|
|
37
|
+
type: 'options',
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: 'Propiedad Creada',
|
|
41
|
+
value: 'property.created',
|
|
42
|
+
description: 'Se dispara cuando se crea una nueva propiedad',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Propiedad Actualizada',
|
|
46
|
+
value: 'property.updated',
|
|
47
|
+
description: 'Se dispara cuando se actualiza una propiedad',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'Lead Creado',
|
|
51
|
+
value: 'lead.created',
|
|
52
|
+
description: 'Se dispara cuando se crea un nuevo lead',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Lead Actualizado',
|
|
56
|
+
value: 'lead.updated',
|
|
57
|
+
description: 'Se dispara cuando se actualiza un lead',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Email Recibido',
|
|
61
|
+
value: 'email.received',
|
|
62
|
+
description: 'Se dispara cuando se recibe un nuevo email',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Maintenance Request Creada',
|
|
66
|
+
value: 'maintenance.created',
|
|
67
|
+
description: 'Se dispara cuando se crea una solicitud de mantenimiento',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Appointment Creado',
|
|
71
|
+
value: 'appointment.created',
|
|
72
|
+
description: 'Se dispara cuando se crea una cita',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
default: 'property.created',
|
|
76
|
+
description: 'El evento que disparará el webhook',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
displayName: 'Filtros Adicionales',
|
|
80
|
+
name: 'filters',
|
|
81
|
+
type: 'collection',
|
|
82
|
+
placeholder: 'Agregar Filtro',
|
|
83
|
+
default: {},
|
|
84
|
+
options: [
|
|
85
|
+
{
|
|
86
|
+
displayName: 'Property Type',
|
|
87
|
+
name: 'property_type',
|
|
88
|
+
type: 'options',
|
|
89
|
+
options: [
|
|
90
|
+
{
|
|
91
|
+
name: 'Apartamento',
|
|
92
|
+
value: 'apartamento',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'Casa',
|
|
96
|
+
value: 'casa',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'Loft',
|
|
100
|
+
value: 'loft',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'Terreno',
|
|
104
|
+
value: 'terreno',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'Oficina',
|
|
108
|
+
value: 'oficina',
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
default: '',
|
|
112
|
+
description: 'Filtrar solo propiedades de este tipo',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
displayName: 'Precio Mínimo',
|
|
116
|
+
name: 'price_min',
|
|
117
|
+
type: 'number',
|
|
118
|
+
default: 0,
|
|
119
|
+
description: 'Filtrar propiedades con precio mayor a este valor',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Precio Máximo',
|
|
123
|
+
name: 'price_max',
|
|
124
|
+
type: 'number',
|
|
125
|
+
default: 0,
|
|
126
|
+
description: 'Filtrar propiedades con precio menor a este valor',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
displayName: 'Ciudad',
|
|
130
|
+
name: 'city',
|
|
131
|
+
type: 'string',
|
|
132
|
+
default: '',
|
|
133
|
+
description: 'Filtrar propiedades de esta ciudad',
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
this.webhookMethods = {
|
|
140
|
+
default: {
|
|
141
|
+
async checkExists() {
|
|
142
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
143
|
+
if (webhookData.webhookId === undefined) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
const credentials = await this.getCredentials('aivenceRealtyApi');
|
|
147
|
+
const baseUrl = credentials.baseUrl;
|
|
148
|
+
const webhookId = webhookData.webhookId;
|
|
149
|
+
try {
|
|
150
|
+
const response = await this.helpers.request({
|
|
151
|
+
method: 'GET',
|
|
152
|
+
url: `${baseUrl}/api/v1/webhooks/${webhookId}`,
|
|
153
|
+
json: true,
|
|
154
|
+
});
|
|
155
|
+
return response.active === true;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
async create() {
|
|
162
|
+
const webhookUrl = this.getNodeWebhookUrl('default');
|
|
163
|
+
const event = this.getNodeParameter('event');
|
|
164
|
+
const filters = this.getNodeParameter('filters', {});
|
|
165
|
+
const credentials = await this.getCredentials('aivenceRealtyApi');
|
|
166
|
+
const baseUrl = credentials.baseUrl;
|
|
167
|
+
const body = {
|
|
168
|
+
url: webhookUrl,
|
|
169
|
+
event,
|
|
170
|
+
active: true,
|
|
171
|
+
filters,
|
|
172
|
+
};
|
|
173
|
+
try {
|
|
174
|
+
const response = await this.helpers.request({
|
|
175
|
+
method: 'POST',
|
|
176
|
+
url: `${baseUrl}/api/v1/webhooks`,
|
|
177
|
+
body,
|
|
178
|
+
json: true,
|
|
179
|
+
});
|
|
180
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
181
|
+
webhookData.webhookId = response.data.id;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
async delete() {
|
|
189
|
+
const webhookData = this.getWorkflowStaticData('node');
|
|
190
|
+
if (webhookData.webhookId === undefined) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
const credentials = await this.getCredentials('aivenceRealtyApi');
|
|
194
|
+
const baseUrl = credentials.baseUrl;
|
|
195
|
+
const webhookId = webhookData.webhookId;
|
|
196
|
+
try {
|
|
197
|
+
await this.helpers.request({
|
|
198
|
+
method: 'DELETE',
|
|
199
|
+
url: `${baseUrl}/api/v1/webhooks/${webhookId}`,
|
|
200
|
+
json: true,
|
|
201
|
+
});
|
|
202
|
+
delete webhookData.webhookId;
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
async webhook() {
|
|
213
|
+
const bodyData = this.getBodyData();
|
|
214
|
+
const event = this.getNodeParameter('event');
|
|
215
|
+
const filters = this.getNodeParameter('filters', {});
|
|
216
|
+
// Validar que el evento recibido coincida con el configurado
|
|
217
|
+
const receivedEvent = bodyData.event;
|
|
218
|
+
if (receivedEvent !== event) {
|
|
219
|
+
return {
|
|
220
|
+
webhookResponse: {
|
|
221
|
+
success: false,
|
|
222
|
+
message: 'Event mismatch',
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
// Aplicar filtros si existen
|
|
227
|
+
if (Object.keys(filters).length > 0) {
|
|
228
|
+
const payload = bodyData.data;
|
|
229
|
+
// Filtro por tipo de propiedad
|
|
230
|
+
if (filters.property_type && payload.property_type !== filters.property_type) {
|
|
231
|
+
return {
|
|
232
|
+
webhookResponse: {
|
|
233
|
+
success: true,
|
|
234
|
+
message: 'Filtered out by property_type',
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// Filtro por precio mínimo
|
|
239
|
+
if (filters.price_min && Number(payload.price) < Number(filters.price_min)) {
|
|
240
|
+
return {
|
|
241
|
+
webhookResponse: {
|
|
242
|
+
success: true,
|
|
243
|
+
message: 'Filtered out by price_min',
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// Filtro por precio máximo
|
|
248
|
+
if (filters.price_max && Number(payload.price) > Number(filters.price_max)) {
|
|
249
|
+
return {
|
|
250
|
+
webhookResponse: {
|
|
251
|
+
success: true,
|
|
252
|
+
message: 'Filtered out by price_max',
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Filtro por ciudad
|
|
257
|
+
if (filters.city && payload.city !== filters.city) {
|
|
258
|
+
return {
|
|
259
|
+
webhookResponse: {
|
|
260
|
+
success: true,
|
|
261
|
+
message: 'Filtered out by city',
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
workflowData: [this.helpers.returnJsonArray(bodyData)],
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
exports.AivenceRealtyTrigger = AivenceRealtyTrigger;
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-aivencerealtycrm",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Nodo n8n para integrar el CRM inmobiliario AivenceRealty",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"dist/credentials/AivenceRealtyApi.credentials.js"
|
|
40
40
|
],
|
|
41
41
|
"nodes": [
|
|
42
|
-
"dist/nodes/AivenceRealty/AivenceRealty.node.js"
|
|
42
|
+
"dist/nodes/AivenceRealty/AivenceRealty.node.js",
|
|
43
|
+
"dist/nodes/AivenceRealtyTrigger/AivenceRealtyTrigger.node.js"
|
|
43
44
|
]
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|