n8n-nodes-richpanel 1.1.2 → 1.1.4

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.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Richpanel = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
+ const BASE_URL = 'https://api.richpanel.com/v1';
5
6
  class Richpanel {
6
7
  constructor() {
7
8
  this.description = {
@@ -1356,7 +1357,7 @@ async function handleConversationOperations(operation, itemIndex) {
1356
1357
  }
1357
1358
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1358
1359
  method: 'POST',
1359
- url: '/tickets',
1360
+ url: `${BASE_URL}/tickets`,
1360
1361
  body,
1361
1362
  json: true,
1362
1363
  });
@@ -1378,7 +1379,7 @@ async function handleConversationOperations(operation, itemIndex) {
1378
1379
  }
1379
1380
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1380
1381
  method: 'PUT',
1381
- url: `/tickets/${conversationId}`,
1382
+ url: `${BASE_URL}/tickets/${conversationId}`,
1382
1383
  body,
1383
1384
  json: true,
1384
1385
  });
@@ -1387,7 +1388,7 @@ async function handleConversationOperations(operation, itemIndex) {
1387
1388
  const conversationId = this.getNodeParameter('conversationId', itemIndex);
1388
1389
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1389
1390
  method: 'GET',
1390
- url: `/tickets/${conversationId}`,
1391
+ url: `${BASE_URL}/tickets/${conversationId}`,
1391
1392
  json: true,
1392
1393
  });
1393
1394
  }
@@ -1395,7 +1396,7 @@ async function handleConversationOperations(operation, itemIndex) {
1395
1396
  const conversationNumber = this.getNodeParameter('conversationNumber', itemIndex);
1396
1397
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1397
1398
  method: 'GET',
1398
- url: `/tickets/number/${conversationNumber}`,
1399
+ url: `${BASE_URL}/tickets/number/${conversationNumber}`,
1399
1400
  json: true,
1400
1401
  });
1401
1402
  }
@@ -1404,7 +1405,7 @@ async function handleConversationOperations(operation, itemIndex) {
1404
1405
  const customerIdentifier = this.getNodeParameter('customerIdentifier', itemIndex);
1405
1406
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1406
1407
  method: 'GET',
1407
- url: `/tickets/${customerType}/${customerIdentifier}`,
1408
+ url: `${BASE_URL}/tickets/${customerType}/${customerIdentifier}`,
1408
1409
  json: true,
1409
1410
  });
1410
1411
  }
@@ -1481,7 +1482,7 @@ async function handleCustomerOperations(operation, itemIndex) {
1481
1482
  }
1482
1483
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1483
1484
  method: 'POST',
1484
- url: '/customers',
1485
+ url: `${BASE_URL}/customers`,
1485
1486
  body,
1486
1487
  json: true,
1487
1488
  });
@@ -1491,7 +1492,7 @@ async function handleCustomerOperations(operation, itemIndex) {
1491
1492
  const customerIdentifier = this.getNodeParameter('customerIdentifier', itemIndex);
1492
1493
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1493
1494
  method: 'GET',
1494
- url: `/customers/${customerType}/${customerIdentifier}`,
1495
+ url: `${BASE_URL}/customers/${customerType}/${customerIdentifier}`,
1495
1496
  json: true,
1496
1497
  });
1497
1498
  }
@@ -1560,7 +1561,7 @@ async function handleOrderOperations(operation, itemIndex) {
1560
1561
  }
1561
1562
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1562
1563
  method: 'POST',
1563
- url: `/order/${appClientId}`,
1564
+ url: `${BASE_URL}/order/${appClientId}`,
1564
1565
  body,
1565
1566
  json: true,
1566
1567
  });
@@ -1569,7 +1570,7 @@ async function handleOrderOperations(operation, itemIndex) {
1569
1570
  const orderIdGet = this.getNodeParameter('orderIdGet', itemIndex);
1570
1571
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1571
1572
  method: 'GET',
1572
- url: `/order/${orderIdGet}`,
1573
+ url: `${BASE_URL}/order/${orderIdGet}`,
1573
1574
  json: true,
1574
1575
  });
1575
1576
  }
@@ -1635,7 +1636,7 @@ async function handleSubscriptionOperations(operation, itemIndex) {
1635
1636
  }
1636
1637
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1637
1638
  method: 'POST',
1638
- url: `/subscription/${appClientId}`,
1639
+ url: `${BASE_URL}/subscription/${appClientId}`,
1639
1640
  body,
