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