waba-toolkit 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -158,6 +158,102 @@ interface PhoneNumber {
158
158
  interface ListPhoneNumbersResponse {
159
159
  data: PhoneNumber[];
160
160
  }
161
+ type FlowCategory = 'SIGN_UP' | 'SIGN_IN' | 'APPOINTMENT_BOOKING' | 'LEAD_GENERATION' | 'CONTACT_US' | 'CUSTOMER_SUPPORT' | 'SURVEY' | 'OTHER';
162
+ interface CreateFlowOptions {
163
+ name: string;
164
+ categories?: FlowCategory[];
165
+ endpointUri?: string;
166
+ cloneFlowId?: string;
167
+ }
168
+ interface CreateFlowResponse {
169
+ id: string;
170
+ }
171
+ interface FlowValidationError {
172
+ error: string;
173
+ error_type: string;
174
+ message: string;
175
+ line_start: number;
176
+ line_end: number;
177
+ column_start: number;
178
+ column_end: number;
179
+ }
180
+ interface UpdateFlowJsonResponse {
181
+ success: boolean;
182
+ validation_errors: FlowValidationError[];
183
+ }
184
+ interface PublishFlowResponse {
185
+ success: boolean;
186
+ }
187
+ type FlowStatus = 'DRAFT' | 'PUBLISHED' | 'DEPRECATED' | 'BLOCKED' | 'THROTTLED';
188
+ interface FlowListItem {
189
+ id: string;
190
+ name: string;
191
+ status: FlowStatus;
192
+ categories: FlowCategory[];
193
+ validation_errors: FlowValidationError[];
194
+ }
195
+ interface ListFlowsResponse {
196
+ data: FlowListItem[];
197
+ paging?: {
198
+ cursors: {
199
+ before: string;
200
+ after: string;
201
+ };
202
+ };
203
+ }
204
+ type TemplateCategory = 'AUTHENTICATION' | 'MARKETING' | 'UTILITY';
205
+ type TemplateStatus = 'APPROVED' | 'IN_APPEAL' | 'PENDING' | 'REJECTED' | 'PENDING_DELETION' | 'DELETED' | 'DISABLED' | 'PAUSED' | 'LIMIT_EXCEEDED';
206
+ interface TemplateComponentDefinition {
207
+ type: 'HEADER' | 'BODY' | 'FOOTER' | 'BUTTONS';
208
+ format?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'DOCUMENT' | 'LOCATION';
209
+ text?: string;
210
+ buttons?: Array<{
211
+ type: string;
212
+ text?: string;
213
+ url?: string;
214
+ phone_number?: string;
215
+ [key: string]: unknown;
216
+ }>;
217
+ example?: {
218
+ header_text?: string[];
219
+ header_handle?: string[];
220
+ body_text?: string[][];
221
+ };
222
+ [key: string]: unknown;
223
+ }
224
+ interface TemplateListItem {
225
+ id: string;
226
+ name: string;
227
+ language: string;
228
+ status: TemplateStatus;
229
+ category: TemplateCategory;
230
+ previous_category?: TemplateCategory;
231
+ components: TemplateComponentDefinition[];
232
+ }
233
+ interface ListTemplatesResponse {
234
+ data: TemplateListItem[];
235
+ paging?: {
236
+ cursors: {
237
+ before: string;
238
+ after: string;
239
+ };
240
+ };
241
+ }
242
+ interface CreateTemplateRequest {
243
+ name: string;
244
+ language: string;
245
+ category: TemplateCategory;
246
+ components: TemplateComponentDefinition[];
247
+ allow_category_change?: boolean;
248
+ }
249
+ interface CreateTemplateResponse {
250
+ id: string;
251
+ status: TemplateStatus;
252
+ category: TemplateCategory;
253
+ }
254
+ interface DeleteTemplateResponse {
255
+ success: boolean;
256
+ }
161
257
 
162
258
  interface WABAApiClientOptions {
163
259
  accessToken: string;
@@ -229,6 +325,78 @@ declare class WABAApiClient {
229
325
  * @throws {WABANetworkError} - Network/connection failures
230
326
  */
231
327
  sendMessage(payload: MessagePayload): Promise<SendMessageResponse>;
328
+ /**
329
+ * Create a new WhatsApp Flow.
330
+ *
331
+ * @param wabaId - WhatsApp Business Account ID
332
+ * @param options - Flow creation options
333
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
334
+ * @throws {WABASendError} - Flow creation failure
335
+ * @throws {WABANetworkError} - Network/connection failures
336
+ */
337
+ createFlow(wabaId: string, options: CreateFlowOptions): Promise<CreateFlowResponse>;
338
+ /**
339
+ * Upload or update Flow JSON for an existing flow.
340
+ *
341
+ * @param flowId - Flow ID to update
342
+ * @param filePath - Path to the Flow JSON file
343
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
344
+ * @throws {WABASendError} - Flow update failure
345
+ * @throws {WABANetworkError} - Network/connection failures
346
+ */
347
+ updateFlowJson(flowId: string, filePath: string): Promise<UpdateFlowJsonResponse>;
348
+ /**
349
+ * Publish a flow. This action is irreversible.
350
+ * Once published, the flow and its assets become immutable.
351
+ * To update a published flow, create a new flow with clone_flow_id.
352
+ *
353
+ * @param flowId - Flow ID to publish
354
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
355
+ * @throws {WABASendError} - Flow publish failure
356
+ * @throws {WABANetworkError} - Network/connection failures
357
+ */
358
+ publishFlow(flowId: string): Promise<PublishFlowResponse>;
359
+ /**
360
+ * List all flows for a WhatsApp Business Account.
361
+ *
362
+ * @param wabaId - WhatsApp Business Account ID
363
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
364
+ * @throws {WABASendError} - Request failure
365
+ * @throws {WABANetworkError} - Network/connection failures
366
+ */
367
+ listFlows(wabaId: string): Promise<ListFlowsResponse>;
368
+ /**
369
+ * List all message templates for a WhatsApp Business Account.
370
+ *
371
+ * @param wabaId - WhatsApp Business Account ID
372
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
373
+ * @throws {WABASendError} - Request failure
374
+ * @throws {WABANetworkError} - Network/connection failures
375
+ */
376
+ listTemplates(wabaId: string): Promise<ListTemplatesResponse>;
377
+ /**
378
+ * Create a new message template.
379
+ *
380
+ * @param wabaId - WhatsApp Business Account ID
381
+ * @param request - Template creation request
382
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
383
+ * @throws {WABASendError} - Template creation failure
384
+ * @throws {WABANetworkError} - Network/connection failures
385
+ */
386
+ createTemplate(wabaId: string, request: CreateTemplateRequest): Promise<CreateTemplateResponse>;
387
+ /**
388
+ * Delete a message template by name.
389
+ *
390
+ * @param wabaId - WhatsApp Business Account ID
391
+ * @param templateName - Name of the template to delete
392
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
393
+ * @throws {WABASendError} - Template deletion failure
394
+ * @throws {WABANetworkError} - Network/connection failures
395
+ */
396
+ deleteTemplate(wabaId: string, templateName: string): Promise<DeleteTemplateResponse>;
397
+ private makeGetRequest;
398
+ private makeDeleteRequest;
399
+ private makeFormDataRequest;
232
400
  private makeRequest;
233
401
  }
234
402
 
@@ -756,4 +924,4 @@ declare class WABASendError extends WABAError {
756
924
  constructor(message: string, statusCode: number, errorPayload: unknown);
757
925
  }
758
926
 
759
- export { type AudioMessage, type ButtonMessage, type ButtonReply, type CallEntry, type CallWebhookValue, type ContactCard, type ContactInfo, type ContactsMessage, type ConversationObject, type DeregisterPhoneRequest, type DocumentMessage, type GetMediaOptions, type ImageMessage, type IncomingMessage, type IncomingMessageBase, type InteractiveMessage, type ListPhoneNumbersResponse, type ListReply, type LocationMessage, type MediaBufferResult, type MediaMessage, type MediaMetadata, type MediaObject, type MediaStreamResult, type MessageClassification, type MessageContext, type MessagePayload, type MessageStatus, type MessageWebhookValue, type OrderMessage, type PhoneNumber, type PricingObject, type ReactionMessage, type ReferralMessage, type RegisterPhoneRequest, type SendMessageResponse, type SendTemplateMessageRequest, type SendTextMessageRequest, type StatusEntry, type StatusWebhookValue, type StickerMessage, type SuccessResponse, type SystemMessage, type TemplateComponent, type TemplateParameter, type TextMessage, type UnsupportedMessage, type VerifyWebhookSignatureOptions, type VideoMessage, WABAApiClient, type WABAApiClientOptions, WABAAuthError, WABAClient, type WABAClientOptions, WABAConfigError, WABAError, WABAMediaError, WABANetworkError, WABASendError, WABASignatureError, type WebhookChange, type WebhookClassification, type WebhookContact, type WebhookEntry, type WebhookError, type WebhookMetadata, type WebhookPayload, type WebhookValue, classifyMessage, classifyWebhook, extractMediaId, getCallId, getContactInfo, getMessageId, getMessageTimestamp, isMediaMessage, verifyWebhookSignature };
927
+ export { type AudioMessage, type ButtonMessage, type ButtonReply, type CallEntry, type CallWebhookValue, type ContactCard, type ContactInfo, type ContactsMessage, type ConversationObject, type CreateFlowOptions, type CreateFlowResponse, type CreateTemplateRequest, type CreateTemplateResponse, type DeleteTemplateResponse, type DeregisterPhoneRequest, type DocumentMessage, type FlowCategory, type FlowListItem, type FlowStatus, type FlowValidationError, type GetMediaOptions, type ImageMessage, type IncomingMessage, type IncomingMessageBase, type InteractiveMessage, type ListFlowsResponse, type ListPhoneNumbersResponse, type ListReply, type ListTemplatesResponse, type LocationMessage, type MediaBufferResult, type MediaMessage, type MediaMetadata, type MediaObject, type MediaStreamResult, type MessageClassification, type MessageContext, type MessagePayload, type MessageStatus, type MessageWebhookValue, type OrderMessage, type PhoneNumber, type PricingObject, type PublishFlowResponse, type ReactionMessage, type ReferralMessage, type RegisterPhoneRequest, type SendMessageResponse, type SendTemplateMessageRequest, type SendTextMessageRequest, type StatusEntry, type StatusWebhookValue, type StickerMessage, type SuccessResponse, type SystemMessage, type TemplateCategory, type TemplateComponent, type TemplateComponentDefinition, type TemplateListItem, type TemplateParameter, type TemplateStatus, type TextMessage, type UnsupportedMessage, type UpdateFlowJsonResponse, type VerifyWebhookSignatureOptions, type VideoMessage, WABAApiClient, type WABAApiClientOptions, WABAAuthError, WABAClient, type WABAClientOptions, WABAConfigError, WABAError, WABAMediaError, WABANetworkError, WABASendError, WABASignatureError, type WebhookChange, type WebhookClassification, type WebhookContact, type WebhookEntry, type WebhookError, type WebhookMetadata, type WebhookPayload, type WebhookValue, classifyMessage, classifyWebhook, extractMediaId, getCallId, getContactInfo, getMessageId, getMessageTimestamp, isMediaMessage, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -158,6 +158,102 @@ interface PhoneNumber {
158
158
  interface ListPhoneNumbersResponse {
159
159
  data: PhoneNumber[];
160
160
  }
161
+ type FlowCategory = 'SIGN_UP' | 'SIGN_IN' | 'APPOINTMENT_BOOKING' | 'LEAD_GENERATION' | 'CONTACT_US' | 'CUSTOMER_SUPPORT' | 'SURVEY' | 'OTHER';
162
+ interface CreateFlowOptions {
163
+ name: string;
164
+ categories?: FlowCategory[];
165
+ endpointUri?: string;
166
+ cloneFlowId?: string;
167
+ }
168
+ interface CreateFlowResponse {
169
+ id: string;
170
+ }
171
+ interface FlowValidationError {
172
+ error: string;
173
+ error_type: string;
174
+ message: string;
175
+ line_start: number;
176
+ line_end: number;
177
+ column_start: number;
178
+ column_end: number;
179
+ }
180
+ interface UpdateFlowJsonResponse {
181
+ success: boolean;
182
+ validation_errors: FlowValidationError[];
183
+ }
184
+ interface PublishFlowResponse {
185
+ success: boolean;
186
+ }
187
+ type FlowStatus = 'DRAFT' | 'PUBLISHED' | 'DEPRECATED' | 'BLOCKED' | 'THROTTLED';
188
+ interface FlowListItem {
189
+ id: string;
190
+ name: string;
191
+ status: FlowStatus;
192
+ categories: FlowCategory[];
193
+ validation_errors: FlowValidationError[];
194
+ }
195
+ interface ListFlowsResponse {
196
+ data: FlowListItem[];
197
+ paging?: {
198
+ cursors: {
199
+ before: string;
200
+ after: string;
201
+ };
202
+ };
203
+ }
204
+ type TemplateCategory = 'AUTHENTICATION' | 'MARKETING' | 'UTILITY';
205
+ type TemplateStatus = 'APPROVED' | 'IN_APPEAL' | 'PENDING' | 'REJECTED' | 'PENDING_DELETION' | 'DELETED' | 'DISABLED' | 'PAUSED' | 'LIMIT_EXCEEDED';
206
+ interface TemplateComponentDefinition {
207
+ type: 'HEADER' | 'BODY' | 'FOOTER' | 'BUTTONS';
208
+ format?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'DOCUMENT' | 'LOCATION';
209
+ text?: string;
210
+ buttons?: Array<{
211
+ type: string;
212
+ text?: string;
213
+ url?: string;
214
+ phone_number?: string;
215
+ [key: string]: unknown;
216
+ }>;
217
+ example?: {
218
+ header_text?: string[];
219
+ header_handle?: string[];
220
+ body_text?: string[][];
221
+ };
222
+ [key: string]: unknown;
223
+ }
224
+ interface TemplateListItem {
225
+ id: string;
226
+ name: string;
227
+ language: string;
228
+ status: TemplateStatus;
229
+ category: TemplateCategory;
230
+ previous_category?: TemplateCategory;
231
+ components: TemplateComponentDefinition[];
232
+ }
233
+ interface ListTemplatesResponse {
234
+ data: TemplateListItem[];
235
+ paging?: {
236
+ cursors: {
237
+ before: string;
238
+ after: string;
239
+ };
240
+ };
241
+ }
242
+ interface CreateTemplateRequest {
243
+ name: string;
244
+ language: string;
245
+ category: TemplateCategory;
246
+ components: TemplateComponentDefinition[];
247
+ allow_category_change?: boolean;
248
+ }
249
+ interface CreateTemplateResponse {
250
+ id: string;
251
+ status: TemplateStatus;
252
+ category: TemplateCategory;
253
+ }
254
+ interface DeleteTemplateResponse {
255
+ success: boolean;
256
+ }
161
257
 
162
258
  interface WABAApiClientOptions {
163
259
  accessToken: string;
@@ -229,6 +325,78 @@ declare class WABAApiClient {
229
325
  * @throws {WABANetworkError} - Network/connection failures
230
326
  */
231
327
  sendMessage(payload: MessagePayload): Promise<SendMessageResponse>;
328
+ /**
329
+ * Create a new WhatsApp Flow.
330
+ *
331
+ * @param wabaId - WhatsApp Business Account ID
332
+ * @param options - Flow creation options
333
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
334
+ * @throws {WABASendError} - Flow creation failure
335
+ * @throws {WABANetworkError} - Network/connection failures
336
+ */
337
+ createFlow(wabaId: string, options: CreateFlowOptions): Promise<CreateFlowResponse>;
338
+ /**
339
+ * Upload or update Flow JSON for an existing flow.
340
+ *
341
+ * @param flowId - Flow ID to update
342
+ * @param filePath - Path to the Flow JSON file
343
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
344
+ * @throws {WABASendError} - Flow update failure
345
+ * @throws {WABANetworkError} - Network/connection failures
346
+ */
347
+ updateFlowJson(flowId: string, filePath: string): Promise<UpdateFlowJsonResponse>;
348
+ /**
349
+ * Publish a flow. This action is irreversible.
350
+ * Once published, the flow and its assets become immutable.
351
+ * To update a published flow, create a new flow with clone_flow_id.
352
+ *
353
+ * @param flowId - Flow ID to publish
354
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
355
+ * @throws {WABASendError} - Flow publish failure
356
+ * @throws {WABANetworkError} - Network/connection failures
357
+ */
358
+ publishFlow(flowId: string): Promise<PublishFlowResponse>;
359
+ /**
360
+ * List all flows for a WhatsApp Business Account.
361
+ *
362
+ * @param wabaId - WhatsApp Business Account ID
363
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
364
+ * @throws {WABASendError} - Request failure
365
+ * @throws {WABANetworkError} - Network/connection failures
366
+ */
367
+ listFlows(wabaId: string): Promise<ListFlowsResponse>;
368
+ /**
369
+ * List all message templates for a WhatsApp Business Account.
370
+ *
371
+ * @param wabaId - WhatsApp Business Account ID
372
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
373
+ * @throws {WABASendError} - Request failure
374
+ * @throws {WABANetworkError} - Network/connection failures
375
+ */
376
+ listTemplates(wabaId: string): Promise<ListTemplatesResponse>;
377
+ /**
378
+ * Create a new message template.
379
+ *
380
+ * @param wabaId - WhatsApp Business Account ID
381
+ * @param request - Template creation request
382
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
383
+ * @throws {WABASendError} - Template creation failure
384
+ * @throws {WABANetworkError} - Network/connection failures
385
+ */
386
+ createTemplate(wabaId: string, request: CreateTemplateRequest): Promise<CreateTemplateResponse>;
387
+ /**
388
+ * Delete a message template by name.
389
+ *
390
+ * @param wabaId - WhatsApp Business Account ID
391
+ * @param templateName - Name of the template to delete
392
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
393
+ * @throws {WABASendError} - Template deletion failure
394
+ * @throws {WABANetworkError} - Network/connection failures
395
+ */
396
+ deleteTemplate(wabaId: string, templateName: string): Promise<DeleteTemplateResponse>;
397
+ private makeGetRequest;
398
+ private makeDeleteRequest;
399
+ private makeFormDataRequest;
232
400
  private makeRequest;
233
401
  }
234
402
 
@@ -756,4 +924,4 @@ declare class WABASendError extends WABAError {
756
924
  constructor(message: string, statusCode: number, errorPayload: unknown);
757
925
  }
758
926
 
759
- export { type AudioMessage, type ButtonMessage, type ButtonReply, type CallEntry, type CallWebhookValue, type ContactCard, type ContactInfo, type ContactsMessage, type ConversationObject, type DeregisterPhoneRequest, type DocumentMessage, type GetMediaOptions, type ImageMessage, type IncomingMessage, type IncomingMessageBase, type InteractiveMessage, type ListPhoneNumbersResponse, type ListReply, type LocationMessage, type MediaBufferResult, type MediaMessage, type MediaMetadata, type MediaObject, type MediaStreamResult, type MessageClassification, type MessageContext, type MessagePayload, type MessageStatus, type MessageWebhookValue, type OrderMessage, type PhoneNumber, type PricingObject, type ReactionMessage, type ReferralMessage, type RegisterPhoneRequest, type SendMessageResponse, type SendTemplateMessageRequest, type SendTextMessageRequest, type StatusEntry, type StatusWebhookValue, type StickerMessage, type SuccessResponse, type SystemMessage, type TemplateComponent, type TemplateParameter, type TextMessage, type UnsupportedMessage, type VerifyWebhookSignatureOptions, type VideoMessage, WABAApiClient, type WABAApiClientOptions, WABAAuthError, WABAClient, type WABAClientOptions, WABAConfigError, WABAError, WABAMediaError, WABANetworkError, WABASendError, WABASignatureError, type WebhookChange, type WebhookClassification, type WebhookContact, type WebhookEntry, type WebhookError, type WebhookMetadata, type WebhookPayload, type WebhookValue, classifyMessage, classifyWebhook, extractMediaId, getCallId, getContactInfo, getMessageId, getMessageTimestamp, isMediaMessage, verifyWebhookSignature };
927
+ export { type AudioMessage, type ButtonMessage, type ButtonReply, type CallEntry, type CallWebhookValue, type ContactCard, type ContactInfo, type ContactsMessage, type ConversationObject, type CreateFlowOptions, type CreateFlowResponse, type CreateTemplateRequest, type CreateTemplateResponse, type DeleteTemplateResponse, type DeregisterPhoneRequest, type DocumentMessage, type FlowCategory, type FlowListItem, type FlowStatus, type FlowValidationError, type GetMediaOptions, type ImageMessage, type IncomingMessage, type IncomingMessageBase, type InteractiveMessage, type ListFlowsResponse, type ListPhoneNumbersResponse, type ListReply, type ListTemplatesResponse, type LocationMessage, type MediaBufferResult, type MediaMessage, type MediaMetadata, type MediaObject, type MediaStreamResult, type MessageClassification, type MessageContext, type MessagePayload, type MessageStatus, type MessageWebhookValue, type OrderMessage, type PhoneNumber, type PricingObject, type PublishFlowResponse, type ReactionMessage, type ReferralMessage, type RegisterPhoneRequest, type SendMessageResponse, type SendTemplateMessageRequest, type SendTextMessageRequest, type StatusEntry, type StatusWebhookValue, type StickerMessage, type SuccessResponse, type SystemMessage, type TemplateCategory, type TemplateComponent, type TemplateComponentDefinition, type TemplateListItem, type TemplateParameter, type TemplateStatus, type TextMessage, type UnsupportedMessage, type UpdateFlowJsonResponse, type VerifyWebhookSignatureOptions, type VideoMessage, WABAApiClient, type WABAApiClientOptions, WABAAuthError, WABAClient, type WABAClientOptions, WABAConfigError, WABAError, WABAMediaError, WABANetworkError, WABASendError, WABASignatureError, type WebhookChange, type WebhookClassification, type WebhookContact, type WebhookEntry, type WebhookError, type WebhookMetadata, type WebhookPayload, type WebhookValue, classifyMessage, classifyWebhook, extractMediaId, getCallId, getContactInfo, getMessageId, getMessageTimestamp, isMediaMessage, verifyWebhookSignature };
package/dist/index.js CHANGED
@@ -230,6 +230,7 @@ var WABAClient = class {
230
230
  };
231
231
 
232
232
  // src/api/client.ts
233
+ var import_node_fs = require("fs");
233
234
  var DEFAULT_API_VERSION2 = "v22.0";
234
235
  var DEFAULT_BASE_URL2 = "https://graph.facebook.com";
235
236
  var WABAApiClient = class {
@@ -364,6 +365,263 @@ var WABAApiClient = class {
364
365
  const url = `${this.baseUrl}/${this.apiVersion}/${this.phoneNumberId}/messages`;
365
366
  return this.makeRequest(url, "POST", payload);
366
367
  }
368
+ /**
369
+ * Create a new WhatsApp Flow.
370
+ *
371
+ * @param wabaId - WhatsApp Business Account ID
372
+ * @param options - Flow creation options
373
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
374
+ * @throws {WABASendError} - Flow creation failure
375
+ * @throws {WABANetworkError} - Network/connection failures
376
+ */
377
+ async createFlow(wabaId, options) {
378
+ const url = `${this.baseUrl}/${this.apiVersion}/${wabaId}/flows`;
379
+ const formData = new FormData();
380
+ formData.append("name", options.name);
381
+ const categories = options.categories ?? ["OTHER"];
382
+ formData.append("categories", JSON.stringify(categories));
383
+ if (options.endpointUri) {
384
+ formData.append("endpoint_uri", options.endpointUri);
385
+ }
386
+ if (options.cloneFlowId) {
387
+ formData.append("clone_flow_id", options.cloneFlowId);
388
+ }
389
+ return this.makeFormDataRequest(url, formData);
390
+ }
391
+ /**
392
+ * Upload or update Flow JSON for an existing flow.
393
+ *
394
+ * @param flowId - Flow ID to update
395
+ * @param filePath - Path to the Flow JSON file
396
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
397
+ * @throws {WABASendError} - Flow update failure
398
+ * @throws {WABANetworkError} - Network/connection failures
399
+ */
400
+ async updateFlowJson(flowId, filePath) {
401
+ const url = `${this.baseUrl}/${this.apiVersion}/${flowId}/assets`;
402
+ const fileContent = (0, import_node_fs.readFileSync)(filePath, "utf8");
403
+ const blob = new Blob([fileContent], { type: "application/json" });
404
+ const formData = new FormData();
405
+ formData.append("file", blob, "flow.json");
406
+ formData.append("name", "flow.json");
407
+ formData.append("asset_type", "FLOW_JSON");
408
+ return this.makeFormDataRequest(url, formData);
409
+ }
410
+ /**
411
+ * Publish a flow. This action is irreversible.
412
+ * Once published, the flow and its assets become immutable.
413
+ * To update a published flow, create a new flow with clone_flow_id.
414
+ *
415
+ * @param flowId - Flow ID to publish
416
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
417
+ * @throws {WABASendError} - Flow publish failure
418
+ * @throws {WABANetworkError} - Network/connection failures
419
+ */
420
+ async publishFlow(flowId) {
421
+ const url = `${this.baseUrl}/${this.apiVersion}/${flowId}/publish`;
422
+ let response;
423
+ try {
424
+ response = await fetch(url, {
425
+ method: "POST",
426
+ headers: {
427
+ Authorization: `Bearer ${this.accessToken}`
428
+ }
429
+ });
430
+ } catch (error) {
431
+ throw new WABANetworkError(
432
+ `Failed to make request: ${error instanceof Error ? error.message : "Unknown error"}`,
433
+ error instanceof Error ? error : void 0
434
+ );
435
+ }
436
+ if (response.ok) {
437
+ return await response.json();
438
+ }
439
+ const errorBody = await response.json().catch(() => null);
440
+ if (response.status === 401 || response.status === 403) {
441
+ throw new WABAAuthError(
442
+ `Authentication failed: ${response.status} ${response.statusText}`,
443
+ response.status
444
+ );
445
+ }
446
+ throw new WABASendError(
447
+ `Request failed: ${response.status} ${response.statusText}`,
448
+ response.status,
449
+ errorBody
450
+ );
451
+ }
452
+ /**
453
+ * List all flows for a WhatsApp Business Account.
454
+ *
455
+ * @param wabaId - WhatsApp Business Account ID
456
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
457
+ * @throws {WABASendError} - Request failure
458
+ * @throws {WABANetworkError} - Network/connection failures
459
+ */
460
+ async listFlows(wabaId) {
461
+ const url = `${this.baseUrl}/${this.apiVersion}/${wabaId}/flows`;
462
+ let response;
463
+ try {
464
+ response = await fetch(url, {
465
+ method: "GET",
466
+ headers: {
467
+ Authorization: `Bearer ${this.accessToken}`
468
+ }
469
+ });
470
+ } catch (error) {
471
+ throw new WABANetworkError(
472
+ `Failed to make request: ${error instanceof Error ? error.message : "Unknown error"}`,
473
+ error instanceof Error ? error : void 0
474
+ );
475
+ }
476
+ if (response.ok) {
477
+ return await response.json();
478
+ }
479
+ const errorBody = await response.json().catch(() => null);
480
+ if (response.status === 401 || response.status === 403) {
481
+ throw new WABAAuthError(
482
+ `Authentication failed: ${response.status} ${response.statusText}`,
483
+ response.status
484
+ );
485
+ }
486
+ throw new WABASendError(
487
+ `Request failed: ${response.status} ${response.statusText}`,
488
+ response.status,
489
+ errorBody
490
+ );
491
+ }
492
+ /**
493
+ * List all message templates for a WhatsApp Business Account.
494
+ *
495
+ * @param wabaId - WhatsApp Business Account ID
496
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
497
+ * @throws {WABASendError} - Request failure
498
+ * @throws {WABANetworkError} - Network/connection failures
499
+ */
500
+ async listTemplates(wabaId) {
501
+ const url = `${this.baseUrl}/${this.apiVersion}/${wabaId}/message_templates`;
502
+ return this.makeGetRequest(url);
503
+ }
504
+ /**
505
+ * Create a new message template.
506
+ *
507
+ * @param wabaId - WhatsApp Business Account ID
508
+ * @param request - Template creation request
509
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
510
+ * @throws {WABASendError} - Template creation failure
511
+ * @throws {WABANetworkError} - Network/connection failures
512
+ */
513
+ async createTemplate(wabaId, request) {
514
+ const url = `${this.baseUrl}/${this.apiVersion}/${wabaId}/message_templates`;
515
+ return this.makeRequest(url, "POST", request);
516
+ }
517
+ /**
518
+ * Delete a message template by name.
519
+ *
520
+ * @param wabaId - WhatsApp Business Account ID
521
+ * @param templateName - Name of the template to delete
522
+ * @throws {WABAAuthError} - Authentication failure (invalid token)
523
+ * @throws {WABASendError} - Template deletion failure
524
+ * @throws {WABANetworkError} - Network/connection failures
525
+ */
526
+ async deleteTemplate(wabaId, templateName) {
527
+ const url = `${this.baseUrl}/${this.apiVersion}/${wabaId}/message_templates?name=${encodeURIComponent(templateName)}`;
528
+ return this.makeDeleteRequest(url);
529
+ }
530
+ async makeGetRequest(url) {
531
+ let response;
532
+ try {
533
+ response = await fetch(url, {
534
+ method: "GET",
535
+ headers: {
536
+ Authorization: `Bearer ${this.accessToken}`
537
+ }
538
+ });
539
+ } catch (error) {
540
+ throw new WABANetworkError(
541
+ `Failed to make request: ${error instanceof Error ? error.message : "Unknown error"}`,
542
+ error instanceof Error ? error : void 0
543
+ );
544
+ }
545
+ if (response.ok) {
546
+ return await response.json();
547
+ }
548
+ const errorBody = await response.json().catch(() => null);
549
+ if (response.status === 401 || response.status === 403) {
550
+ throw new WABAAuthError(
551
+ `Authentication failed: ${response.status} ${response.statusText}`,
552
+ response.status
553
+ );
554
+ }
555
+ throw new WABASendError(
556
+ `Request failed: ${response.status} ${response.statusText}`,
557
+ response.status,
558
+ errorBody
559
+ );
560
+ }
561
+ async makeDeleteRequest(url) {
562
+ let response;
563
+ try {
564
+ response = await fetch(url, {
565
+ method: "DELETE",
566
+ headers: {
567
+ Authorization: `Bearer ${this.accessToken}`
568
+ }
569
+ });
570
+ } catch (error) {
571
+ throw new WABANetworkError(
572
+ `Failed to make request: ${error instanceof Error ? error.message : "Unknown error"}`,
573
+ error instanceof Error ? error : void 0
574
+ );
575
+ }
576
+ if (response.ok) {
577
+ return await response.json();
578
+ }
579
+ const errorBody = await response.json().catch(() => null);
580
+ if (response.status === 401 || response.status === 403) {
581
+ throw new WABAAuthError(
582
+ `Authentication failed: ${response.status} ${response.statusText}`,
583
+ response.status
584
+ );
585
+ }
586
+ throw new WABASendError(
587
+ `Request failed: ${response.status} ${response.statusText}`,
588
+ response.status,
589
+ errorBody
590
+ );
591
+ }
592
+ async makeFormDataRequest(url, formData) {
593
+ let response;
594
+ try {
595
+ response = await fetch(url, {
596
+ method: "POST",
597
+ headers: {
598
+ Authorization: `Bearer ${this.accessToken}`
599
+ // Note: Do NOT set Content-Type header - fetch will set it with boundary for FormData
600
+ },
601
+ body: formData
602
+ });
603
+ } catch (error) {
604
+ throw new WABANetworkError(
605
+ `Failed to make request: ${error instanceof Error ? error.message : "Unknown error"}`,
606
+ error instanceof Error ? error : void 0
607
+ );
608
+ }
609
+ if (response.ok) {
610
+ return await response.json();
611
+ }
612
+ const errorBody = await response.json().catch(() => null);
613
+ if (response.status === 401 || response.status === 403) {
614
+ throw new WABAAuthError(
615
+ `Authentication failed: ${response.status} ${response.statusText}`,
616
+ response.status
617
+ );
618
+ }
619
+ throw new WABASendError(
620
+ `Request failed: ${response.status} ${response.statusText}`,
621
+ response.status,
622
+ errorBody
623
+ );
624
+ }
367
625
  async makeRequest(url, method, body) {
368
626
  let response;
369
627
  try {