@wesell/n8n-nodes-confirmx 0.1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/credentials/ConfirmXApi.credentials.d.ts +18 -0
- package/credentials/ConfirmXApi.credentials.js +31 -0
- package/credentials/ConfirmXApi.credentials.js.map +1 -0
- package/credentials/ConfirmXApi.credentials.ts +40 -0
- package/index.d.ts +14 -0
- package/index.js +26 -0
- package/nodes/ConfirmX/ConfirmXAccount.node.d.ts +5 -0
- package/nodes/ConfirmX/ConfirmXAccount.node.js +81 -0
- package/nodes/ConfirmX/ConfirmXAccount.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXAccount.node.ts +81 -0
- package/nodes/ConfirmX/ConfirmXConversation.node.d.ts +13 -0
- package/nodes/ConfirmX/ConfirmXConversation.node.js +266 -0
- package/nodes/ConfirmX/ConfirmXConversation.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXConversation.node.ts +263 -0
- package/nodes/ConfirmX/ConfirmXMessage.node.d.ts +13 -0
- package/nodes/ConfirmX/ConfirmXMessage.node.js +364 -0
- package/nodes/ConfirmX/ConfirmXMessage.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXMessage.node.ts +361 -0
- package/nodes/ConfirmX/ConfirmXShippingZone.node.d.ts +5 -0
- package/nodes/ConfirmX/ConfirmXShippingZone.node.js +100 -0
- package/nodes/ConfirmX/ConfirmXShippingZone.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXShippingZone.node.ts +103 -0
- package/nodes/ConfirmX/ConfirmXTemplate.node.d.ts +13 -0
- package/nodes/ConfirmX/ConfirmXTemplate.node.js +310 -0
- package/nodes/ConfirmX/ConfirmXTemplate.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXTemplate.node.ts +310 -0
- package/nodes/ConfirmX/ConfirmXTrigger.node.d.ts +29 -0
- package/nodes/ConfirmX/ConfirmXTrigger.node.js +190 -0
- package/nodes/ConfirmX/ConfirmXTrigger.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXTrigger.node.ts +245 -0
- package/nodes/ConfirmX/ConfirmXWebhook.node.d.ts +5 -0
- package/nodes/ConfirmX/ConfirmXWebhook.node.js +169 -0
- package/nodes/ConfirmX/ConfirmXWebhook.node.js.map +1 -0
- package/nodes/ConfirmX/ConfirmXWebhook.node.ts +163 -0
- package/nodes/ConfirmX/confirmx.svg +4 -0
- package/package.json +69 -0
- package/transports/http.d.ts +43 -0
- package/transports/http.js +117 -0
- package/transports/http.js.map +1 -0
- package/transports/http.ts +170 -0
- package/transports/signature.d.ts +21 -0
- package/transports/signature.js +50 -0
- package/transports/signature.js.map +1 -0
- package/transports/signature.ts +55 -0
- package/types/api.d.ts +199 -0
- package/types/api.js +21 -0
- package/types/api.js.map +1 -0
- package/types/api.ts +238 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfirmXConversation = void 0;
|
|
4
|
+
const http_1 = require("../../transports/http");
|
|
5
|
+
class ConfirmXConversation {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'ConfirmX Conversation',
|
|
9
|
+
name: 'confirmXConversation',
|
|
10
|
+
icon: 'file:confirmx.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
14
|
+
description: 'Read and manage WhatsApp conversations: list, view, mark read, change status, assign to a teammate.',
|
|
15
|
+
defaults: { name: 'ConfirmX Conversation' },
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [{ name: 'confirmXApi', required: true }],
|
|
19
|
+
properties: [
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Operation',
|
|
22
|
+
name: 'operation',
|
|
23
|
+
type: 'options',
|
|
24
|
+
noDataExpression: true,
|
|
25
|
+
options: [
|
|
26
|
+
{
|
|
27
|
+
name: 'List',
|
|
28
|
+
value: 'list',
|
|
29
|
+
action: 'List conversations',
|
|
30
|
+
description: 'List recent WhatsApp conversations for the org. Use to discover open conversations, find a conversation by contact phone or name, or check unread counts. Supports `status` filter (open/resolved/archived), free-text `q` search, and tag CSV. Returns up to 100 per page with `messages[0]` as the latest preview.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Get',
|
|
34
|
+
value: 'get',
|
|
35
|
+
action: 'Get conversation',
|
|
36
|
+
description: 'Fetch a single conversation by id. Use when you already have a `conversationId` (from a webhook, from List, or from an upstream node) and need the contact, account, and latest message. Requires `conversationId`.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Mark Read',
|
|
40
|
+
value: 'markRead',
|
|
41
|
+
action: 'Mark as read',
|
|
42
|
+
description: 'Zero the unread counter on a conversation. Use after a human or AI finishes handling the thread so the badge clears. Requires `conversationId`.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'Update Status',
|
|
46
|
+
value: 'updateStatus',
|
|
47
|
+
action: 'Update status',
|
|
48
|
+
description: 'Set a conversation\'s status (`open`, `resolved`, `archived`). Use `resolved` when the issue is closed and `archived` to remove from default views. Requires `conversationId` and `status`.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Assign',
|
|
52
|
+
value: 'assign',
|
|
53
|
+
action: 'Assign to user',
|
|
54
|
+
description: 'Assign a conversation to a teammate by `assignToUserId` (or pass `null` to unassign). Requires `conversationId`. Returns the updated conversation with the `assignedTo` relation.',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
default: 'list',
|
|
58
|
+
},
|
|
59
|
+
// --- Account (optional for list, not needed for the others) ---
|
|
60
|
+
{
|
|
61
|
+
displayName: 'Account',
|
|
62
|
+
name: 'accountId',
|
|
63
|
+
type: 'resourceLocator',
|
|
64
|
+
default: { mode: 'list', value: '' },
|
|
65
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
66
|
+
modes: [
|
|
67
|
+
{ displayName: 'From List', name: 'list', type: 'list', typeOptions: { searchable: true } },
|
|
68
|
+
{ displayName: 'By ID', name: 'id', type: 'string' },
|
|
69
|
+
],
|
|
70
|
+
typeOptions: { loadOptionsMethod: 'getAccounts' },
|
|
71
|
+
description: 'Restrict list to one WhatsApp account (optional — leave empty for org-wide)',
|
|
72
|
+
},
|
|
73
|
+
// --- List filters ---
|
|
74
|
+
{
|
|
75
|
+
displayName: 'Status',
|
|
76
|
+
name: 'status',
|
|
77
|
+
type: 'options',
|
|
78
|
+
default: '',
|
|
79
|
+
options: [
|
|
80
|
+
{ name: 'All', value: '' },
|
|
81
|
+
{ name: 'Open', value: 'open' },
|
|
82
|
+
{ name: 'Resolved', value: 'resolved' },
|
|
83
|
+
{ name: 'Archived', value: 'archived' },
|
|
84
|
+
],
|
|
85
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
displayName: 'Search',
|
|
89
|
+
name: 'q',
|
|
90
|
+
type: 'string',
|
|
91
|
+
default: '',
|
|
92
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
93
|
+
description: 'Free-text search over contact phone + name + last message body',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
displayName: 'Sort By',
|
|
97
|
+
name: 'sortBy',
|
|
98
|
+
type: 'options',
|
|
99
|
+
default: 'lastMessageAt',
|
|
100
|
+
options: [
|
|
101
|
+
{ name: 'Last Message At', value: 'lastMessageAt' },
|
|
102
|
+
{ name: 'Unread Count', value: 'unreadCount' },
|
|
103
|
+
{ name: 'Created At', value: 'createdAt' },
|
|
104
|
+
],
|
|
105
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
displayName: 'Sort Order',
|
|
109
|
+
name: 'sortOrder',
|
|
110
|
+
type: 'options',
|
|
111
|
+
default: 'desc',
|
|
112
|
+
options: [
|
|
113
|
+
{ name: 'Descending', value: 'desc' },
|
|
114
|
+
{ name: 'Ascending', value: 'asc' },
|
|
115
|
+
],
|
|
116
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
displayName: 'Page',
|
|
120
|
+
name: 'page',
|
|
121
|
+
type: 'number',
|
|
122
|
+
default: 1,
|
|
123
|
+
typeOptions: { minValue: 1 },
|
|
124
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
displayName: 'Return All',
|
|
128
|
+
name: 'returnAll',
|
|
129
|
+
type: 'boolean',
|
|
130
|
+
default: false,
|
|
131
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
displayName: 'Limit',
|
|
135
|
+
name: 'limit',
|
|
136
|
+
type: 'number',
|
|
137
|
+
default: 30,
|
|
138
|
+
typeOptions: { minValue: 1, maxValue: 100 },
|
|
139
|
+
displayOptions: { show: { operation: ['list'], returnAll: [false] } },
|
|
140
|
+
},
|
|
141
|
+
// --- Conversation ID (get / markRead / updateStatus / assign) ---
|
|
142
|
+
{
|
|
143
|
+
displayName: 'Conversation ID',
|
|
144
|
+
name: 'conversationId',
|
|
145
|
+
type: 'string',
|
|
146
|
+
default: '',
|
|
147
|
+
required: true,
|
|
148
|
+
displayOptions: { show: { operation: ['get', 'markRead', 'updateStatus', 'assign'] } },
|
|
149
|
+
},
|
|
150
|
+
// --- Update Status ---
|
|
151
|
+
{
|
|
152
|
+
displayName: 'Status',
|
|
153
|
+
name: 'newStatus',
|
|
154
|
+
type: 'options',
|
|
155
|
+
default: 'open',
|
|
156
|
+
options: [
|
|
157
|
+
{ name: 'Open', value: 'open' },
|
|
158
|
+
{ name: 'Resolved', value: 'resolved' },
|
|
159
|
+
{ name: 'Archived', value: 'archived' },
|
|
160
|
+
],
|
|
161
|
+
displayOptions: { show: { operation: ['updateStatus'] } },
|
|
162
|
+
},
|
|
163
|
+
// --- Assign ---
|
|
164
|
+
{
|
|
165
|
+
displayName: 'Assign To User ID',
|
|
166
|
+
name: 'assignToUserId',
|
|
167
|
+
type: 'string',
|
|
168
|
+
default: '',
|
|
169
|
+
displayOptions: { show: { operation: ['assign'] } },
|
|
170
|
+
description: 'User ID to assign to. Leave empty or pass "null" (string) to unassign.',
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
usableAsTool: true,
|
|
174
|
+
};
|
|
175
|
+
this.methods = {
|
|
176
|
+
loadOptions: {
|
|
177
|
+
async getAccounts() {
|
|
178
|
+
return await (0, http_1.loadAccountOptions)(this);
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
async execute() {
|
|
184
|
+
const items = this.getInputData();
|
|
185
|
+
const returnData = [];
|
|
186
|
+
const resolveAccountId = (i) => {
|
|
187
|
+
const v = this.getNodeParameter('accountId', i, '');
|
|
188
|
+
if (!v)
|
|
189
|
+
return undefined;
|
|
190
|
+
return typeof v === 'string' ? v : v?.value;
|
|
191
|
+
};
|
|
192
|
+
for (let i = 0; i < items.length; i++) {
|
|
193
|
+
const operation = this.getNodeParameter('operation', i);
|
|
194
|
+
if (operation === 'list') {
|
|
195
|
+
const qs = {};
|
|
196
|
+
const accountId = resolveAccountId(i);
|
|
197
|
+
if (accountId)
|
|
198
|
+
qs.accountId = accountId;
|
|
199
|
+
const status = this.getNodeParameter('status', i, '');
|
|
200
|
+
if (status)
|
|
201
|
+
qs.status = status;
|
|
202
|
+
const q = this.getNodeParameter('q', i, '').trim();
|
|
203
|
+
if (q)
|
|
204
|
+
qs.q = q;
|
|
205
|
+
qs.sortBy = this.getNodeParameter('sortBy', i);
|
|
206
|
+
qs.sortOrder = this.getNodeParameter('sortOrder', i);
|
|
207
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
208
|
+
const limit = this.getNodeParameter('limit', i) || 30;
|
|
209
|
+
qs.limit = returnAll ? 100 : limit;
|
|
210
|
+
qs.page = this.getNodeParameter('page', i);
|
|
211
|
+
const res = await (0, http_1.confirmxApiRequest)(this, {
|
|
212
|
+
method: 'GET',
|
|
213
|
+
endpoint: '/conversations',
|
|
214
|
+
qs,
|
|
215
|
+
});
|
|
216
|
+
const list = res.conversations || [];
|
|
217
|
+
const sliced = returnAll ? list : list.slice(0, limit);
|
|
218
|
+
returnData.push(...sliced.map((c) => ({ json: c })));
|
|
219
|
+
}
|
|
220
|
+
else if (operation === 'get') {
|
|
221
|
+
const id = this.getNodeParameter('conversationId', i);
|
|
222
|
+
const res = await (0, http_1.confirmxApiRequest)(this, {
|
|
223
|
+
method: 'GET',
|
|
224
|
+
endpoint: `/conversations/${id}`,
|
|
225
|
+
});
|
|
226
|
+
returnData.push({ json: res.conversation });
|
|
227
|
+
}
|
|
228
|
+
else if (operation === 'markRead') {
|
|
229
|
+
const id = this.getNodeParameter('conversationId', i);
|
|
230
|
+
const res = await (0, http_1.confirmxApiRequest)(this, {
|
|
231
|
+
method: 'POST',
|
|
232
|
+
endpoint: `/conversations/${id}/read`,
|
|
233
|
+
});
|
|
234
|
+
returnData.push({ json: { conversationId: id, ...res } });
|
|
235
|
+
}
|
|
236
|
+
else if (operation === 'updateStatus') {
|
|
237
|
+
const id = this.getNodeParameter('conversationId', i);
|
|
238
|
+
const status = this.getNodeParameter('newStatus', i);
|
|
239
|
+
const res = await (0, http_1.confirmxApiRequest)(this, {
|
|
240
|
+
method: 'PATCH',
|
|
241
|
+
endpoint: `/conversations/${id}/status`,
|
|
242
|
+
body: { status },
|
|
243
|
+
});
|
|
244
|
+
returnData.push({ json: res.conversation });
|
|
245
|
+
}
|
|
246
|
+
else if (operation === 'assign') {
|
|
247
|
+
const id = this.getNodeParameter('conversationId', i);
|
|
248
|
+
let raw = this.getNodeParameter('assignToUserId', i, '').trim();
|
|
249
|
+
let assignToUserId;
|
|
250
|
+
if (!raw || raw.toLowerCase() === 'null')
|
|
251
|
+
assignToUserId = null;
|
|
252
|
+
else
|
|
253
|
+
assignToUserId = raw;
|
|
254
|
+
const res = await (0, http_1.confirmxApiRequest)(this, {
|
|
255
|
+
method: 'PATCH',
|
|
256
|
+
endpoint: `/conversations/${id}/assign`,
|
|
257
|
+
body: { assignToUserId },
|
|
258
|
+
});
|
|
259
|
+
returnData.push({ json: res.conversation });
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return [returnData];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.ConfirmXConversation = ConfirmXConversation;
|
|
266
|
+
//# sourceMappingURL=ConfirmXConversation.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmXConversation.node.js","sourceRoot":"","sources":["ConfirmXConversation.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import type { INodeType, INodeTypeDescription } from 'n8n-workflow'
|
|
2
|
+
import { confirmxApiRequest, loadAccountOptions } from '../../transports/http'
|
|
3
|
+
|
|
4
|
+
export class ConfirmXConversation implements INodeType {
|
|
5
|
+
description: INodeTypeDescription = {
|
|
6
|
+
displayName: 'ConfirmX Conversation',
|
|
7
|
+
name: 'confirmXConversation',
|
|
8
|
+
icon: 'file:confirmx.svg',
|
|
9
|
+
group: ['transform'],
|
|
10
|
+
version: 1,
|
|
11
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
12
|
+
description:
|
|
13
|
+
'Read and manage WhatsApp conversations: list, view, mark read, change status, assign to a teammate.',
|
|
14
|
+
defaults: { name: 'ConfirmX Conversation' },
|
|
15
|
+
inputs: ['main'],
|
|
16
|
+
outputs: ['main'],
|
|
17
|
+
credentials: [{ name: 'confirmXApi', required: true }],
|
|
18
|
+
properties: [
|
|
19
|
+
{
|
|
20
|
+
displayName: 'Operation',
|
|
21
|
+
name: 'operation',
|
|
22
|
+
type: 'options',
|
|
23
|
+
noDataExpression: true,
|
|
24
|
+
options: [
|
|
25
|
+
{
|
|
26
|
+
name: 'List',
|
|
27
|
+
value: 'list',
|
|
28
|
+
action: 'List conversations',
|
|
29
|
+
description:
|
|
30
|
+
'List recent WhatsApp conversations for the org. Use to discover open conversations, find a conversation by contact phone or name, or check unread counts. Supports `status` filter (open/resolved/archived), free-text `q` search, and tag CSV. Returns up to 100 per page with `messages[0]` as the latest preview.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Get',
|
|
34
|
+
value: 'get',
|
|
35
|
+
action: 'Get conversation',
|
|
36
|
+
description:
|
|
37
|
+
'Fetch a single conversation by id. Use when you already have a `conversationId` (from a webhook, from List, or from an upstream node) and need the contact, account, and latest message. Requires `conversationId`.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Mark Read',
|
|
41
|
+
value: 'markRead',
|
|
42
|
+
action: 'Mark as read',
|
|
43
|
+
description:
|
|
44
|
+
'Zero the unread counter on a conversation. Use after a human or AI finishes handling the thread so the badge clears. Requires `conversationId`.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Update Status',
|
|
48
|
+
value: 'updateStatus',
|
|
49
|
+
action: 'Update status',
|
|
50
|
+
description:
|
|
51
|
+
'Set a conversation\'s status (`open`, `resolved`, `archived`). Use `resolved` when the issue is closed and `archived` to remove from default views. Requires `conversationId` and `status`.',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'Assign',
|
|
55
|
+
value: 'assign',
|
|
56
|
+
action: 'Assign to user',
|
|
57
|
+
description:
|
|
58
|
+
'Assign a conversation to a teammate by `assignToUserId` (or pass `null` to unassign). Requires `conversationId`. Returns the updated conversation with the `assignedTo` relation.',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
default: 'list',
|
|
62
|
+
},
|
|
63
|
+
// --- Account (optional for list, not needed for the others) ---
|
|
64
|
+
{
|
|
65
|
+
displayName: 'Account',
|
|
66
|
+
name: 'accountId',
|
|
67
|
+
type: 'resourceLocator',
|
|
68
|
+
default: { mode: 'list', value: '' },
|
|
69
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
70
|
+
modes: [
|
|
71
|
+
{ displayName: 'From List', name: 'list', type: 'list', typeOptions: { searchable: true } },
|
|
72
|
+
{ displayName: 'By ID', name: 'id', type: 'string' },
|
|
73
|
+
],
|
|
74
|
+
typeOptions: { loadOptionsMethod: 'getAccounts' },
|
|
75
|
+
description: 'Restrict list to one WhatsApp account (optional — leave empty for org-wide)',
|
|
76
|
+
},
|
|
77
|
+
// --- List filters ---
|
|
78
|
+
{
|
|
79
|
+
displayName: 'Status',
|
|
80
|
+
name: 'status',
|
|
81
|
+
type: 'options',
|
|
82
|
+
default: '',
|
|
83
|
+
options: [
|
|
84
|
+
{ name: 'All', value: '' },
|
|
85
|
+
{ name: 'Open', value: 'open' },
|
|
86
|
+
{ name: 'Resolved', value: 'resolved' },
|
|
87
|
+
{ name: 'Archived', value: 'archived' },
|
|
88
|
+
],
|
|
89
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
displayName: 'Search',
|
|
93
|
+
name: 'q',
|
|
94
|
+
type: 'string',
|
|
95
|
+
default: '',
|
|
96
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
97
|
+
description: 'Free-text search over contact phone + name + last message body',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
displayName: 'Sort By',
|
|
101
|
+
name: 'sortBy',
|
|
102
|
+
type: 'options',
|
|
103
|
+
default: 'lastMessageAt',
|
|
104
|
+
options: [
|
|
105
|
+
{ name: 'Last Message At', value: 'lastMessageAt' },
|
|
106
|
+
{ name: 'Unread Count', value: 'unreadCount' },
|
|
107
|
+
{ name: 'Created At', value: 'createdAt' },
|
|
108
|
+
],
|
|
109
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
displayName: 'Sort Order',
|
|
113
|
+
name: 'sortOrder',
|
|
114
|
+
type: 'options',
|
|
115
|
+
default: 'desc',
|
|
116
|
+
options: [
|
|
117
|
+
{ name: 'Descending', value: 'desc' },
|
|
118
|
+
{ name: 'Ascending', value: 'asc' },
|
|
119
|
+
],
|
|
120
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
displayName: 'Page',
|
|
124
|
+
name: 'page',
|
|
125
|
+
type: 'number',
|
|
126
|
+
default: 1,
|
|
127
|
+
typeOptions: { minValue: 1 },
|
|
128
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
displayName: 'Return All',
|
|
132
|
+
name: 'returnAll',
|
|
133
|
+
type: 'boolean',
|
|
134
|
+
default: false,
|
|
135
|
+
displayOptions: { show: { operation: ['list'] } },
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
displayName: 'Limit',
|
|
139
|
+
name: 'limit',
|
|
140
|
+
type: 'number',
|
|
141
|
+
default: 30,
|
|
142
|
+
typeOptions: { minValue: 1, maxValue: 100 },
|
|
143
|
+
displayOptions: { show: { operation: ['list'], returnAll: [false] } },
|
|
144
|
+
},
|
|
145
|
+
// --- Conversation ID (get / markRead / updateStatus / assign) ---
|
|
146
|
+
{
|
|
147
|
+
displayName: 'Conversation ID',
|
|
148
|
+
name: 'conversationId',
|
|
149
|
+
type: 'string',
|
|
150
|
+
default: '',
|
|
151
|
+
required: true,
|
|
152
|
+
displayOptions: { show: { operation: ['get', 'markRead', 'updateStatus', 'assign'] } },
|
|
153
|
+
},
|
|
154
|
+
// --- Update Status ---
|
|
155
|
+
{
|
|
156
|
+
displayName: 'Status',
|
|
157
|
+
name: 'newStatus',
|
|
158
|
+
type: 'options',
|
|
159
|
+
default: 'open',
|
|
160
|
+
options: [
|
|
161
|
+
{ name: 'Open', value: 'open' },
|
|
162
|
+
{ name: 'Resolved', value: 'resolved' },
|
|
163
|
+
{ name: 'Archived', value: 'archived' },
|
|
164
|
+
],
|
|
165
|
+
displayOptions: { show: { operation: ['updateStatus'] } },
|
|
166
|
+
},
|
|
167
|
+
// --- Assign ---
|
|
168
|
+
{
|
|
169
|
+
displayName: 'Assign To User ID',
|
|
170
|
+
name: 'assignToUserId',
|
|
171
|
+
type: 'string',
|
|
172
|
+
default: '',
|
|
173
|
+
displayOptions: { show: { operation: ['assign'] } },
|
|
174
|
+
description: 'User ID to assign to. Leave empty or pass "null" (string) to unassign.',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
usableAsTool: true,
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
methods = {
|
|
181
|
+
loadOptions: {
|
|
182
|
+
async getAccounts(this: any) {
|
|
183
|
+
return await loadAccountOptions(this)
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async execute(this: any) {
|
|
189
|
+
const items = this.getInputData()
|
|
190
|
+
const returnData: any[] = []
|
|
191
|
+
const resolveAccountId = (i: number) => {
|
|
192
|
+
const v = this.getNodeParameter('accountId', i, '') as any
|
|
193
|
+
if (!v) return undefined
|
|
194
|
+
return typeof v === 'string' ? v : v?.value
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
for (let i = 0; i < items.length; i++) {
|
|
198
|
+
const operation = this.getNodeParameter('operation', i) as string
|
|
199
|
+
|
|
200
|
+
if (operation === 'list') {
|
|
201
|
+
const qs: Record<string, any> = {}
|
|
202
|
+
const accountId = resolveAccountId(i)
|
|
203
|
+
if (accountId) qs.accountId = accountId
|
|
204
|
+
const status = this.getNodeParameter('status', i, '') as string
|
|
205
|
+
if (status) qs.status = status
|
|
206
|
+
const q = (this.getNodeParameter('q', i, '') as string).trim()
|
|
207
|
+
if (q) qs.q = q
|
|
208
|
+
qs.sortBy = this.getNodeParameter('sortBy', i) as string
|
|
209
|
+
qs.sortOrder = this.getNodeParameter('sortOrder', i) as string
|
|
210
|
+
const returnAll = this.getNodeParameter('returnAll', i) as boolean
|
|
211
|
+
const limit = (this.getNodeParameter('limit', i) as number) || 30
|
|
212
|
+
qs.limit = returnAll ? 100 : limit
|
|
213
|
+
qs.page = this.getNodeParameter('page', i) as number
|
|
214
|
+
|
|
215
|
+
const res = await confirmxApiRequest<{ conversations: any[] }>(this, {
|
|
216
|
+
method: 'GET',
|
|
217
|
+
endpoint: '/conversations',
|
|
218
|
+
qs,
|
|
219
|
+
})
|
|
220
|
+
const list = res.conversations || []
|
|
221
|
+
const sliced = returnAll ? list : list.slice(0, limit)
|
|
222
|
+
returnData.push(...sliced.map((c) => ({ json: c })))
|
|
223
|
+
} else if (operation === 'get') {
|
|
224
|
+
const id = this.getNodeParameter('conversationId', i) as string
|
|
225
|
+
const res = await confirmxApiRequest<{ conversation: any }>(this, {
|
|
226
|
+
method: 'GET',
|
|
227
|
+
endpoint: `/conversations/${id}`,
|
|
228
|
+
})
|
|
229
|
+
returnData.push({ json: res.conversation })
|
|
230
|
+
} else if (operation === 'markRead') {
|
|
231
|
+
const id = this.getNodeParameter('conversationId', i) as string
|
|
232
|
+
const res = await confirmxApiRequest<any>(this, {
|
|
233
|
+
method: 'POST',
|
|
234
|
+
endpoint: `/conversations/${id}/read`,
|
|
235
|
+
})
|
|
236
|
+
returnData.push({ json: { conversationId: id, ...res } })
|
|
237
|
+
} else if (operation === 'updateStatus') {
|
|
238
|
+
const id = this.getNodeParameter('conversationId', i) as string
|
|
239
|
+
const status = this.getNodeParameter('newStatus', i) as string
|
|
240
|
+
const res = await confirmxApiRequest<{ conversation: any }>(this, {
|
|
241
|
+
method: 'PATCH',
|
|
242
|
+
endpoint: `/conversations/${id}/status`,
|
|
243
|
+
body: { status },
|
|
244
|
+
})
|
|
245
|
+
returnData.push({ json: res.conversation })
|
|
246
|
+
} else if (operation === 'assign') {
|
|
247
|
+
const id = this.getNodeParameter('conversationId', i) as string
|
|
248
|
+
let raw = (this.getNodeParameter('assignToUserId', i, '') as string).trim()
|
|
249
|
+
let assignToUserId: string | null
|
|
250
|
+
if (!raw || raw.toLowerCase() === 'null') assignToUserId = null
|
|
251
|
+
else assignToUserId = raw
|
|
252
|
+
const res = await confirmxApiRequest<{ conversation: any }>(this, {
|
|
253
|
+
method: 'PATCH',
|
|
254
|
+
endpoint: `/conversations/${id}/assign`,
|
|
255
|
+
body: { assignToUserId },
|
|
256
|
+
})
|
|
257
|
+
returnData.push({ json: res.conversation })
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return [returnData]
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class ConfirmXMessage implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
methods: {
|
|
5
|
+
loadOptions: {
|
|
6
|
+
getAccounts(this: any): Promise<{
|
|
7
|
+
name: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}[]>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
execute(this: any): Promise<any[][]>;
|
|
13
|
+
}
|