1640
1641
  json: true,
1641
1642
  });
@@ -1650,7 +1651,7 @@ async function handleUserOperations(operation, itemIndex) {
1650
1651
  const userId = this.getNodeParameter('userId', itemIndex);
1651
1652
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1652
1653
  method: 'GET',
1653
- url: `/users/${userId}`,
1654
+ url: `${BASE_URL}/users/${userId}`,
1654
1655
  json: true,
1655
1656
  });
1656
1657
  }
@@ -1670,7 +1671,7 @@ async function handleUserOperations(operation, itemIndex) {
1670
1671
  qs.per_page = options.perPage;
1671
1672
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1672
1673
  method: 'GET',
1673
- url: '/users',
1674
+ url: `${BASE_URL}/users`,
1674
1675
  qs,
1675
1676
  json: true,
1676
1677
  });
@@ -1687,7 +1688,7 @@ async function handleTagOperations(operation, itemIndex) {
1687
1688
  const tagColor = this.getNodeParameter('tagColor', itemIndex);
1688
1689
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1689
1690
  method: 'POST',
1690
- url: '/tags',
1691
+ url: `${BASE_URL}/tags`,
1691
1692
  body: {
1692
1693
  name: tagName,
1693
1694
  color: tagColor,
@@ -1711,7 +1712,7 @@ async function handleTagOperations(operation, itemIndex) {
1711
1712
  qs.per_page = options.perPage;
1712
1713
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1713
1714
  method: 'GET',
1714
- url: '/tags',
1715
+ url: `${BASE_URL}/tags`,
1715
1716
  qs,
1716
1717
  json: true,
1717
1718
  });
@@ -1727,7 +1728,7 @@ async function handleChannelOperations(operation, itemIndex) {
1727
1728
  const channelId = this.getNodeParameter('channelId', itemIndex);
1728
1729
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1729
1730
  method: 'GET',
1730
- url: `/channel/${channelId}`,
1731
+ url: `${BASE_URL}/channel/${channelId}`,
1731
1732
  json: true,
1732
1733
  });
1733
1734
  }
@@ -1747,7 +1748,7 @@ async function handleChannelOperations(operation, itemIndex) {
1747
1748
  qs.per_page = options.perPage;
1748
1749
  return await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1749
1750
  method: 'GET',
1750
- url: '/channel',
1751
+ url: `${BASE_URL}/channel`,
1751
1752
  qs,
1752
1753
  json: true,
1753
1754
  });
