n8n-nodes-cribops 0.1.18 → 0.1.20

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.
@@ -25,6 +25,13 @@ class CribopsApi {
25
25
  required: true,
26
26
  description: 'Base URL of the Cribops API',
27
27
  },
28
+ {
29
+ displayName: 'Organization ID',
30
+ name: 'organizationId',
31
+ type: 'string',
32
+ default: '',
33
+ description: 'Organization ID (optional - if not provided, will use the default organization for the API token)',
34
+ },
28
35
  ];
29
36
  authenticate = {
30
37
  type: 'generic',
@@ -41,7 +41,7 @@ class CribopsTrigger {
41
41
  loadOptionsMethod: 'getWebhooks',
42
42
  },
43
43
  default: '',
44
- description: 'The Cribops webhook to use. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
44
+ description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
45
45
  },
46
46
  {
47
47
  displayName: 'Event Types',
@@ -109,14 +109,17 @@ class CribopsTrigger {
109
109
  apiToken: credentials.apiToken,
110
110
  });
111
111
  try {
112
- // Call the API to get available webhooks
113
- // The API endpoint would be something like GET /api/v1/webhooks
114
- const response = await cribopsHttp.request('GET', '/api/v1/webhooks');
115
- const webhooks = response.data || [];
116
- return webhooks.map((webhook) => ({
117
- name: webhook.name || webhook.id,
112
+ // Get organization ID from credentials if provided
113
+ const organizationId = credentials.organizationId;
114
+ const webhooks = await cribopsHttp.getWebhooks(organizationId);
115
+ // Filter for N8N type webhooks that are active and not linked
116
+ const availableWebhooks = webhooks.filter((webhook) => webhook.type === 'N8N' &&
117
+ webhook.status === 'active' &&
118
+ !webhook.linked_workflow_id);
119
+ return availableWebhooks.map((webhook) => ({
120
+ name: webhook.name,
118
121
  value: webhook.id,
119
- description: webhook.description || `Webhook ID: ${webhook.id}`,
122
+ description: webhook.description || `Type: ${webhook.type}`,
120
123
  }));
121
124
  }
122
125
  catch (error) {
@@ -135,37 +138,37 @@ class CribopsTrigger {
135
138
  async create() {
136
139
  const webhookUrl = this.getNodeWebhookUrl('default');
137
140
  const webhookId = this.getNodeParameter('webhookId');
138
- const eventTypes = this.getNodeParameter('eventTypes', []);
139
- const additionalFields = this.getNodeParameter('additionalFields', {});
140
141
  const credentials = await this.getCredentials('cribopsApi');
142
+ const workflowId = this.getWorkflow().id;
143
+ const workflowName = this.getWorkflow().name;
141
144
  const cribopsHttp = new CribopsHttp_1.CribopsHttp({
142
145
  baseUrl: credentials.baseUrl,
143
146
  apiToken: credentials.apiToken,
144
147
  });
145
148
  try {
146
- // Register this n8n webhook URL with the Cribops webhook
149
+ // Link this workflow to the webhook entity
147
150
  const body = {
148
- webhook_id: webhookId,
149
- target_url: webhookUrl,
150
- event_types: eventTypes,
151
- secret: additionalFields.secretToken || undefined,
151
+ workflow_id: workflowId,
152
+ webhook_url: webhookUrl,
153
+ test_webhook_url: webhookUrl.replace('/webhook/', '/webhook-test/'),
154
+ workflow_name: workflowName || 'Unnamed Workflow',
152
155
  };
153
- // Register the n8n webhook URL with Cribops
154
- await cribopsHttp.request('POST', `/api/v1/webhooks/${webhookId}/targets`, body);
156
+ // Link the n8n workflow to the webhook entity
157
+ await cribopsHttp.request('POST', `/api/v1/webhooks/${webhookId}/link`, body);
155
158
  // Store webhook data for later use
156
159
  const webhookData = this.getWorkflowStaticData('node');
157
160
  webhookData.webhookId = webhookId;
158
- webhookData.targetUrl = webhookUrl;
161
+ webhookData.webhookUrl = webhookUrl;
159
162
  return true;
160
163
  }
161
164
  catch (error) {
162
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to register webhook target: ${error instanceof Error ? error.message : String(error)}`);
165
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to link webhook: ${error instanceof Error ? error.message : String(error)}`);
163
166
  }
164
167
  },
165
168
  async delete() {
166
169
  const webhookData = this.getWorkflowStaticData('node');
167
170
  const credentials = await this.getCredentials('cribopsApi');
168
- if (!webhookData.webhookId || !webhookData.targetUrl) {
171
+ if (!webhookData.webhookId) {
169
172
  return true;
170
173
  }
171
174
  const cribopsHttp = new CribopsHttp_1.CribopsHttp({
@@ -173,17 +176,15 @@ class CribopsTrigger {
173
176
  apiToken: credentials.apiToken,
174
177
  });
175
178
  try {
176
- // Unregister the n8n webhook URL from Cribops
177
- await cribopsHttp.request('DELETE', `/api/v1/webhooks/${webhookData.webhookId}/targets`, {
178
- target_url: webhookData.targetUrl,
179
- });
179
+ // Unlink the workflow from the webhook entity
180
+ await cribopsHttp.request('DELETE', `/api/v1/webhooks/${webhookData.webhookId}/link`);
180
181
  delete webhookData.webhookId;
181
- delete webhookData.targetUrl;
182
+ delete webhookData.webhookUrl;
182
183
  return true;
183
184
  }
184
185
  catch (error) {
185
186
  // Log error but don't fail
186
- console.error('Failed to unregister webhook target:', error);
187
+ console.error('Failed to unlink webhook:', error);
187
188
  return true;
188
189
  }
189
190
  },
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-cribops",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "n8n community node for Cribops AI platform integration",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"
@@ -37,6 +37,18 @@ export interface CribopsQueueMessage {
37
37
  };
38
38
  inserted_at: string;
39
39
  }
40
+ export interface CribopsWebhookEntity {
41
+ id: string;
42
+ name: string;
43
+ description?: string;
44
+ type: 'N8N' | 'GHL_API' | 'GENERIC';
45
+ status: 'active' | 'inactive';
46
+ linked_workflow_id?: string;
47
+ linked_workflow_name?: string;
48
+ organization_id: string;
49
+ created_at: string;
50
+ updated_at: string;
51
+ }
40
52
  export declare class CribopsHttp {
41
53
  private config;
42
54
  constructor(config: CribopsHttpConfig);
@@ -57,5 +69,13 @@ export declare class CribopsHttp {
57
69
  status: string;
58
70
  updated_count: number;
59
71
  }>;
72
+ getWebhooks(organizationId?: string): Promise<CribopsWebhookEntity[]>;
73
+ linkWebhook(webhookId: string, linkData: {
74
+ workflow_id: string;
75
+ webhook_url: string;
76
+ test_webhook_url: string;
77
+ workflow_name: string;
78
+ }): Promise<any>;
79
+ unlinkWebhook(webhookId: string): Promise<any>;
60
80
  request<T = any>(method: IHttpRequestMethods, endpoint: string, data?: IDataObject, options?: Partial<IHttpRequestOptions>): Promise<T>;
61
81
  }
@@ -10,7 +10,21 @@ class CribopsHttp {
10
10
  };
11
11
  }
12
12
  async makeRequest(method, endpoint, data, options) {
13
- const url = `${this.config.baseUrl}${endpoint}`;
13
+ let url = `${this.config.baseUrl}${endpoint}`;
14
+ // Handle query parameters
15
+ if (method === 'GET' && data?.params) {
16
+ const params = new URLSearchParams();
17
+ Object.entries(data.params).forEach(([key, value]) => {
18
+ if (value !== undefined && value !== null) {
19
+ params.append(key, String(value));
20
+ }
21
+ });
22
+ const queryString = params.toString();
23
+ if (queryString) {
24
+ url += `?${queryString}`;
25
+ }
26
+ delete data.params;
27
+ }
14
28
  const requestHeaders = {
15
29
  'Authorization': `Bearer ${this.config.apiToken}`,
16
30
  'Content-Type': 'application/json',
@@ -25,7 +39,7 @@ class CribopsHttp {
25
39
  const response = await fetch(url, {
26
40
  method,
27
41
  headers: requestHeaders,
28
- body: data ? JSON.stringify(data) : undefined,
42
+ body: (method !== 'GET' && data) ? JSON.stringify(data) : undefined,
29
43
  });
30
44
  if (!response.ok) {
31
45
  const errorText = await response.text();
@@ -144,6 +158,33 @@ class CribopsHttp {
144
158
  throw new Error(`Failed to mark messages as failed for tenant ${tenantId}: ${error}`);
145
159
  }
146
160
  }
161
+ // Webhook-specific methods
162
+ async getWebhooks(organizationId) {
163
+ try {
164
+ const params = organizationId ? { params: { organization_id: organizationId } } : undefined;
165
+ const response = await this.makeRequest('GET', '/api/v1/webhooks', params);
166
+ return response.data || [];
167
+ }
168
+ catch (error) {
169
+ throw new Error(`Failed to fetch webhooks: ${error}`);
170
+ }
171
+ }
172
+ async linkWebhook(webhookId, linkData) {
173
+ try {
174
+ return await this.makeRequest('POST', `/api/v1/webhooks/${webhookId}/link`, linkData);
175
+ }
176
+ catch (error) {
177
+ throw new Error(`Failed to link webhook: ${error}`);
178
+ }
179
+ }
180
+ async unlinkWebhook(webhookId) {
181
+ try {
182
+ return await this.makeRequest('DELETE', `/api/v1/webhooks/${webhookId}/link`);
183
+ }
184
+ catch (error) {
185
+ throw new Error(`Failed to unlink webhook: ${error}`);
186
+ }
187
+ }
147
188
  // Generic request method for custom API calls
148
189
  async request(method, endpoint, data, options) {
149
190
  return this.makeRequest(method, endpoint, data, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-cribops",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "description": "n8n community node for Cribops AI platform integration",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"