n8n-nodes-cribops 0.1.16 → 0.1.18
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/CribopsApi.credentials.js +1 -1
- package/dist/nodes/Cribops/Cribops.node.js +88 -0
- package/dist/nodes/CribopsTrigger/CribopsTrigger.node.d.ts +2 -3
- package/dist/nodes/CribopsTrigger/CribopsTrigger.node.js +91 -78
- package/dist/package.json +1 -1
- package/dist/utils/CribopsHttp.d.ts +22 -1
- package/dist/utils/CribopsHttp.js +36 -0
- package/package.json +1 -1
|
@@ -48,6 +48,12 @@ class Cribops {
|
|
|
48
48
|
description: 'List all available agents',
|
|
49
49
|
action: 'List all available agents',
|
|
50
50
|
},
|
|
51
|
+
{
|
|
52
|
+
name: 'Poll Queue',
|
|
53
|
+
value: 'pollQueue',
|
|
54
|
+
description: 'Poll messages from the queue',
|
|
55
|
+
action: 'Poll messages from the queue',
|
|
56
|
+
},
|
|
51
57
|
{
|
|
52
58
|
name: 'Reply to Conversation',
|
|
53
59
|
value: 'replyToConversation',
|
|
@@ -149,6 +155,45 @@ class Cribops {
|
|
|
149
155
|
},
|
|
150
156
|
description: 'Whether to show typing indicator (true) or stop typing (false)',
|
|
151
157
|
},
|
|
158
|
+
{
|
|
159
|
+
displayName: 'Tenant ID',
|
|
160
|
+
name: 'tenantId',
|
|
161
|
+
type: 'string',
|
|
162
|
+
required: true,
|
|
163
|
+
default: '',
|
|
164
|
+
placeholder: 'my-tenant',
|
|
165
|
+
displayOptions: {
|
|
166
|
+
show: {
|
|
167
|
+
operation: ['pollQueue'],
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
description: 'The tenant ID for your Cribops organization',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
displayName: 'Batch Size',
|
|
174
|
+
name: 'batchSize',
|
|
175
|
+
type: 'number',
|
|
176
|
+
default: 10,
|
|
177
|
+
displayOptions: {
|
|
178
|
+
show: {
|
|
179
|
+
operation: ['pollQueue'],
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
description: 'Number of messages to retrieve (max 100)',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
displayName: 'Queue Name',
|
|
186
|
+
name: 'queueName',
|
|
187
|
+
type: 'string',
|
|
188
|
+
default: '',
|
|
189
|
+
placeholder: 'e.g., stripe_events',
|
|
190
|
+
displayOptions: {
|
|
191
|
+
show: {
|
|
192
|
+
operation: ['pollQueue'],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
description: 'Specific queue to poll (optional). Leave empty to poll all queues.',
|
|
196
|
+
},
|
|
152
197
|
{
|
|
153
198
|
displayName: 'Message',
|
|
154
199
|
name: 'message',
|
|
@@ -342,6 +387,9 @@ class Cribops {
|
|
|
342
387
|
case 'listAgents':
|
|
343
388
|
responseData = await listAgents(this, cribopsHttp, i);
|
|
344
389
|
break;
|
|
390
|
+
case 'pollQueue':
|
|
391
|
+
responseData = await pollQueue(this, cribopsHttp, i);
|
|
392
|
+
break;
|
|
345
393
|
default:
|
|
346
394
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
|
|
347
395
|
}
|
|
@@ -536,6 +584,46 @@ async function listAgents(executeFunctions, cribopsHttp, itemIndex) {
|
|
|
536
584
|
const agents = await cribopsHttp.getAgents();
|
|
537
585
|
return { agents, count: agents.length };
|
|
538
586
|
}
|
|
587
|
+
async function pollQueue(executeFunctions, cribopsHttp, itemIndex) {
|
|
588
|
+
const tenantId = executeFunctions.getNodeParameter('tenantId', itemIndex);
|
|
589
|
+
const batchSize = executeFunctions.getNodeParameter('batchSize', itemIndex, 10);
|
|
590
|
+
const queueName = executeFunctions.getNodeParameter('queueName', itemIndex, '') || undefined;
|
|
591
|
+
const messages = await cribopsHttp.pollQueue(tenantId, batchSize, queueName);
|
|
592
|
+
// Process each message to parse the data if it's JSON
|
|
593
|
+
const processedMessages = messages.map(message => {
|
|
594
|
+
let parsedData = message.data.data;
|
|
595
|
+
try {
|
|
596
|
+
parsedData = JSON.parse(message.data.data);
|
|
597
|
+
}
|
|
598
|
+
catch (e) {
|
|
599
|
+
// Keep as string if not valid JSON
|
|
600
|
+
}
|
|
601
|
+
return {
|
|
602
|
+
id: message.id,
|
|
603
|
+
correlation_id: message.correlation_id,
|
|
604
|
+
queue_name: message.queue_name,
|
|
605
|
+
data: parsedData,
|
|
606
|
+
headers: message.data.headers,
|
|
607
|
+
params: message.data.params,
|
|
608
|
+
inserted_at: message.inserted_at,
|
|
609
|
+
// Extract useful fields from headers
|
|
610
|
+
tenant_id: message.data.headers['x-cribops-tenant-id'] || tenantId,
|
|
611
|
+
path: message.data.headers['x-cribops-path'],
|
|
612
|
+
};
|
|
613
|
+
});
|
|
614
|
+
// Auto-acknowledge messages after processing
|
|
615
|
+
if (messages.length > 0) {
|
|
616
|
+
const messageIds = messages.map(msg => msg.id);
|
|
617
|
+
try {
|
|
618
|
+
await cribopsHttp.acknowledgeMessages(tenantId, messageIds);
|
|
619
|
+
}
|
|
620
|
+
catch (ackError) {
|
|
621
|
+
// Log error but don't fail the operation
|
|
622
|
+
console.error('Failed to acknowledge messages:', ackError);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
return { messages: processedMessages, count: processedMessages.length };
|
|
626
|
+
}
|
|
539
627
|
async function sendTypingIndicator(executeFunctions, cribopsHttp, itemIndex) {
|
|
540
628
|
const agentId = executeFunctions.getNodeParameter('agentId', itemIndex, '', { extractValue: true });
|
|
541
629
|
const conversationId = executeFunctions.getNodeParameter('conversationId', itemIndex);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { INodeType, INodeTypeDescription,
|
|
1
|
+
import { INodeType, INodeTypeDescription, IWebhookFunctions, IWebhookResponseData, IHookFunctions, ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
|
|
2
2
|
export declare class CribopsTrigger implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|
|
5
5
|
loadOptions: {
|
|
6
|
-
|
|
6
|
+
getWebhooks(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
9
|
webhookMethods: {
|
|
@@ -13,6 +13,5 @@ export declare class CribopsTrigger implements INodeType {
|
|
|
13
13
|
delete(this: IHookFunctions): Promise<boolean>;
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
|
-
trigger(this: ITriggerFunctions): Promise<ITriggerResponse>;
|
|
17
16
|
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
18
17
|
}
|
|
@@ -10,7 +10,7 @@ class CribopsTrigger {
|
|
|
10
10
|
icon: 'file:cribopstrigger.svg',
|
|
11
11
|
group: ['trigger'],
|
|
12
12
|
version: 1,
|
|
13
|
-
description: 'Triggers when receiving messages
|
|
13
|
+
description: 'Triggers when receiving messages via Cribops webhook',
|
|
14
14
|
defaults: {
|
|
15
15
|
name: 'Cribops Trigger',
|
|
16
16
|
},
|
|
@@ -27,21 +27,21 @@ class CribopsTrigger {
|
|
|
27
27
|
name: 'default',
|
|
28
28
|
httpMethod: 'POST',
|
|
29
29
|
responseMode: 'onReceived',
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
path: '={{$parameter["webhookId"]}}',
|
|
31
|
+
isFullPath: false,
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
34
|
properties: [
|
|
35
35
|
{
|
|
36
|
-
displayName: '
|
|
37
|
-
name: '
|
|
36
|
+
displayName: 'Webhook Name or ID',
|
|
37
|
+
name: 'webhookId',
|
|
38
38
|
type: 'options',
|
|
39
39
|
required: true,
|
|
40
40
|
typeOptions: {
|
|
41
|
-
loadOptionsMethod: '
|
|
41
|
+
loadOptionsMethod: 'getWebhooks',
|
|
42
42
|
},
|
|
43
43
|
default: '',
|
|
44
|
-
description: 'The Cribops
|
|
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>.',
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
displayName: 'Event Types',
|
|
@@ -63,8 +63,13 @@ class CribopsTrigger {
|
|
|
63
63
|
value: 'file_attachment',
|
|
64
64
|
description: 'File attachments',
|
|
65
65
|
},
|
|
66
|
+
{
|
|
67
|
+
name: 'System Event',
|
|
68
|
+
value: 'system_event',
|
|
69
|
+
description: 'System events and notifications',
|
|
70
|
+
},
|
|
66
71
|
],
|
|
67
|
-
default: ['user_message'],
|
|
72
|
+
default: ['user_message', 'agent_response'],
|
|
68
73
|
description: 'Types of events to trigger on',
|
|
69
74
|
},
|
|
70
75
|
{
|
|
@@ -82,7 +87,14 @@ class CribopsTrigger {
|
|
|
82
87
|
password: true,
|
|
83
88
|
},
|
|
84
89
|
default: '',
|
|
85
|
-
description: 'Secret token for webhook
|
|
90
|
+
description: 'Secret token for webhook signature validation',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
displayName: 'Include Headers',
|
|
94
|
+
name: 'includeHeaders',
|
|
95
|
+
type: 'boolean',
|
|
96
|
+
default: false,
|
|
97
|
+
description: 'Whether to include the webhook headers in the output',
|
|
86
98
|
},
|
|
87
99
|
],
|
|
88
100
|
},
|
|
@@ -90,22 +102,25 @@ class CribopsTrigger {
|
|
|
90
102
|
};
|
|
91
103
|
methods = {
|
|
92
104
|
loadOptions: {
|
|
93
|
-
async
|
|
105
|
+
async getWebhooks() {
|
|
94
106
|
const credentials = await this.getCredentials('cribopsApi');
|
|
95
107
|
const cribopsHttp = new CribopsHttp_1.CribopsHttp({
|
|
96
108
|
baseUrl: credentials.baseUrl,
|
|
97
109
|
apiToken: credentials.apiToken,
|
|
98
110
|
});
|
|
99
111
|
try {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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,
|
|
118
|
+
value: webhook.id,
|
|
119
|
+
description: webhook.description || `Webhook ID: ${webhook.id}`,
|
|
105
120
|
}));
|
|
106
121
|
}
|
|
107
122
|
catch (error) {
|
|
108
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load
|
|
123
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load webhooks: ${error instanceof Error ? error.message : String(error)}`);
|
|
109
124
|
}
|
|
110
125
|
},
|
|
111
126
|
},
|
|
@@ -113,26 +128,13 @@ class CribopsTrigger {
|
|
|
113
128
|
webhookMethods = {
|
|
114
129
|
default: {
|
|
115
130
|
async checkExists() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const cribopsHttp = new CribopsHttp_1.CribopsHttp({
|
|
120
|
-
baseUrl: credentials.baseUrl,
|
|
121
|
-
apiToken: credentials.apiToken,
|
|
122
|
-
});
|
|
123
|
-
try {
|
|
124
|
-
// Check if webhook exists for this agent
|
|
125
|
-
// This would need to be implemented in your Cribops API
|
|
126
|
-
// For now, return false to always create
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
131
|
+
// Always return false to create webhook registration
|
|
132
|
+
// The actual webhook already exists in Cribops backend
|
|
133
|
+
return false;
|
|
132
134
|
},
|
|
133
135
|
async create() {
|
|
134
136
|
const webhookUrl = this.getNodeWebhookUrl('default');
|
|
135
|
-
const
|
|
137
|
+
const webhookId = this.getNodeParameter('webhookId');
|
|
136
138
|
const eventTypes = this.getNodeParameter('eventTypes', []);
|
|
137
139
|
const additionalFields = this.getNodeParameter('additionalFields', {});
|
|
138
140
|
const credentials = await this.getCredentials('cribopsApi');
|
|
@@ -141,30 +143,29 @@ class CribopsTrigger {
|
|
|
141
143
|
apiToken: credentials.apiToken,
|
|
142
144
|
});
|
|
143
145
|
try {
|
|
144
|
-
// Register webhook with Cribops
|
|
145
|
-
// This is a placeholder - implement actual API call
|
|
146
|
+
// Register this n8n webhook URL with the Cribops webhook
|
|
146
147
|
const body = {
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
webhook_id: webhookId,
|
|
149
|
+
target_url: webhookUrl,
|
|
149
150
|
event_types: eventTypes,
|
|
150
151
|
secret: additionalFields.secretToken || undefined,
|
|
151
152
|
};
|
|
152
|
-
//
|
|
153
|
-
|
|
153
|
+
// Register the n8n webhook URL with Cribops
|
|
154
|
+
await cribopsHttp.request('POST', `/api/v1/webhooks/${webhookId}/targets`, body);
|
|
154
155
|
// Store webhook data for later use
|
|
155
156
|
const webhookData = this.getWorkflowStaticData('node');
|
|
156
|
-
webhookData.webhookId =
|
|
157
|
-
webhookData.
|
|
157
|
+
webhookData.webhookId = webhookId;
|
|
158
|
+
webhookData.targetUrl = webhookUrl;
|
|
158
159
|
return true;
|
|
159
160
|
}
|
|
160
161
|
catch (error) {
|
|
161
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to register webhook: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to register webhook target: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
163
|
}
|
|
163
164
|
},
|
|
164
165
|
async delete() {
|
|
165
166
|
const webhookData = this.getWorkflowStaticData('node');
|
|
166
167
|
const credentials = await this.getCredentials('cribopsApi');
|
|
167
|
-
if (!webhookData.webhookId) {
|
|
168
|
+
if (!webhookData.webhookId || !webhookData.targetUrl) {
|
|
168
169
|
return true;
|
|
169
170
|
}
|
|
170
171
|
const cribopsHttp = new CribopsHttp_1.CribopsHttp({
|
|
@@ -172,38 +173,36 @@ class CribopsTrigger {
|
|
|
172
173
|
apiToken: credentials.apiToken,
|
|
173
174
|
});
|
|
174
175
|
try {
|
|
175
|
-
// Unregister webhook from Cribops
|
|
176
|
-
|
|
177
|
-
|
|
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
|
+
});
|
|
178
180
|
delete webhookData.webhookId;
|
|
179
|
-
delete webhookData.
|
|
181
|
+
delete webhookData.targetUrl;
|
|
180
182
|
return true;
|
|
181
183
|
}
|
|
182
184
|
catch (error) {
|
|
183
|
-
|
|
185
|
+
// Log error but don't fail
|
|
186
|
+
console.error('Failed to unregister webhook target:', error);
|
|
187
|
+
return true;
|
|
184
188
|
}
|
|
185
189
|
},
|
|
186
190
|
},
|
|
187
191
|
};
|
|
188
|
-
async trigger() {
|
|
189
|
-
// Minimal implementation - webhooks are handled by webhook() method
|
|
190
|
-
return {
|
|
191
|
-
closeFunction: async () => { },
|
|
192
|
-
manualTriggerFunction: async () => {
|
|
193
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'This node only works with webhooks. Please activate the workflow.');
|
|
194
|
-
},
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
192
|
async webhook() {
|
|
198
193
|
const body = this.getBodyData();
|
|
199
194
|
const headers = this.getHeaderData();
|
|
200
195
|
const eventTypes = this.getNodeParameter('eventTypes', []);
|
|
201
196
|
const additionalFields = this.getNodeParameter('additionalFields', {});
|
|
202
|
-
const
|
|
197
|
+
const webhookId = this.getNodeParameter('webhookId');
|
|
203
198
|
// Validate secret token if provided
|
|
204
199
|
if (additionalFields.secretToken) {
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
// Check for signature in headers (could be HMAC signature or bearer token)
|
|
201
|
+
const signature = headers['x-cribops-signature'] || headers['x-webhook-signature'];
|
|
202
|
+
const authHeader = headers['authorization'];
|
|
203
|
+
// You can implement HMAC signature validation here if needed
|
|
204
|
+
// For now, simple token comparison
|
|
205
|
+
if (additionalFields.secretToken !== signature && `Bearer ${additionalFields.secretToken}` !== authHeader) {
|
|
207
206
|
return {
|
|
208
207
|
webhookResponse: {
|
|
209
208
|
status: 401,
|
|
@@ -212,8 +211,9 @@ class CribopsTrigger {
|
|
|
212
211
|
};
|
|
213
212
|
}
|
|
214
213
|
}
|
|
215
|
-
// Filter by event type
|
|
216
|
-
|
|
214
|
+
// Filter by event type if specified
|
|
215
|
+
const eventType = body.event_type || body.type || body.eventType;
|
|
216
|
+
if (eventTypes.length > 0 && eventType && !eventTypes.includes(eventType)) {
|
|
217
217
|
return {
|
|
218
218
|
webhookResponse: {
|
|
219
219
|
status: 200,
|
|
@@ -221,27 +221,40 @@ class CribopsTrigger {
|
|
|
221
221
|
},
|
|
222
222
|
};
|
|
223
223
|
}
|
|
224
|
-
//
|
|
224
|
+
// Prepare output data with all relevant fields
|
|
225
225
|
const outputData = {
|
|
226
|
+
// Core webhook data
|
|
227
|
+
webhook_id: webhookId,
|
|
228
|
+
event_type: eventType,
|
|
229
|
+
// Message content
|
|
230
|
+
message: body.message || body.content || body.text,
|
|
231
|
+
// Conversation/thread tracking
|
|
232
|
+
conversation_id: body.conversation_id || body.conversationId || body.thread_id || body.threadId,
|
|
233
|
+
// User/agent identification
|
|
234
|
+
user_id: body.user_id || body.userId || body.from_user || body.fromUser,
|
|
235
|
+
agent_id: body.agent_id || body.agentId || body.to_agent || body.toAgent,
|
|
236
|
+
// Response handling
|
|
237
|
+
response_webhook: body.response_webhook || body.responseWebhook || body.callback_url || body.callbackUrl,
|
|
238
|
+
// Metadata
|
|
239
|
+
metadata: body.metadata || {},
|
|
240
|
+
// File attachments if any
|
|
241
|
+
attachments: body.attachments || body.files || [],
|
|
242
|
+
// Timestamp
|
|
243
|
+
timestamp: body.timestamp || body.created_at || body.createdAt || new Date().toISOString(),
|
|
244
|
+
// Include any other fields from the webhook
|
|
226
245
|
...body,
|
|
227
|
-
agent_id: agentId,
|
|
228
|
-
// Ensure conversation_id is available (handle different field names)
|
|
229
|
-
conversation_id: body.conversation_id || body.conversationId || body.thread_id,
|
|
230
|
-
// Ensure response_webhook is available if it exists
|
|
231
|
-
response_webhook: body.response_webhook || body.responseWebhook || body.callback_url,
|
|
232
246
|
};
|
|
233
|
-
//
|
|
234
|
-
|
|
247
|
+
// Include headers if requested
|
|
248
|
+
const workflowData = additionalFields.includeHeaders
|
|
249
|
+
? { json: outputData, headers }
|
|
250
|
+
: { json: outputData };
|
|
235
251
|
// Return the data to the workflow
|
|
236
252
|
return {
|
|
237
|
-
workflowData: [
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
},
|
|
243
|
-
],
|
|
244
|
-
],
|
|
253
|
+
workflowData: [[workflowData]],
|
|
254
|
+
webhookResponse: {
|
|
255
|
+
status: 200,
|
|
256
|
+
body: { received: true },
|
|
257
|
+
},
|
|
245
258
|
};
|
|
246
259
|
}
|
|
247
260
|
}
|
package/dist/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IDataObject } from 'n8n-workflow';
|
|
1
|
+
import { IDataObject, IHttpRequestMethods, IHttpRequestOptions } from 'n8n-workflow';
|
|
2
2
|
export interface CribopsHttpConfig {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
apiToken: string;
|
|
@@ -26,6 +26,17 @@ export interface CribopsWebhookMessage {
|
|
|
26
26
|
fileName?: string;
|
|
27
27
|
fileType?: string;
|
|
28
28
|
}
|
|
29
|
+
export interface CribopsQueueMessage {
|
|
30
|
+
id: number;
|
|
31
|
+
correlation_id: string;
|
|
32
|
+
queue_name: string;
|
|
33
|
+
data: {
|
|
34
|
+
data: string;
|
|
35
|
+
params: IDataObject;
|
|
36
|
+
headers: IDataObject;
|
|
37
|
+
};
|
|
38
|
+
inserted_at: string;
|
|
39
|
+
}
|
|
29
40
|
export declare class CribopsHttp {
|
|
30
41
|
private config;
|
|
31
42
|
constructor(config: CribopsHttpConfig);
|
|
@@ -37,4 +48,14 @@ export declare class CribopsHttp {
|
|
|
37
48
|
validateWebhook(payload: any, signature: string): Promise<boolean>;
|
|
38
49
|
testConnection(): Promise<boolean>;
|
|
39
50
|
sendTypingIndicator(agentId: string, conversationId: string, typing: boolean): Promise<any>;
|
|
51
|
+
pollQueue(tenantId: string, limit?: number, queueName?: string): Promise<CribopsQueueMessage[]>;
|
|
52
|
+
acknowledgeMessages(tenantId: string, messageIds: number[]): Promise<{
|
|
53
|
+
status: string;
|
|
54
|
+
deleted_count: number;
|
|
55
|
+
}>;
|
|
56
|
+
failMessages(tenantId: string, messageIds: number[], errorMessage: string): Promise<{
|
|
57
|
+
status: string;
|
|
58
|
+
updated_count: number;
|
|
59
|
+
}>;
|
|
60
|
+
request<T = any>(method: IHttpRequestMethods, endpoint: string, data?: IDataObject, options?: Partial<IHttpRequestOptions>): Promise<T>;
|
|
40
61
|
}
|
|
@@ -112,5 +112,41 @@ class CribopsHttp {
|
|
|
112
112
|
throw new Error(`Failed to send typing indicator for agent ${agentId}: ${error}`);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
async pollQueue(tenantId, limit = 10, queueName) {
|
|
116
|
+
try {
|
|
117
|
+
const params = { limit };
|
|
118
|
+
if (queueName) {
|
|
119
|
+
params.queue_name = queueName;
|
|
120
|
+
}
|
|
121
|
+
const url = `/api/queue/${tenantId}/poll?${new URLSearchParams(params).toString()}`;
|
|
122
|
+
const response = await this.makeRequest('GET', url);
|
|
123
|
+
return response;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw new Error(`Failed to poll queue for tenant ${tenantId}: ${error}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async acknowledgeMessages(tenantId, messageIds) {
|
|
130
|
+
try {
|
|
131
|
+
const response = await this.makeRequest('POST', `/api/queue/${tenantId}/acknowledge`, { message_ids: messageIds });
|
|
132
|
+
return response;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
throw new Error(`Failed to acknowledge messages for tenant ${tenantId}: ${error}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async failMessages(tenantId, messageIds, errorMessage) {
|
|
139
|
+
try {
|
|
140
|
+
const response = await this.makeRequest('POST', `/api/queue/${tenantId}/fail`, { message_ids: messageIds, error_message: errorMessage });
|
|
141
|
+
return response;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new Error(`Failed to mark messages as failed for tenant ${tenantId}: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Generic request method for custom API calls
|
|
148
|
+
async request(method, endpoint, data, options) {
|
|
149
|
+
return this.makeRequest(method, endpoint, data, options);
|
|
150
|
+
}
|
|
115
151
|
}
|
|
116
152
|
exports.CribopsHttp = CribopsHttp;
|