@@ -1765,7 +1766,7 @@ async function paginateResults(endpoint) {
1765
1766
  while (hasMore) {
1766
1767
  const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'richpanelApi', {
1767
1768
  method: 'GET',
1768
- url: endpoint,
1769
+ url: `${BASE_URL}${endpoint}`,
1769
1770
  qs: { page, per_page: 100 },
1770
1771
  json: true,
1771
1772
  }));
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RichpanelTool = void 0;
4
+ const tools_1 = require("@langchain/core/tools");
5
+ const zod_1 = require("zod");
4
6
  class RichpanelTool {
5
7
  constructor() {
6
8
  this.description = {
@@ -103,203 +105,208 @@ class RichpanelTool {
103
105
  }
104
106
  async supplyData() {
105
107
  const operations = this.getNodeParameter('operations', 0, []);
106
- const toolDefinitions = [];
108
+ const credentials = await this.getCredentials('richpanelApi');
109
+ const apiKey = credentials.apiKey;
110
+ const tools = [];
111
+ // Capture the context for use in tool implementations
112
+ const context = this;
113
+ // Helper function to make API requests
114
+ const makeApiRequest = async (method, endpoint, body) => {
115
+ const options = {
116
+ method,
117
+ url: `https://api.richpanel.com/v1${endpoint}`,
118
+ headers: {
119
+ 'x-richpanel-key': apiKey,
120
+ 'Content-Type': 'application/json',
121
+ Accept: 'application/json',
122
+ },
123
+ body: body ? JSON.stringify(body) : undefined,
124
+ json: true,
125
+ };
126
+ try {
127
+ const response = await context.helpers.httpRequest(options);
128
+ return response;
129
+ }
130
+ catch (error) {
131
+ throw new Error(`Richpanel API error: ${error.message}`);
132
+ }
133
+ };
107
134
  // Create Conversation Tool
108
135
  if (operations.includes('createConversation')) {
109
- toolDefinitions.push({
136
+ const createConversationTool = new tools_1.DynamicStructuredTool({
110
137
  name: 'richpanel_create_conversation',
111
138
  description: 'Create a new support conversation/ticket in Richpanel. Use this when a customer needs help, reports an issue, or has a question that needs tracking.',
112
- schema: {
113
- type: 'object',
114
- properties: {
115
- messageBody: {
116
- type: 'string',
117
- description: 'The customer message content or issue description',
118
- },
119
- customerEmail: {
120
- type: 'string',
121
- description: 'Customer email address',
122
- },
123
- subject: {
124
- type: 'string',
125
- description: 'Subject line for the conversation/ticket',
126
- },
127
- priority: {
128
- type: 'string',
129
- enum: ['HIGH', 'LOW'],
130
- description: 'Priority level (HIGH for urgent issues, LOW for general questions)',
131
- },
132
- },
133
- required: ['messageBody', 'customerEmail'],
139
+ schema: zod_1.z.object({
140
+ messageBody: zod_1.z.string().describe('The customer message content or issue description'),
141
+ customerEmail: zod_1.z.string().email().describe('Customer email address'),
142
+ subject: zod_1.z.string().optional().describe('Subject line for the conversation/ticket'),
143
+ priority: zod_1.z
144
+ .enum(['HIGH', 'LOW'])
145
+ .optional()
146
+ .describe('Priority level (HIGH for urgent issues, LOW for general questions)'),
147
+ }),
148
+ func: async (input) => {
149
+ const { messageBody, customerEmail, subject, priority } = input;
150
+ const body = {
151
+ message_body: messageBody,
152
+ customer_email: customerEmail,
153
+ };
154
+ if (subject)
155
+ body.subject = subject;
156
+ if (priority)
157
+ body.priority = priority;
158
+ const result = await makeApiRequest('POST', '/conversations', body);
159
+ return JSON.stringify(result);
134
160
  },
135
161
  });
162
+ tools.push(createConversationTool);
136
163
  }
137
164
  // Get Conversation Tool
138
165
  if (operations.includes('getConversation')) {
139
- toolDefinitions.push({
166
+ const getConversationTool = new tools_1.DynamicStructuredTool({
140
167
  name: 'richpanel_get_conversation',
141
168
  description: 'Retrieve details about an existing conversation/ticket by ID. Use this to check ticket status, see assigned agent, read conversation history, or verify if an issue is resolved.',
142
- schema: {
143
- type: 'object',
144
- properties: {
145
- conversationId: {
146
- type: 'string',
147
- description: 'The unique ID of the conversation/ticket',
148
- },
149
- },
150
- required: ['conversationId'],
169
+ schema: zod_1.z.object({
170
+ conversationId: zod_1.z.string().describe('The unique ID of the conversation/ticket'),
171
+ }),
172
+ func: async (input) => {
173
+ const { conversationId } = input;
174
+ const result = await makeApiRequest('GET', `/conversations/${conversationId}`);
175
+ return JSON.stringify(result);
151
176
  },
152
177
  });
178
+ tools.push(getConversationTool);
153
179
  }
154
180
  // Update Conversation Tool
155
181
  if (operations.includes('updateConversation')) {
156
- toolDefinitions.push({
182
+ const updateConversationTool = new tools_1.DynamicStructuredTool({
157
183
  name: 'richpanel_update_conversation',
158
184
  description: 'Update conversation properties like status or priority. Use this to close resolved tickets, change priority levels, or update conversation state.',
159
- schema: {
160
- type: 'object',
161
- properties: {
162
- conversationId: {
163
- type: 'string',
164
- description: 'The unique ID of the conversation to update',
165
- },
166
- status: {
167
- type: 'string',
168
- enum: ['OPEN', 'CLOSED'],
169
- description: 'New status (CLOSED when issue is resolved, OPEN otherwise)',
170
- },
171
- priority: {
172
- type: 'string',
173
- enum: ['HIGH', 'LOW'],
174
- description: 'New priority level',
175
- },
176
- },
177
- required: ['conversationId'],
185
+ schema: zod_1.z.object({
186
+ conversationId: zod_1.z.string().describe('The unique ID of the conversation to update'),
187
+ status: zod_1.z
188
+ .enum(['OPEN', 'CLOSED'])
189
+ .optional()
190
+ .describe('New status (CLOSED when issue is resolved, OPEN otherwise)'),
191
+ priority: zod_1.z.enum(['HIGH', 'LOW']).optional().describe('New priority level'),
192
+ }),
193
+ func: async (input) => {
194
+ const { conversationId, status, priority } = input;
195
+ const body = {};
196
+ if (status)
197
+ body.status = status;
198
+ if (priority)
199
+ body.priority = priority;
200
+ const result = await makeApiRequest('PUT', `/conversations/${conversationId}`, body);
201
+ return JSON.stringify(result);
178
202
  },
179
203
  });
204
+ tools.push(updateConversationTool);
180
205
  }
181
206
  // Get Customer Tool
182
207
  if (operations.includes('getCustomer')) {
183
- toolDefinitions.push({
208
+ const getCustomerTool = new tools_1.DynamicStructuredTool({
184
209
  name: 'richpanel_get_customer',
185
210
  description: 'Retrieve customer information by email or phone number. Use this to look up customer details, see order history, check customer status, or verify customer information.',
186
- schema: {
187
- type: 'object',
188
- properties: {
189
- identifier: {
190
- type: 'string',
191
- description: 'Customer email address or phone number',
192
- },
193
- type: {
194
- type: 'string',
195
- enum: ['email', 'phone'],
196
- description: 'Type of identifier (email or phone)',
197
- default: 'email',
198
- },
199
- },
200
- required: ['identifier'],
211
+ schema: zod_1.z.object({
212
+ identifier: zod_1.z.string().describe('Customer email address or phone number'),
213
+ type: zod_1.z
214
+ .enum(['email', 'phone'])
215
+ .default('email')
216
+ .describe('Type of identifier (email or phone)'),
217
+ }),
218
+ func: async (input) => {
219
+ const { identifier, type } = input;
220
+ const endpoint = type === 'email' ? `/customers/${identifier}` : `/customers/phone/${identifier}`;
221
+ const result = await makeApiRequest('GET', endpoint);
222
+ return JSON.stringify(result);
201
223
  },
202
224
  });
225
+ tools.push(getCustomerTool);
203
226
  }
204
227
  // Create/Update Customer Tool
205
228
  if (operations.includes('upsertCustomer')) {
206
- toolDefinitions.push({
229
+ const upsertCustomerTool = new tools_1.DynamicStructuredTool({
207
230
  name: 'richpanel_create_update_customer',
208
231
  description: 'Create a new customer or update existing customer information. Use this when a customer provides updated details or to add a new customer to the system.',
209
- schema: {
210
- type: 'object',
211
- properties: {
212
- email: {
213
- type: 'string',
214
- description: 'Customer email address (required)',
215
- },
216
- firstName: {
217
- type: 'string',
218
- description: 'Customer first name',
219
- },
220
- lastName: {
221
- type: 'string',
222
- description: 'Customer last name',
223
- },
224
- phone: {
225
- type: 'string',
226
- description: 'Customer phone number',
227
- },
228
- city: {
229
- type: 'string',
230
- description: 'Customer city',
231
- },
232
- country: {
233
- type: 'string',
234
- description: 'Customer country',
235
- },
236
- },
237
- required: ['email'],
232
+ schema: zod_1.z.object({
233
+ email: zod_1.z.string().email().describe('Customer email address (required)'),
234
+ firstName: zod_1.z.string().optional().describe('Customer first name'),
235
+ lastName: zod_1.z.string().optional().describe('Customer last name'),
236
+ phone: zod_1.z.string().optional().describe('Customer phone number'),
237
+ city: zod_1.z.string().optional().describe('Customer city'),
238
+ country: zod_1.z.string().optional().describe('Customer country'),
239
+ }),
240
+ func: async (input) => {
241
+ const { email, firstName, lastName, phone, city, country } = input;
242
+ const body = { email };
243
+ if (firstName)
244
+ body.first_name = firstName;
245
+ if (lastName)
246
+ body.last_name = lastName;
247
+ if (phone)
248
+ body.phone = phone;
249
+ if (city)
250
+ body.city = city;
251
+ if (country)
252
+ body.country = country;
253
+ const result = await makeApiRequest('POST', '/customers', body);
254
+ return JSON.stringify(result);
238
255
  },
239
256
  });
257
+ tools.push(upsertCustomerTool);
240
258
  }
241
259
  // Get Order Tool
242
260
  if (operations.includes('getOrder')) {
243
- toolDefinitions.push({
261
+ const getOrderTool = new tools_1.DynamicStructuredTool({
244
262
  name: 'richpanel_get_order',
245
263
  description: 'Retrieve order information by order ID. Use this when a customer asks about order status, shipping, tracking, or order details.',
246
- schema: {
247
- type: 'object',
248
- properties: {
249
- orderId: {
250
- type: 'string',
251
- description: 'The unique order ID/number',
252
- },
253
- },
254
- required: ['orderId'],
264
+ schema: zod_1.z.object({
265
+ orderId: zod_1.z.string().describe('The unique order ID/number'),
266
+ }),
267
+ func: async (input) => {
268
+ const { orderId } = input;
269
+ const result = await makeApiRequest('GET', `/orders/${orderId}`);
270
+ return JSON.stringify(result);
255
271
  },
256
272
  });
273
+ tools.push(getOrderTool);
257
274
  }
258
275
  // Add Tags Tool
259
276
  if (operations.includes('addTags')) {
260
- toolDefinitions.push({
277
+ const addTagsTool = new tools_1.DynamicStructuredTool({
261
278
  name: 'richpanel_add_tags',
262
279
  description: 'Add tags to a conversation for categorization and organization. Use this to tag tickets by issue type, urgency, department, or any other category.',
263
- schema: {
264
- type: 'object',
265
- properties: {
266
- conversationId: {
267
- type: 'string',
268
- description: 'The conversation ID to add tags to',
269
- },
270
- tags: {
271
- type: 'array',
272
- items: {
273
- type: 'string',
274
- },
275
- description: 'Array of tag names (e.g., ["billing", "urgent", "refund"])',
276
- },
277
- },
278
- required: ['conversationId', 'tags'],
280
+ schema: zod_1.z.object({
281
+ conversationId: zod_1.z.string().describe('The conversation ID to add tags to'),
282
+ tags: zod_1.z
283
+ .array(zod_1.z.string())
284
+ .describe('Array of tag names (e.g., ["billing", "urgent", "refund"])'),
285
+ }),
286
+ func: async (input) => {
287
+ const { conversationId, tags } = input;
288
+ const body = { tags };
289
+ const result = await makeApiRequest('POST', `/conversations/${conversationId}/tags`, body);
290
+ return JSON.stringify(result);
279
291
  },
280
292
  });
293
+ tools.push(addTagsTool);
281
294
  }
282
295
  // List Users Tool
283
296
  if (operations.includes('listUsers')) {
284
- toolDefinitions.push({
297
+ const listUsersTool = new tools_1.DynamicStructuredTool({
285
298
  name: 'richpanel_list_users',
286
299
  description: 'Get a list of all support agents/users in Richpanel. Use this when a customer asks to speak with an agent, or to find available support staff.',
287
- schema: {
288
- type: 'object',
289
- properties: {},
300
+ schema: zod_1.z.object({}),
301
+ func: async () => {
302
+ const result = await makeApiRequest('GET', '/users');
303
+ return JSON.stringify(result);
290
304
  },
291
305
  });
306
+ tools.push(listUsersTool);
292
307
  }
293
- // Return tool definitions for AI agent
294
308
  return {
295
- response: toolDefinitions.map((tool) => ({
296
- type: 'function',
297
- function: {
298
- name: tool.name,
299
- description: tool.description,
300
- parameters: tool.schema,
301
- },
302
- })),
309
+ response: tools,
303
310
  };
304
311
  }
305
312
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-richpanel",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "n8n community node for Richpanel customer support platform - manage conversations, customers, orders, and subscriptions",
5
5
  "keywords": [
6
6
  "n8n",
@@ -53,13 +53,15 @@
53
53
  ]
54
54
  },
55
55
  "devDependencies": {
56
+ "@langchain/core": "^0.3.80",
56
57
  "@typescript-eslint/parser": "^5.59.0",
57
58
  "eslint": "^8.40.0",
58
59
  "eslint-plugin-n8n-nodes-base": "^1.12.0",
59
60
  "gulp": "^4.0.2",
60
61
  "n8n-workflow": "^1.0.0",
61
62
  "prettier": "^2.8.8",
62
- "typescript": "^5.0.4"
63
+ "typescript": "^5.0.4",
64
+ "zod": "^4.3.2"
63
65
  },
64
66
  "peerDependencies": {
65
67
  "n8n-workflow": "*"