@growsalesai/n8n-nodes-manychat 0.1.3 → 2.0.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.
@@ -3,6 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Manychat = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  const BASE_URL = 'https://api.manychat.com';
6
+ async function apiRequest(context, method, path, body, qs) {
7
+ const credentials = await context.getCredentials('manychatApi');
8
+ try {
9
+ return await context.helpers.httpRequest({
10
+ method,
11
+ url: `${BASE_URL}${path}`,
12
+ headers: {
13
+ Authorization: `Bearer ${credentials.apiToken}`,
14
+ 'Content-Type': 'application/json',
15
+ },
16
+ body,
17
+ qs,
18
+ json: true,
19
+ });
20
+ }
21
+ catch (error) {
22
+ throw new n8n_workflow_1.NodeApiError(context.getNode(), error);
23
+ }
24
+ }
6
25
  class Manychat {
7
26
  constructor() {
8
27
  this.description = {
@@ -10,22 +29,16 @@ class Manychat {
10
29
  name: 'manychat',
11
30
  icon: 'file:hero_manychat.png.svg',
12
31
  group: ['transform'],
13
- version: 1,
14
- subtitle: '={{$parameter["operation"] + " · " + $parameter["resource"]}}',
32
+ version: 2,
33
+ subtitle: '={{$parameter["resource"] + "." + $parameter["operation"]}}',
15
34
  description: 'Interact with ManyChat API to manage subscribers, send messages, and configure your page',
16
- defaults: {
17
- name: 'ManyChat',
18
- },
35
+ defaults: { name: 'ManyChat - Growsales AI' },
19
36
  inputs: ['main'],
20
37
  outputs: ['main'],
21
- credentials: [
22
- {
23
- name: 'manychatApi',
24
- required: true,
25
- },
26
- ],
38
+ usableAsTool: true,
39
+ credentials: [{ name: 'manychatApi', required: true }],
27
40
  properties: [
28
- // ─── RESOURCE ────────────────────────────────────────────────────────────
41
+ // ─── RESOURCE ──────────────────────────────────────────────────────
29
42
  {
30
43
  displayName: 'Resource',
31
44
  name: 'resource',
@@ -39,7 +52,7 @@ class Manychat {
39
52
  ],
40
53
  default: 'subscriber',
41
54
  },
42
- // ─── PAGE OPERATIONS ─────────────────────────────────────────────────────
55
+ // ─── PAGE OPERATIONS ───────────────────────────────────────────────
43
56
  {
44
57
  displayName: 'Operation',
45
58
  name: 'operation',
@@ -47,25 +60,25 @@ class Manychat {
47
60
  noDataExpression: true,
48
61
  displayOptions: { show: { resource: ['page'] } },
49
62
  options: [
50
- { name: 'Create Bot Field', value: 'createBotField', action: 'Create a bot field' },
51
- { name: 'Create Custom Field', value: 'createCustomField', action: 'Create a custom field' },
52
- { name: 'Create Tag', value: 'createTag', action: 'Create a tag' },
53
- { name: 'Get Bot Fields', value: 'getBotFields', action: 'Get all bot fields' },
54
- { name: 'Get Custom Fields', value: 'getCustomFields', action: 'Get all custom fields' },
55
- { name: 'Get Flows', value: 'getFlows', action: 'Get all flows' },
56
- { name: 'Get Growth Tools', value: 'getGrowthTools', action: 'Get all growth tools' },
57
- { name: 'Get Info', value: 'getInfo', action: 'Get page info' },
58
- { name: 'Get OTN Topics', value: 'getOtnTopics', action: 'Get OTN topics' },
59
- { name: 'Get Tags', value: 'getTags', action: 'Get all tags' },
60
- { name: 'Remove Tag', value: 'removeTag', action: 'Remove a tag by ID' },
61
- { name: 'Remove Tag By Name', value: 'removeTagByName', action: 'Remove a tag by name' },
62
- { name: 'Set Bot Field', value: 'setBotField', action: 'Set a bot field value by ID' },
63
- { name: 'Set Bot Field By Name', value: 'setBotFieldByName', action: 'Set a bot field value by name' },
64
- { name: 'Set Bot Fields', value: 'setBotFields', action: 'Set multiple bot fields at once' },
63
+ { name: 'createBotField', value: 'createBotField', action: 'Create a bot field' },
64
+ { name: 'createCustomField', value: 'createCustomField', action: 'Create a custom field' },
65
+ { name: 'createTag', value: 'createTag', action: 'Create a tag' },
66
+ { name: 'getBotFields', value: 'getBotFields', action: 'Get all bot fields' },
67
+ { name: 'getCustomFields', value: 'getCustomFields', action: 'Get all custom fields' },
68
+ { name: 'getFlows', value: 'getFlows', action: 'Get all flows' },
69
+ { name: 'getGrowthTools', value: 'getGrowthTools', action: 'Get all growth tools' },
70
+ { name: 'getInfo', value: 'getInfo', action: 'Get page info' },
71
+ { name: 'getOtnTopics', value: 'getOtnTopics', action: 'Get OTN topics' },
72
+ { name: 'getTags', value: 'getTags', action: 'Get all tags' },
73
+ { name: 'removeTag', value: 'removeTag', action: 'Remove a tag by ID' },
74
+ { name: 'removeTagByName', value: 'removeTagByName', action: 'Remove a tag by name' },
75
+ { name: 'setBotField', value: 'setBotField', action: 'Set a bot field by ID' },
76
+ { name: 'setBotFieldByName', value: 'setBotFieldByName', action: 'Set a bot field by name' },
77
+ { name: 'setBotFields', value: 'setBotFields', action: 'Set multiple bot fields at once' },
65
78
  ],
66
79
  default: 'getInfo',
67
80
  },
68
- // ─── SENDING OPERATIONS ──────────────────────────────────────────────────
81
+ // ─── SENDING OPERATIONS ────────────────────────────────────────────
69
82
  {
70
83
  displayName: 'Operation',
71
84
  name: 'operation',
@@ -73,13 +86,13 @@ class Manychat {
73
86
  noDataExpression: true,
74
87
  displayOptions: { show: { resource: ['sending'] } },
75
88
  options: [
76
- { name: 'Send Content', value: 'sendContent', action: 'Send content to a subscriber' },
77
- { name: 'Send Content By User Ref', value: 'sendContentByUserRef', action: 'Send content to a subscriber by user ref' },
78
- { name: 'Send Flow', value: 'sendFlow', action: 'Send a flow to a subscriber' },
89
+ { name: 'sendContent', value: 'sendContent', action: 'Send content to a subscriber' },
90
+ { name: 'sendContentByUserRef', value: 'sendContentByUserRef', action: 'Send content by user ref' },
91
+ { name: 'sendFlow', value: 'sendFlow', action: 'Send a flow to a subscriber' },
79
92
  ],
80
93
  default: 'sendFlow',
81
94
  },
82
- // ─── SUBSCRIBER OPERATIONS ───────────────────────────────────────────────
95
+ // ─── SUBSCRIBER OPERATIONS ─────────────────────────────────────────
83
96
  {
84
97
  displayName: 'Operation',
85
98
  name: 'operation',
@@ -87,25 +100,25 @@ class Manychat {
87
100
  noDataExpression: true,
88
101
  displayOptions: { show: { resource: ['subscriber'] } },
89
102
  options: [
90
- { name: 'Add Tag', value: 'addTag', action: 'Add a tag to a subscriber by tag ID' },
91
- { name: 'Add Tag By Name', value: 'addTagByName', action: 'Add a tag to a subscriber by tag name' },
92
- { name: 'Create Subscriber', value: 'createSubscriber', action: 'Create a new subscriber' },
93
- { name: 'Find By Custom Field', value: 'findByCustomField', action: 'Find subscribers by custom field' },
94
- { name: 'Find By Name', value: 'findByName', action: 'Find subscribers by name' },
95
- { name: 'Find By System Field', value: 'findBySystemField', action: 'Find a subscriber by email or phone' },
96
- { name: 'Get Info', value: 'getInfo', action: 'Get subscriber info by ID' },
97
- { name: 'Get Info By User Ref', value: 'getInfoByUserRef', action: 'Get subscriber info by user ref' },
98
- { name: 'Remove Tag', value: 'removeTag', action: 'Remove a tag from a subscriber by tag ID' },
99
- { name: 'Remove Tag By Name', value: 'removeTagByName', action: 'Remove a tag from a subscriber by tag name' },
100
- { name: 'Set Custom Field', value: 'setCustomField', action: 'Set a custom field value by field ID' },
101
- { name: 'Set Custom Field By Name', value: 'setCustomFieldByName', action: 'Set a custom field value by field name' },
102
- { name: 'Set Custom Fields', value: 'setCustomFields', action: 'Set multiple custom fields at once' },
103
- { name: 'Update Subscriber', value: 'updateSubscriber', action: 'Update subscriber data' },
104
- { name: 'Verify By Signed Request', value: 'verifyBySignedRequest', action: 'Verify a subscriber by signed request' },
103
+ { name: 'addTag', value: 'addTag', action: 'Add a tag to a subscriber by tag ID' },
104
+ { name: 'addTagByName', value: 'addTagByName', action: 'Add a tag to a subscriber by tag name' },
105
+ { name: 'createSubscriber', value: 'createSubscriber', action: 'Create a new subscriber' },
106
+ { name: 'findByCustomField', value: 'findByCustomField', action: 'Find subscribers by custom field' },
107
+ { name: 'findByName', value: 'findByName', action: 'Find subscribers by name' },
108
+ { name: 'findBySystemField', value: 'findBySystemField', action: 'Find a subscriber by email or phone' },
109
+ { name: 'getInfo', value: 'getInfo', action: 'Get subscriber info by ID' },
110
+ { name: 'getInfoByUserRef', value: 'getInfoByUserRef', action: 'Get subscriber info by user ref' },
111
+ { name: 'removeTag', value: 'removeTag', action: 'Remove a tag from subscriber by tag ID' },
112
+ { name: 'removeTagByName', value: 'removeTagByName', action: 'Remove a tag from subscriber by tag name' },
113
+ { name: 'setCustomField', value: 'setCustomField', action: 'Set a custom field by field ID' },
114
+ { name: 'setCustomFieldByName', value: 'setCustomFieldByName', action: 'Set a custom field by field name' },
115
+ { name: 'setCustomFields', value: 'setCustomFields', action: 'Set multiple custom fields at once' },
116
+ { name: 'updateSubscriber', value: 'updateSubscriber', action: 'Update subscriber data' },
117
+ { name: 'verifyBySignedRequest', value: 'verifyBySignedRequest', action: 'Verify subscriber by signed request' },
105
118
  ],
106
119
  default: 'getInfo',
107
120
  },
108
- // ─── TEMPLATE OPERATIONS ─────────────────────────────────────────────────
121
+ // ─── TEMPLATE OPERATIONS ───────────────────────────────────────────
109
122
  {
110
123
  displayName: 'Operation',
111
124
  name: 'operation',
@@ -113,39 +126,268 @@ class Manychat {
113
126
  noDataExpression: true,
114
127
  displayOptions: { show: { resource: ['template'] } },
115
128
  options: [
116
- { name: 'Generate Single Use Link', value: 'generateSingleUseLink', action: 'Generate a single-use installation link for a template' },
129
+ { name: 'generateSingleUseLink', value: 'generateSingleUseLink', action: 'Generate a single-use installation link' },
117
130
  ],
118
131
  default: 'generateSingleUseLink',
119
132
  },
120
- // ════════════════════════════════════════════════════════════════
121
- // PAGE PARAMETERS
122
- // ════════════════════════════════════════════════════════════════
123
- // page > createTag
133
+ // ══════════════════════════════════════════════════════════════════
134
+ // TAG SELECTION — by ID (addTag, removeTag in page + subscriber)
135
+ // ══════════════════════════════════════════════════════════════════
136
+ {
137
+ displayName: 'Tag',
138
+ name: 'tag_input_mode',
139
+ type: 'options',
140
+ options: [
141
+ { name: 'Select from List', value: 'list' },
142
+ { name: 'Enter ID Manually', value: 'id' },
143
+ ],
144
+ default: 'list',
145
+ displayOptions: { show: { operation: ['removeTag', 'addTag'] } },
146
+ },
147
+ {
148
+ displayName: 'Tag',
149
+ name: 'tag_id_list',
150
+ type: 'options',
151
+ typeOptions: { loadOptionsMethod: 'getTagsById' },
152
+ default: '',
153
+ description: 'Select a tag from the list',
154
+ displayOptions: { show: { operation: ['removeTag', 'addTag'], tag_input_mode: ['list'] } },
155
+ },
156
+ {
157
+ displayName: 'Tag ID',
158
+ name: 'tag_id',
159
+ type: 'number',
160
+ default: 0,
161
+ displayOptions: { show: { operation: ['removeTag', 'addTag'], tag_input_mode: ['id'] } },
162
+ },
163
+ // ══════════════════════════════════════════════════════════════════
164
+ // TAG SELECTION — by Name (addTagByName, removeTagByName)
165
+ // ══════════════════════════════════════════════════════════════════
166
+ {
167
+ displayName: 'Tag',
168
+ name: 'tag_name_mode',
169
+ type: 'options',
170
+ options: [
171
+ { name: 'Select from List', value: 'list' },
172
+ { name: 'Enter Name Manually', value: 'enter' },
173
+ ],
174
+ default: 'list',
175
+ displayOptions: { show: { operation: ['removeTagByName', 'addTagByName'] } },
176
+ },
177
+ {
178
+ displayName: 'Tag',
179
+ name: 'tag_name_list',
180
+ type: 'options',
181
+ typeOptions: { loadOptionsMethod: 'getTagsByName' },
182
+ default: '',
183
+ description: 'Select a tag from the list',
184
+ displayOptions: { show: { operation: ['removeTagByName', 'addTagByName'], tag_name_mode: ['list'] } },
185
+ },
124
186
  {
125
187
  displayName: 'Tag Name',
126
- name: 'name',
188
+ name: 'tag_name',
189
+ type: 'string',
190
+ default: '',
191
+ displayOptions: { show: { operation: ['removeTagByName', 'addTagByName'], tag_name_mode: ['enter'] } },
192
+ },
193
+ // ══════════════════════════════════════════════════════════════════
194
+ // FLOW SELECTION — sendFlow
195
+ // ══════════════════════════════════════════════════════════════════
196
+ {
197
+ displayName: 'Flow',
198
+ name: 'flow_mode',
199
+ type: 'options',
200
+ options: [
201
+ { name: 'Select from List', value: 'list' },
202
+ { name: 'Enter NS Manually', value: 'enter' },
203
+ ],
204
+ default: 'list',
205
+ displayOptions: { show: { operation: ['sendFlow'] } },
206
+ },
207
+ {
208
+ displayName: 'Flow',
209
+ name: 'flow_ns_list',
210
+ type: 'options',
211
+ typeOptions: { loadOptionsMethod: 'getFlowsList' },
212
+ default: '',
213
+ description: 'Select a flow from the list',
214
+ displayOptions: { show: { operation: ['sendFlow'], flow_mode: ['list'] } },
215
+ },
216
+ {
217
+ displayName: 'Flow NS',
218
+ name: 'flow_ns',
219
+ type: 'string',
220
+ default: '',
221
+ description: 'The flow namespace identifier (e.g. content20180221085508_278600)',
222
+ displayOptions: { show: { operation: ['sendFlow'], flow_mode: ['enter'] } },
223
+ },
224
+ // ══════════════════════════════════════════════════════════════════
225
+ // CUSTOM FIELD — by ID (subscriber: setCustomField, findByCustomField)
226
+ // ══════════════════════════════════════════════════════════════════
227
+ {
228
+ displayName: 'Custom Field',
229
+ name: 'custom_field_mode',
230
+ type: 'options',
231
+ options: [
232
+ { name: 'Select from List', value: 'list' },
233
+ { name: 'Enter ID Manually', value: 'id' },
234
+ ],
235
+ default: 'list',
236
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomField', 'findByCustomField'] } },
237
+ },
238
+ {
239
+ displayName: 'Custom Field',
240
+ name: 'custom_field_id_list',
241
+ type: 'options',
242
+ typeOptions: { loadOptionsMethod: 'getCustomFieldsById' },
243
+ default: '',
244
+ description: 'Select a custom field from the list',
245
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomField', 'findByCustomField'], custom_field_mode: ['list'] } },
246
+ },
247
+ {
248
+ displayName: 'Field ID',
249
+ name: 'field_id',
250
+ type: 'number',
251
+ default: 0,
252
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomField', 'findByCustomField'], custom_field_mode: ['id'] } },
253
+ },
254
+ // ══════════════════════════════════════════════════════════════════
255
+ // CUSTOM FIELD — by Name (subscriber: setCustomFieldByName)
256
+ // ══════════════════════════════════════════════════════════════════
257
+ {
258
+ displayName: 'Custom Field',
259
+ name: 'custom_field_name_mode',
260
+ type: 'options',
261
+ options: [
262
+ { name: 'Select from List', value: 'list' },
263
+ { name: 'Enter Name Manually', value: 'enter' },
264
+ ],
265
+ default: 'list',
266
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomFieldByName'] } },
267
+ },
268
+ {
269
+ displayName: 'Custom Field',
270
+ name: 'custom_field_name_list',
271
+ type: 'options',
272
+ typeOptions: { loadOptionsMethod: 'getCustomFieldsByName' },
273
+ default: '',
274
+ description: 'Select a custom field from the list',
275
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomFieldByName'], custom_field_name_mode: ['list'] } },
276
+ },
277
+ {
278
+ displayName: 'Field Name',
279
+ name: 'field_name',
280
+ type: 'string',
281
+ default: '',
282
+ description: 'Not case sensitive',
283
+ displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomFieldByName'], custom_field_name_mode: ['enter'] } },
284
+ },
285
+ // ══════════════════════════════════════════════════════════════════
286
+ // BOT FIELD — by ID (page: setBotField)
287
+ // ══════════════════════════════════════════════════════════════════
288
+ {
289
+ displayName: 'Bot Field',
290
+ name: 'bot_field_mode',
291
+ type: 'options',
292
+ options: [
293
+ { name: 'Select from List', value: 'list' },
294
+ { name: 'Enter ID Manually', value: 'id' },
295
+ ],
296
+ default: 'list',
297
+ displayOptions: { show: { resource: ['page'], operation: ['setBotField'] } },
298
+ },
299
+ {
300
+ displayName: 'Bot Field',
301
+ name: 'bot_field_id_list',
302
+ type: 'options',
303
+ typeOptions: { loadOptionsMethod: 'getBotFieldsById' },
304
+ default: '',
305
+ description: 'Select a bot field from the list',
306
+ displayOptions: { show: { resource: ['page'], operation: ['setBotField'], bot_field_mode: ['list'] } },
307
+ },
308
+ {
309
+ displayName: 'Field ID',
310
+ name: 'field_id',
311
+ type: 'number',
312
+ default: 0,
313
+ displayOptions: { show: { resource: ['page'], operation: ['setBotField'], bot_field_mode: ['id'] } },
314
+ },
315
+ // ══════════════════════════════════════════════════════════════════
316
+ // BOT FIELD — by Name (page: setBotFieldByName)
317
+ // ══════════════════════════════════════════════════════════════════
318
+ {
319
+ displayName: 'Bot Field',
320
+ name: 'bot_field_name_mode',
321
+ type: 'options',
322
+ options: [
323
+ { name: 'Select from List', value: 'list' },
324
+ { name: 'Enter Name Manually', value: 'enter' },
325
+ ],
326
+ default: 'list',
327
+ displayOptions: { show: { resource: ['page'], operation: ['setBotFieldByName'] } },
328
+ },
329
+ {
330
+ displayName: 'Bot Field',
331
+ name: 'bot_field_name_list',
332
+ type: 'options',
333
+ typeOptions: { loadOptionsMethod: 'getBotFieldsByName' },
334
+ default: '',
335
+ description: 'Select a bot field from the list',
336
+ displayOptions: { show: { resource: ['page'], operation: ['setBotFieldByName'], bot_field_name_mode: ['list'] } },
337
+ },
338
+ {
339
+ displayName: 'Field Name',
340
+ name: 'field_name',
341
+ type: 'string',
342
+ default: '',
343
+ displayOptions: { show: { resource: ['page'], operation: ['setBotFieldByName'], bot_field_name_mode: ['enter'] } },
344
+ },
345
+ // ══════════════════════════════════════════════════════════════════
346
+ // FIELD VALUE (shared for setBotField, setBotFieldByName, setCustomField, setCustomFieldByName)
347
+ // ══════════════════════════════════════════════════════════════════
348
+ {
349
+ displayName: 'Field Value',
350
+ name: 'field_value',
127
351
  type: 'string',
128
352
  required: true,
129
353
  default: '',
130
- displayOptions: { show: { resource: ['page'], operation: ['createTag'] } },
354
+ displayOptions: { show: { operation: ['setBotField', 'setBotFieldByName', 'setCustomField', 'setCustomFieldByName'] } },
131
355
  },
132
- // page > removeTag
356
+ // ══════════════════════════════════════════════════════════════════
357
+ // SUBSCRIBER ID — shared across operations
358
+ // ══════════════════════════════════════════════════════════════════
133
359
  {
134
- displayName: 'Tag ID',
135
- name: 'tag_id',
360
+ displayName: 'Subscriber ID',
361
+ name: 'subscriber_id',
362
+ type: 'number',
363
+ required: true,
364
+ default: 0,
365
+ displayOptions: {
366
+ show: {
367
+ resource: ['subscriber'],
368
+ operation: ['getInfo', 'addTag', 'addTagByName', 'removeTag', 'removeTagByName', 'setCustomField', 'setCustomFieldByName', 'setCustomFields', 'updateSubscriber', 'verifyBySignedRequest'],
369
+ },
370
+ },
371
+ },
372
+ {
373
+ displayName: 'Subscriber ID',
374
+ name: 'subscriber_id',
136
375
  type: 'number',
137
376
  required: true,
138
377
  default: 0,
139
- displayOptions: { show: { resource: ['page'], operation: ['removeTag'] } },
378
+ displayOptions: { show: { resource: ['sending'], operation: ['sendFlow', 'sendContent'] } },
140
379
  },
141
- // page > removeTagByName
380
+ // ══════════════════════════════════════════════════════════════════
381
+ // PAGE PARAMETERS
382
+ // ══════════════════════════════════════════════════════════════════
383
+ // page > createTag
142
384
  {
143
385
  displayName: 'Tag Name',
144
- name: 'tag_name',
386
+ name: 'name',
145
387
  type: 'string',
146
388
  required: true,
147
389
  default: '',
148
- displayOptions: { show: { resource: ['page'], operation: ['removeTagByName'] } },
390
+ displayOptions: { show: { resource: ['page'], operation: ['createTag'] } },
149
391
  },
150
392
  // page > createCustomField
151
393
  {
@@ -156,18 +398,17 @@ class Manychat {
156
398
  default: '',
157
399
  displayOptions: { show: { resource: ['page'], operation: ['createCustomField'] } },
158
400
  },
159
- // page > createCustomField + createBotField
160
401
  {
161
402
  displayName: 'Type',
162
403
  name: 'type',
163
404
  type: 'options',
164
405
  required: true,
165
406
  options: [
166
- { name: 'Boolean', value: 'boolean' },
167
- { name: 'Date', value: 'date' },
168
- { name: 'Datetime', value: 'datetime' },
169
- { name: 'Number', value: 'number' },
170
- { name: 'Text', value: 'text' },
407
+ { name: 'boolean', value: 'boolean' },
408
+ { name: 'date', value: 'date' },
409
+ { name: 'datetime', value: 'datetime' },
410
+ { name: 'number', value: 'number' },
411
+ { name: 'text', value: 'text' },
171
412
  ],
172
413
  default: 'text',
173
414
  displayOptions: { show: { resource: ['page'], operation: ['createCustomField', 'createBotField'] } },
@@ -195,32 +436,6 @@ class Manychat {
195
436
  default: '',
196
437
  displayOptions: { show: { resource: ['page'], operation: ['createBotField'] } },
197
438
  },
198
- // page > setBotField
199
- {
200
- displayName: 'Field ID',
201
- name: 'field_id',
202
- type: 'number',
203
- required: true,
204
- default: 0,
205
- displayOptions: { show: { resource: ['page'], operation: ['setBotField'] } },
206
- },
207
- {
208
- displayName: 'Field Value',
209
- name: 'field_value',
210
- type: 'string',
211
- required: true,
212
- default: '',
213
- displayOptions: { show: { resource: ['page'], operation: ['setBotField', 'setBotFieldByName'] } },
214
- },
215
- // page > setBotFieldByName
216
- {
217
- displayName: 'Field Name',
218
- name: 'field_name',
219
- type: 'string',
220
- required: true,
221
- default: '',
222
- displayOptions: { show: { resource: ['page'], operation: ['setBotFieldByName'] } },
223
- },
224
439
  // page > setBotFields
225
440
  {
226
441
  displayName: 'Fields (JSON)',
@@ -231,18 +446,9 @@ class Manychat {
231
446
  description: 'Array of objects with field_id and field_value',
232
447
  displayOptions: { show: { resource: ['page'], operation: ['setBotFields'] } },
233
448
  },
234
- // ════════════════════════════════════════════════════════════════
449
+ // ══════════════════════════════════════════════════════════════════
235
450
  // SENDING PARAMETERS
236
- // ════════════════════════════════════════════════════════════════
237
- // sending > sendFlow + sendContent
238
- {
239
- displayName: 'Subscriber ID',
240
- name: 'subscriber_id',
241
- type: 'number',
242
- required: true,
243
- default: 0,
244
- displayOptions: { show: { resource: ['sending'], operation: ['sendFlow', 'sendContent'] } },
245
- },
451
+ // ══════════════════════════════════════════════════════════════════
246
452
  // sending > sendContentByUserRef
247
453
  {
248
454
  displayName: 'User Ref',
@@ -252,17 +458,6 @@ class Manychat {
252
458
  default: 0,
253
459
  displayOptions: { show: { resource: ['sending'], operation: ['sendContentByUserRef'] } },
254
460
  },
255
- // sending > sendFlow
256
- {
257
- displayName: 'Flow NS',
258
- name: 'flow_ns',
259
- type: 'string',
260
- required: true,
261
- default: '',
262
- description: 'The flow namespace identifier (e.g. content20180221085508_278600)',
263
- displayOptions: { show: { resource: ['sending'], operation: ['sendFlow'] } },
264
- },
265
- // sending > sendContent + sendContentByUserRef
266
461
  {
267
462
  displayName: 'Content Data (JSON)',
268
463
  name: 'data',
@@ -272,17 +467,16 @@ class Manychat {
272
467
  description: 'The content object as JSON. See ManyChat API docs for the full schema.',
273
468
  displayOptions: { show: { resource: ['sending'], operation: ['sendContent', 'sendContentByUserRef'] } },
274
469
  },
275
- // sending > sendContent
276
470
  {
277
471
  displayName: 'Message Tag',
278
472
  name: 'message_tag',
279
473
  type: 'options',
280
474
  options: [
281
475
  { name: '(None)', value: '' },
282
- { name: 'Account Update', value: 'ACCOUNT_UPDATE' },
283
- { name: 'Confirmed Event Update', value: 'CONFIRMED_EVENT_UPDATE' },
284
- { name: 'Customer Feedback', value: 'CUSTOMER_FEEDBACK' },
285
- { name: 'Post Purchase Update', value: 'POST_PURCHASE_UPDATE' },
476
+ { name: 'ACCOUNT_UPDATE', value: 'ACCOUNT_UPDATE' },
477
+ { name: 'CONFIRMED_EVENT_UPDATE', value: 'CONFIRMED_EVENT_UPDATE' },
478
+ { name: 'CUSTOMER_FEEDBACK', value: 'CUSTOMER_FEEDBACK' },
479
+ { name: 'POST_PURCHASE_UPDATE', value: 'POST_PURCHASE_UPDATE' },
286
480
  ],
287
481
  default: '',
288
482
  displayOptions: { show: { resource: ['sending'], operation: ['sendContent'] } },
@@ -294,22 +488,9 @@ class Manychat {
294
488
  default: '',
295
489
  displayOptions: { show: { resource: ['sending'], operation: ['sendContent'] } },
296
490
  },
297
- // ════════════════════════════════════════════════════════════════
491
+ // ══════════════════════════════════════════════════════════════════
298
492
  // SUBSCRIBER PARAMETERS
299
- // ════════════════════════════════════════════════════════════════
300
- {
301
- displayName: 'Subscriber ID',
302
- name: 'subscriber_id',
303
- type: 'number',
304
- required: true,
305
- default: 0,
306
- displayOptions: {
307
- show: {
308
- resource: ['subscriber'],
309
- operation: ['getInfo', 'addTag', 'addTagByName', 'removeTag', 'removeTagByName', 'setCustomField', 'setCustomFieldByName', 'setCustomFields', 'updateSubscriber', 'verifyBySignedRequest'],
310
- },
311
- },
312
- },
493
+ // ══════════════════════════════════════════════════════════════════
313
494
  // subscriber > getInfoByUserRef
314
495
  {
315
496
  displayName: 'User Ref',
@@ -328,22 +509,14 @@ class Manychat {
328
509
  default: '',
329
510
  displayOptions: { show: { resource: ['subscriber'], operation: ['findByName'] } },
330
511
  },
331
- // subscriber > findByCustomField
332
- {
333
- displayName: 'Field ID',
334
- name: 'field_id',
335
- type: 'number',
336
- required: true,
337
- default: 0,
338
- displayOptions: { show: { resource: ['subscriber'], operation: ['findByCustomField'] } },
339
- },
512
+ // subscriber > findByCustomField — field value
340
513
  {
341
514
  displayName: 'Field Value',
342
- name: 'field_value',
515
+ name: 'find_field_value',
343
516
  type: 'string',
344
517
  required: true,
345
518
  default: '',
346
- displayOptions: { show: { resource: ['subscriber'], operation: ['findByCustomField', 'setCustomField'] } },
519
+ displayOptions: { show: { resource: ['subscriber'], operation: ['findByCustomField'] } },
347
520
  },
348
521
  // subscriber > findBySystemField
349
522
  {
@@ -361,50 +534,6 @@ class Manychat {
361
534
  default: '',
362
535
  displayOptions: { show: { resource: ['subscriber'], operation: ['findBySystemField'] } },
363
536
  },
364
- // subscriber > addTag / removeTag
365
- {
366
- displayName: 'Tag ID',
367
- name: 'tag_id',
368
- type: 'number',
369
- required: true,
370
- default: 0,
371
- displayOptions: { show: { resource: ['subscriber'], operation: ['addTag', 'removeTag'] } },
372
- },
373
- {
374
- displayName: 'Tag Name',
375
- name: 'tag_name',
376
- type: 'string',
377
- required: true,
378
- default: '',
379
- displayOptions: { show: { resource: ['subscriber'], operation: ['addTagByName', 'removeTagByName'] } },
380
- },
381
- // subscriber > setCustomField
382
- {
383
- displayName: 'Field ID',
384
- name: 'field_id',
385
- type: 'number',
386
- required: true,
387
- default: 0,
388
- displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomField'] } },
389
- },
390
- // subscriber > setCustomFieldByName
391
- {
392
- displayName: 'Field Name',
393
- name: 'field_name',
394
- type: 'string',
395
- required: true,
396
- default: '',
397
- description: 'Not case sensitive',
398
- displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomFieldByName'] } },
399
- },
400
- {
401
- displayName: 'Field Value',
402
- name: 'field_value',
403
- type: 'string',
404
- required: true,
405
- default: '',
406
- displayOptions: { show: { resource: ['subscriber'], operation: ['setCustomFieldByName'] } },
407
- },
408
537
  // subscriber > setCustomFields
409
538
  {
410
539
  displayName: 'Fields (JSON)',
@@ -470,8 +599,8 @@ class Manychat {
470
599
  type: 'options',
471
600
  options: [
472
601
  { name: '(Not Set)', value: '' },
473
- { name: 'Female', value: 'female' },
474
- { name: 'Male', value: 'male' },
602
+ { name: 'female', value: 'female' },
603
+ { name: 'male', value: 'male' },
475
604
  ],
476
605
  default: '',
477
606
  displayOptions: { show: { resource: ['subscriber'], operation: ['createSubscriber', 'updateSubscriber'] } },
@@ -481,7 +610,7 @@ class Manychat {
481
610
  name: 'has_opt_in_sms',
482
611
  type: 'boolean',
483
612
  default: false,
484
- description: 'Whether the subscriber has opted in to SMS. Required when phone is provided.',
613
+ description: 'Whether Required when phone is provided',
485
614
  displayOptions: { show: { resource: ['subscriber'], operation: ['createSubscriber', 'updateSubscriber'] } },
486
615
  },
487
616
  {
@@ -489,7 +618,7 @@ class Manychat {
489
618
  name: 'has_opt_in_email',
490
619
  type: 'boolean',
491
620
  default: false,
492
- description: 'Whether the subscriber has opted in to email. Required when email is provided.',
621
+ description: 'Whether Required when email is provided',
493
622
  displayOptions: { show: { resource: ['subscriber'], operation: ['createSubscriber', 'updateSubscriber'] } },
494
623
  },
495
624
  {
@@ -500,9 +629,9 @@ class Manychat {
500
629
  description: 'Required when Has Opt-In SMS is true',
501
630
  displayOptions: { show: { resource: ['subscriber'], operation: ['createSubscriber', 'updateSubscriber'] } },
502
631
  },
503
- // ════════════════════════════════════════════════════════════════
632
+ // ══════════════════════════════════════════════════════════════════
504
633
  // TEMPLATE PARAMETERS
505
- // ════════════════════════════════════════════════════════════════
634
+ // ══════════════════════════════════════════════════════════════════
506
635
  {
507
636
  displayName: 'Template ID',
508
637
  name: 'template_id',
@@ -513,69 +642,147 @@ class Manychat {
513
642
  },
514
643
  ],
515
644
  };
645
+ // ── LOAD OPTIONS ─────────────────────────────────────────────────────────
646
+ this.methods = {
647
+ loadOptions: {
648
+ async getTagsById() {
649
+ var _a;
650
+ const response = await apiRequest(this, 'GET', '/fb/page/getTags');
651
+ const tags = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
652
+ return tags.map((t) => ({ name: t.name, value: t.id }));
653
+ },
654
+ async getTagsByName() {
655
+ var _a;
656
+ const response = await apiRequest(this, 'GET', '/fb/page/getTags');
657
+ const tags = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
658
+ return tags.map((t) => ({ name: t.name, value: t.name }));
659
+ },
660
+ async getFlowsList() {
661
+ var _a, _b, _c;
662
+ const response = await apiRequest(this, 'GET', '/fb/page/getFlows');
663
+ const flows = ((_c = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.flows) !== null && _b !== void 0 ? _b : response.data) !== null && _c !== void 0 ? _c : []);
664
+ return flows.map((f) => ({ name: f.name, value: f.ns }));
665
+ },
666
+ async getCustomFieldsById() {
667
+ var _a;
668
+ const response = await apiRequest(this, 'GET', '/fb/page/getCustomFields');
669
+ const fields = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
670
+ return fields.map((f) => ({ name: `${f.name} [${f.type}]`, value: f.id }));
671
+ },
672
+ async getCustomFieldsByName() {
673
+ var _a;
674
+ const response = await apiRequest(this, 'GET', '/fb/page/getCustomFields');
675
+ const fields = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
676
+ return fields.map((f) => ({ name: `${f.name} [${f.type}]`, value: f.name }));
677
+ },
678
+ async getBotFieldsById() {
679
+ var _a;
680
+ const response = await apiRequest(this, 'GET', '/fb/page/getBotFields');
681
+ const fields = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
682
+ return fields.map((f) => ({ name: `${f.name} [${f.type}]`, value: f.id }));
683
+ },
684
+ async getBotFieldsByName() {
685
+ var _a;
686
+ const response = await apiRequest(this, 'GET', '/fb/page/getBotFields');
687
+ const fields = ((_a = response.data) !== null && _a !== void 0 ? _a : []);
688
+ return fields.map((f) => ({ name: `${f.name} [${f.type}]`, value: f.name }));
689
+ },
690
+ },
691
+ };
516
692
  }
693
+ // ── EXECUTE ──────────────────────────────────────────────────────────────
517
694
  async execute() {
518
695
  const items = this.getInputData();
519
696
  const returnData = [];
520
- const credentials = await this.getCredentials('manychatApi');
521
- const token = credentials.apiToken;
522
- const makeRequest = async (method, path, body, qs) => {
523
- try {
524
- return await this.helpers.httpRequest({
525
- method,
526
- url: `${BASE_URL}${path}`,
527
- headers: {
528
- Authorization: `Bearer ${token}`,
529
- 'Content-Type': 'application/json',
530
- },
531
- body,
532
- qs,
533
- json: true,
534
- });
535
- }
536
- catch (error) {
537
- throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
538
- }
697
+ const request = async (method, path, body, qs) => apiRequest(this, method, path, body, qs);
698
+ // Helper: resolve tag ID (from list or manual)
699
+ const resolveTagId = (i) => {
700
+ const mode = this.getNodeParameter('tag_input_mode', i, 'list');
701
+ return mode === 'list'
702
+ ? this.getNodeParameter('tag_id_list', i)
703
+ : this.getNodeParameter('tag_id', i);
704
+ };
705
+ // Helper: resolve tag name (from list or manual)
706
+ const resolveTagName = (i) => {
707
+ const mode = this.getNodeParameter('tag_name_mode', i, 'list');
708
+ return mode === 'list'
709
+ ? this.getNodeParameter('tag_name_list', i)
710
+ : this.getNodeParameter('tag_name', i);
711
+ };
712
+ // Helper: resolve flow NS (from list or manual)
713
+ const resolveFlowNs = (i) => {
714
+ const mode = this.getNodeParameter('flow_mode', i, 'list');
715
+ return mode === 'list'
716
+ ? this.getNodeParameter('flow_ns_list', i)
717
+ : this.getNodeParameter('flow_ns', i);
718
+ };
719
+ // Helper: resolve custom field ID (from list or manual)
720
+ const resolveCustomFieldId = (i) => {
721
+ const mode = this.getNodeParameter('custom_field_mode', i, 'list');
722
+ return mode === 'list'
723
+ ? this.getNodeParameter('custom_field_id_list', i)
724
+ : this.getNodeParameter('field_id', i);
725
+ };
726
+ // Helper: resolve custom field name (from list or manual)
727
+ const resolveCustomFieldName = (i) => {
728
+ const mode = this.getNodeParameter('custom_field_name_mode', i, 'list');
729
+ return mode === 'list'
730
+ ? this.getNodeParameter('custom_field_name_list', i)
731
+ : this.getNodeParameter('field_name', i);
732
+ };
733
+ // Helper: resolve bot field ID (from list or manual)
734
+ const resolveBotFieldId = (i) => {
735
+ const mode = this.getNodeParameter('bot_field_mode', i, 'list');
736
+ return mode === 'list'
737
+ ? this.getNodeParameter('bot_field_id_list', i)
738
+ : this.getNodeParameter('field_id', i);
739
+ };
740
+ // Helper: resolve bot field name (from list or manual)
741
+ const resolveBotFieldName = (i) => {
742
+ const mode = this.getNodeParameter('bot_field_name_mode', i, 'list');
743
+ return mode === 'list'
744
+ ? this.getNodeParameter('bot_field_name_list', i)
745
+ : this.getNodeParameter('field_name', i);
539
746
  };
540
747
  for (let i = 0; i < items.length; i++) {
541
748
  try {
542
749
  const resource = this.getNodeParameter('resource', i);
543
750
  const operation = this.getNodeParameter('operation', i);
544
751
  let responseData;
545
- // ── PAGE ──────────────────────────────────────────────────────────────
752
+ // ── PAGE ────────────────────────────────────────────────────
546
753
  if (resource === 'page') {
547
754
  if (operation === 'getInfo') {
548
- responseData = await makeRequest('GET', '/fb/page/getInfo');
755
+ responseData = await request('GET', '/fb/page/getInfo');
549
756
  }
550
757
  else if (operation === 'getTags') {
551
- responseData = await makeRequest('GET', '/fb/page/getTags');
758
+ responseData = await request('GET', '/fb/page/getTags');
552
759
  }
553
760
  else if (operation === 'getCustomFields') {
554
- responseData = await makeRequest('GET', '/fb/page/getCustomFields');
761
+ responseData = await request('GET', '/fb/page/getCustomFields');
555
762
  }
556
763
  else if (operation === 'getGrowthTools') {
557
- responseData = await makeRequest('GET', '/fb/page/getGrowthTools');
764
+ responseData = await request('GET', '/fb/page/getGrowthTools');
558
765
  }
559
766
  else if (operation === 'getFlows') {
560
- responseData = await makeRequest('GET', '/fb/page/getFlows');
767
+ responseData = await request('GET', '/fb/page/getFlows');
561
768
  }
562
769
  else if (operation === 'getOtnTopics') {
563
- responseData = await makeRequest('GET', '/fb/page/getOtnTopics');
770
+ responseData = await request('GET', '/fb/page/getOtnTopics');
564
771
  }
565
772
  else if (operation === 'getBotFields') {
566
- responseData = await makeRequest('GET', '/fb/page/getBotFields');
773
+ responseData = await request('GET', '/fb/page/getBotFields');
567
774
  }
568
775
  else if (operation === 'createTag') {
569
776
  const name = this.getNodeParameter('name', i);
570
- responseData = await makeRequest('POST', '/fb/page/createTag', { name });
777
+ responseData = await request('POST', '/fb/page/createTag', { name });
571
778
  }
572
779
  else if (operation === 'removeTag') {
573
- const tag_id = this.getNodeParameter('tag_id', i);
574
- responseData = await makeRequest('POST', '/fb/page/removeTag', { tag_id });
780
+ const tag_id = resolveTagId(i);
781
+ responseData = await request('POST', '/fb/page/removeTag', { tag_id });
575
782
  }
576
783
  else if (operation === 'removeTagByName') {
577
- const tag_name = this.getNodeParameter('tag_name', i);
578
- responseData = await makeRequest('POST', '/fb/page/removeTagByName', { tag_name });
784
+ const tag_name = resolveTagName(i);
785
+ responseData = await request('POST', '/fb/page/removeTagByName', { tag_name });
579
786
  }
580
787
  else if (operation === 'createCustomField') {
581
788
  const caption = this.getNodeParameter('caption', i);
@@ -584,7 +791,7 @@ class Manychat {
584
791
  const body = { caption, type };
585
792
  if (description)
586
793
  body.description = description;
587
- responseData = await makeRequest('POST', '/fb/page/createCustomField', body);
794
+ responseData = await request('POST', '/fb/page/createCustomField', body);
588
795
  }
589
796
  else if (operation === 'createBotField') {
590
797
  const name = this.getNodeParameter('name', i);
@@ -596,33 +803,33 @@ class Manychat {
596
803
  body.description = description;
597
804
  if (value)
598
805
  body.value = value;
599
- responseData = await makeRequest('POST', '/fb/page/createBotField', body);
806
+ responseData = await request('POST', '/fb/page/createBotField', body);
600
807
  }
601
808
  else if (operation === 'setBotField') {
602
- const field_id = this.getNodeParameter('field_id', i);
809
+ const field_id = resolveBotFieldId(i);
603
810
  const field_value = this.getNodeParameter('field_value', i);
604
- responseData = await makeRequest('POST', '/fb/page/setBotField', { field_id, field_value });
811
+ responseData = await request('POST', '/fb/page/setBotField', { field_id, field_value });
605
812
  }
606
813
  else if (operation === 'setBotFieldByName') {
607
- const field_name = this.getNodeParameter('field_name', i);
814
+ const field_name = resolveBotFieldName(i);
608
815
  const field_value = this.getNodeParameter('field_value', i);
609
- responseData = await makeRequest('POST', '/fb/page/setBotFieldByName', { field_name, field_value });
816
+ responseData = await request('POST', '/fb/page/setBotFieldByName', { field_name, field_value });
610
817
  }
611
818
  else if (operation === 'setBotFields') {
612
819
  const fieldsRaw = this.getNodeParameter('fields', i);
613
820
  const fields = typeof fieldsRaw === 'string' ? JSON.parse(fieldsRaw) : fieldsRaw;
614
- responseData = await makeRequest('POST', '/fb/page/setBotFields', { fields });
821
+ responseData = await request('POST', '/fb/page/setBotFields', { fields });
615
822
  }
616
823
  else {
617
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown page operation: ${operation}`, { itemIndex: i });
824
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
618
825
  }
619
- // ── SENDING ───────────────────────────────────────────────────────────
826
+ // ── SENDING ─────────────────────────────────────────────────
620
827
  }
621
828
  else if (resource === 'sending') {
622
829
  if (operation === 'sendFlow') {
623
830
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
624
- const flow_ns = this.getNodeParameter('flow_ns', i);
625
- responseData = await makeRequest('POST', '/fb/sending/sendFlow', { subscriber_id, flow_ns });
831
+ const flow_ns = resolveFlowNs(i);
832
+ responseData = await request('POST', '/fb/sending/sendFlow', { subscriber_id, flow_ns });
626
833
  }
627
834
  else if (operation === 'sendContent') {
628
835
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
@@ -635,36 +842,36 @@ class Manychat {
635
842
  body.message_tag = message_tag;
636
843
  if (otn_topic_name)
637
844
  body.otn_topic_name = otn_topic_name;
638
- responseData = await makeRequest('POST', '/fb/sending/sendContent', body);
845
+ responseData = await request('POST', '/fb/sending/sendContent', body);
639
846
  }
640
847
  else if (operation === 'sendContentByUserRef') {
641
848
  const user_ref = this.getNodeParameter('user_ref', i);
642
849
  const dataRaw = this.getNodeParameter('data', i);
643
850
  const data = typeof dataRaw === 'string' ? JSON.parse(dataRaw) : dataRaw;
644
- responseData = await makeRequest('POST', '/fb/sending/sendContentByUserRef', { user_ref, data });
851
+ responseData = await request('POST', '/fb/sending/sendContentByUserRef', { user_ref, data });
645
852
  }
646
853
  else {
647
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown sending operation: ${operation}`, { itemIndex: i });
854
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
648
855
  }
649
- // ── SUBSCRIBER ────────────────────────────────────────────────────────
856
+ // ── SUBSCRIBER ───────────────────────────────────────────────
650
857
  }
651
858
  else if (resource === 'subscriber') {
652
859
  if (operation === 'getInfo') {
653
860
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
654
- responseData = await makeRequest('GET', '/fb/subscriber/getInfo', undefined, { subscriber_id });
861
+ responseData = await request('GET', '/fb/subscriber/getInfo', undefined, { subscriber_id });
655
862
  }
656
863
  else if (operation === 'getInfoByUserRef') {
657
864
  const user_ref = this.getNodeParameter('user_ref', i);
658
- responseData = await makeRequest('GET', '/fb/subscriber/getInfoByUserRef', undefined, { user_ref });
865
+ responseData = await request('GET', '/fb/subscriber/getInfoByUserRef', undefined, { user_ref });
659
866
  }
660
867
  else if (operation === 'findByName') {
661
868
  const name = this.getNodeParameter('name', i);
662
- responseData = await makeRequest('GET', '/fb/subscriber/findByName', undefined, { name });
869
+ responseData = await request('GET', '/fb/subscriber/findByName', undefined, { name });
663
870
  }
664
871
  else if (operation === 'findByCustomField') {
665
- const field_id = this.getNodeParameter('field_id', i);
666
- const field_value = this.getNodeParameter('field_value', i);
667
- responseData = await makeRequest('GET', '/fb/subscriber/findByCustomField', undefined, { field_id, field_value });
872
+ const field_id = resolveCustomFieldId(i);
873
+ const field_value = this.getNodeParameter('find_field_value', i);
874
+ responseData = await request('GET', '/fb/subscriber/findByCustomField', undefined, { field_id, field_value });
668
875
  }
669
876
  else if (operation === 'findBySystemField') {
670
877
  const email = this.getNodeParameter('email', i);
@@ -677,50 +884,50 @@ class Manychat {
677
884
  qs.email = email;
678
885
  if (phone)
679
886
  qs.phone = phone;
680
- responseData = await makeRequest('GET', '/fb/subscriber/findBySystemField', undefined, qs);
887
+ responseData = await request('GET', '/fb/subscriber/findBySystemField', undefined, qs);
681
888
  }
682
889
  else if (operation === 'addTag') {
683
890
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
684
- const tag_id = this.getNodeParameter('tag_id', i);
685
- responseData = await makeRequest('POST', '/fb/subscriber/addTag', { subscriber_id, tag_id });
891
+ const tag_id = resolveTagId(i);
892
+ responseData = await request('POST', '/fb/subscriber/addTag', { subscriber_id, tag_id });
686
893
  }
687
894
  else if (operation === 'addTagByName') {
688
895
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
689
- const tag_name = this.getNodeParameter('tag_name', i);
690
- responseData = await makeRequest('POST', '/fb/subscriber/addTagByName', { subscriber_id, tag_name });
896
+ const tag_name = resolveTagName(i);
897
+ responseData = await request('POST', '/fb/subscriber/addTagByName', { subscriber_id, tag_name });
691
898
  }
692
899
  else if (operation === 'removeTag') {
693
900
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
694
- const tag_id = this.getNodeParameter('tag_id', i);
695
- responseData = await makeRequest('POST', '/fb/subscriber/removeTag', { subscriber_id, tag_id });
901
+ const tag_id = resolveTagId(i);
902
+ responseData = await request('POST', '/fb/subscriber/removeTag', { subscriber_id, tag_id });
696
903
  }
697
904
  else if (operation === 'removeTagByName') {
698
905
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
699
- const tag_name = this.getNodeParameter('tag_name', i);
700
- responseData = await makeRequest('POST', '/fb/subscriber/removeTagByName', { subscriber_id, tag_name });
906
+ const tag_name = resolveTagName(i);
907
+ responseData = await request('POST', '/fb/subscriber/removeTagByName', { subscriber_id, tag_name });
701
908
  }
702
909
  else if (operation === 'setCustomField') {
703
910
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
704
- const field_id = this.getNodeParameter('field_id', i);
911
+ const field_id = resolveCustomFieldId(i);
705
912
  const field_value = this.getNodeParameter('field_value', i);
706
- responseData = await makeRequest('POST', '/fb/subscriber/setCustomField', { subscriber_id, field_id, field_value });
913
+ responseData = await request('POST', '/fb/subscriber/setCustomField', { subscriber_id, field_id, field_value });
707
914
  }
708
915
  else if (operation === 'setCustomFieldByName') {
709
916
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
710
- const field_name = this.getNodeParameter('field_name', i);
917
+ const field_name = resolveCustomFieldName(i);
711
918
  const field_value = this.getNodeParameter('field_value', i);
712
- responseData = await makeRequest('POST', '/fb/subscriber/setCustomFieldByName', { subscriber_id, field_name, field_value });
919
+ responseData = await request('POST', '/fb/subscriber/setCustomFieldByName', { subscriber_id, field_name, field_value });
713
920
  }
714
921
  else if (operation === 'setCustomFields') {
715
922
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
716
923
  const fieldsRaw = this.getNodeParameter('fields', i);
717
924
  const fields = typeof fieldsRaw === 'string' ? JSON.parse(fieldsRaw) : fieldsRaw;
718
- responseData = await makeRequest('POST', '/fb/subscriber/setCustomFields', { subscriber_id, fields });
925
+ responseData = await request('POST', '/fb/subscriber/setCustomFields', { subscriber_id, fields });
719
926
  }
720
927
  else if (operation === 'verifyBySignedRequest') {
721
928
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
722
929
  const signed_request = this.getNodeParameter('signed_request', i);
723
- responseData = await makeRequest('POST', '/fb/subscriber/verifyBySignedRequest', { subscriber_id, signed_request });
930
+ responseData = await request('POST', '/fb/subscriber/verifyBySignedRequest', { subscriber_id, signed_request });
724
931
  }
725
932
  else if (operation === 'createSubscriber') {
726
933
  const body = {};
@@ -730,9 +937,6 @@ class Manychat {
730
937
  const whatsapp_phone = this.getNodeParameter('whatsapp_phone', i);
731
938
  const email = this.getNodeParameter('email', i);
732
939
  const gender = this.getNodeParameter('gender', i);
733
- const has_opt_in_sms = this.getNodeParameter('has_opt_in_sms', i);
734
- const has_opt_in_email = this.getNodeParameter('has_opt_in_email', i);
735
- const consent_phrase = this.getNodeParameter('consent_phrase', i);
736
940
  if (first_name)
737
941
  body.first_name = first_name;
738
942
  if (last_name)
@@ -745,11 +949,12 @@ class Manychat {
745
949
  body.email = email;
746
950
  if (gender)
747
951
  body.gender = gender;
748
- body.has_opt_in_sms = has_opt_in_sms;
749
- body.has_opt_in_email = has_opt_in_email;
952
+ body.has_opt_in_sms = this.getNodeParameter('has_opt_in_sms', i);
953
+ body.has_opt_in_email = this.getNodeParameter('has_opt_in_email', i);
954
+ const consent_phrase = this.getNodeParameter('consent_phrase', i);
750
955
  if (consent_phrase)
751
956
  body.consent_phrase = consent_phrase;
752
- responseData = await makeRequest('POST', '/fb/subscriber/createSubscriber', body);
957
+ responseData = await request('POST', '/fb/subscriber/createSubscriber', body);
753
958
  }
754
959
  else if (operation === 'updateSubscriber') {
755
960
  const subscriber_id = this.getNodeParameter('subscriber_id', i);
@@ -759,9 +964,6 @@ class Manychat {
759
964
  const phone = this.getNodeParameter('phone', i);
760
965
  const email = this.getNodeParameter('email', i);
761
966
  const gender = this.getNodeParameter('gender', i);
762
- const has_opt_in_sms = this.getNodeParameter('has_opt_in_sms', i);
763
- const has_opt_in_email = this.getNodeParameter('has_opt_in_email', i);
764
- const consent_phrase = this.getNodeParameter('consent_phrase', i);
765
967
  if (first_name)
766
968
  body.first_name = first_name;
767
969
  if (last_name)
@@ -772,24 +974,25 @@ class Manychat {
772
974
  body.email = email;
773
975
  if (gender)
774
976
  body.gender = gender;
775
- body.has_opt_in_sms = has_opt_in_sms;
776
- body.has_opt_in_email = has_opt_in_email;
977
+ body.has_opt_in_sms = this.getNodeParameter('has_opt_in_sms', i);
978
+ body.has_opt_in_email = this.getNodeParameter('has_opt_in_email', i);
979
+ const consent_phrase = this.getNodeParameter('consent_phrase', i);
777
980
  if (consent_phrase)
778
981
  body.consent_phrase = consent_phrase;
779
- responseData = await makeRequest('POST', '/fb/subscriber/updateSubscriber', body);
982
+ responseData = await request('POST', '/fb/subscriber/updateSubscriber', body);
780
983
  }
781
984
  else {
782
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown subscriber operation: ${operation}`, { itemIndex: i });
985
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
783
986
  }
784
- // ── TEMPLATE ──────────────────────────────────────────────────────────
987
+ // ── TEMPLATE ─────────────────────────────────────────────────
785
988
  }
786
989
  else if (resource === 'template') {
787
990
  if (operation === 'generateSingleUseLink') {
788
991
  const template_id = this.getNodeParameter('template_id', i);
789
- responseData = await makeRequest('POST', '/user/template/generateSingleUseLink', { template_id });
992
+ responseData = await request('POST', '/user/template/generateSingleUseLink', { template_id });
790
993
  }
791
994
  else {
792
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown template operation: ${operation}`, { itemIndex: i });
995
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`, { itemIndex: i });
793
996
  }
794
997
  }
795
998
  else {