meta-cloud-api 0.1.10 → 0.1.12
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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types/webhook.d.mts +1 -18
- package/dist/types/webhook.d.ts +1 -18
- package/dist/types/webhook.js.map +1 -1
- package/dist/types/webhook.mjs.map +1 -1
- package/dist/webhook.d.mts +8 -37
- package/dist/webhook.d.ts +8 -37
- package/dist/webhook.js +1 -1
- package/dist/webhook.js.map +1 -1
- package/dist/webhook.mjs +1 -1
- package/dist/webhook.mjs.map +1 -1
- package/package.json +1 -1
package/dist/types/webhook.d.mts
CHANGED
|
@@ -387,23 +387,6 @@ interface WebhookEvent {
|
|
|
387
387
|
*/
|
|
388
388
|
value: any;
|
|
389
389
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Configuration for the webhook handler
|
|
392
|
-
*/
|
|
393
|
-
interface WebhookConfig {
|
|
394
|
-
/**
|
|
395
|
-
* The URL path to listen on
|
|
396
|
-
*/
|
|
397
|
-
path?: string;
|
|
398
|
-
/**
|
|
399
|
-
* The verification token for the webhook
|
|
400
|
-
*/
|
|
401
|
-
verifyToken: string;
|
|
402
|
-
/**
|
|
403
|
-
* The public URL for the webhook
|
|
404
|
-
*/
|
|
405
|
-
callbackUrl: string;
|
|
406
|
-
}
|
|
407
390
|
/**
|
|
408
391
|
* Handler function for processing messages
|
|
409
392
|
*/
|
|
@@ -450,4 +433,4 @@ declare enum EventField {
|
|
|
450
433
|
UNKNOWN = "unknown"
|
|
451
434
|
}
|
|
452
435
|
|
|
453
|
-
export { EventField, type EventHandler, type MessageHandler, MessageStatus, MessageType, type
|
|
436
|
+
export { EventField, type EventHandler, type MessageHandler, MessageStatus, MessageType, type WebhookEvent, type WebhookMessage };
|
package/dist/types/webhook.d.ts
CHANGED
|
@@ -387,23 +387,6 @@ interface WebhookEvent {
|
|
|
387
387
|
*/
|
|
388
388
|
value: any;
|
|
389
389
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Configuration for the webhook handler
|
|
392
|
-
*/
|
|
393
|
-
interface WebhookConfig {
|
|
394
|
-
/**
|
|
395
|
-
* The URL path to listen on
|
|
396
|
-
*/
|
|
397
|
-
path?: string;
|
|
398
|
-
/**
|
|
399
|
-
* The verification token for the webhook
|
|
400
|
-
*/
|
|
401
|
-
verifyToken: string;
|
|
402
|
-
/**
|
|
403
|
-
* The public URL for the webhook
|
|
404
|
-
*/
|
|
405
|
-
callbackUrl: string;
|
|
406
|
-
}
|
|
407
390
|
/**
|
|
408
391
|
* Handler function for processing messages
|
|
409
392
|
*/
|
|
@@ -450,4 +433,4 @@ declare enum EventField {
|
|
|
450
433
|
UNKNOWN = "unknown"
|
|
451
434
|
}
|
|
452
435
|
|
|
453
|
-
export { EventField, type EventHandler, type MessageHandler, MessageStatus, MessageType, type
|
|
436
|
+
export { EventField, type EventHandler, type MessageHandler, MessageStatus, MessageType, type WebhookEvent, type WebhookMessage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/webhook.ts"],"sourcesContent":["/**\n * Represents a message received through the webhook\n * Based on Meta's documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#messages-object\n */\nexport interface WebhookMessage {\n /**\n * The message ID\n */\n id: string;\n\n /**\n * The sender's phone number\n */\n from: string;\n\n /**\n * The timestamp of the message\n */\n timestamp: string;\n\n /**\n * The type of message (text, image, etc.)\n */\n type: MessageType;\n\n /**\n * The phone number ID that received the message\n */\n phoneNumberId: string;\n\n /**\n * Text object for text messages\n */\n text?: {\n /**\n * The text content of the message\n */\n body: string;\n };\n\n /**\n * Image object for image messages\n */\n image?: {\n /**\n * The image caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the image\n */\n sha256?: string;\n /**\n * The ID for the image\n */\n id: string;\n /**\n * The MIME type of the image\n */\n mime_type: string;\n };\n\n /**\n * Video object for video messages\n */\n video?: {\n /**\n * The video caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the video\n */\n sha256?: string;\n /**\n * The ID for the video\n */\n id: string;\n /**\n * The MIME type of the video\n */\n mime_type: string;\n };\n\n /**\n * Audio object for audio messages\n */\n audio?: {\n /**\n * The ID for the audio file\n */\n id: string;\n /**\n * The MIME type of the audio file\n */\n mime_type: string;\n /**\n * Whether the audio is a voice message\n */\n voice?: boolean;\n };\n\n /**\n * Document object for document messages\n */\n document?: {\n /**\n * The document caption (if provided)\n */\n caption?: string;\n /**\n * The document filename\n */\n filename: string;\n /**\n * The SHA256 hash of the document\n */\n sha256?: string;\n /**\n * The ID for the document\n */\n id: string;\n /**\n * The MIME type of the document\n */\n mime_type: string;\n };\n\n /**\n * Sticker object for sticker messages\n */\n sticker?: {\n /**\n * The ID for the sticker\n */\n id: string;\n /**\n * Whether this is an animated sticker\n */\n animated: boolean;\n /**\n * The MIME type of the sticker\n */\n mime_type: string;\n };\n\n /**\n * Contacts object for contact messages\n */\n contacts?: Array<{\n /**\n * The contact's name\n */\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n middle_name?: string;\n suffix?: string;\n prefix?: string;\n };\n /**\n * The contact's phone numbers\n */\n phones?: Array<{\n phone: string;\n type?: string;\n wa_id?: string;\n }>;\n /**\n * The contact's emails\n */\n emails?: Array<{\n email: string;\n type?: string;\n }>;\n /**\n * The contact's addresses\n */\n addresses?: Array<{\n street?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n country_code?: string;\n type?: string;\n }>;\n /**\n * The contact's organizations\n */\n org?: {\n company?: string;\n department?: string;\n title?: string;\n };\n /**\n * The contact's URLs\n */\n urls?: Array<{\n url: string;\n type?: string;\n }>;\n /**\n * The contact's birthday (YYYY-MM-DD format)\n */\n birthday?: string;\n }>;\n\n /**\n * Location object for location messages\n */\n location?: {\n /**\n * Latitude of the location\n */\n latitude: number;\n /**\n * Longitude of the location\n */\n longitude: number;\n /**\n * Name of the location\n */\n name?: string;\n /**\n * Address of the location\n */\n address?: string;\n };\n\n /**\n * Interactive object for interactive messages\n */\n interactive?: {\n /**\n * Type of the interactive message\n */\n type: string;\n /**\n * ID for the button that was clicked\n */\n button_reply?: {\n id: string;\n title: string;\n };\n /**\n * ID for the list item that was selected\n */\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n };\n\n /**\n * System object for system messages (like user phone number changes)\n */\n system?: {\n /**\n * The type of system update\n */\n type: string;\n /**\n * User's identity if the update is a customer identity change\n */\n identity?: string;\n /**\n * Old and new phone numbers if the update is a phone number change\n */\n customer?: {\n /**\n * The previous phone number\n */\n previous_wa_id: string;\n /**\n * The new phone number\n */\n wa_id: string;\n };\n };\n\n /**\n * Order object for order messages\n */\n order?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product items in the order\n */\n product_items: Array<{\n /**\n * Product ID\n */\n product_retailer_id: string;\n /**\n * Quantity of the product\n */\n quantity: number;\n /**\n * Item price\n */\n item_price: number;\n /**\n * Currency code\n */\n currency: string;\n }>;\n /**\n * Text message included with the order\n */\n text?: string;\n };\n\n /**\n * Context object, included when a user replies or interacts\n */\n context?: {\n /**\n * ID of the message being replied to or interacted with\n */\n message_id: string;\n /**\n * ID of the forwarded message, if applicable\n */\n forwarded?: boolean;\n /**\n * Frequently forwarded status\n */\n frequently_forwarded?: boolean;\n /**\n * Original message information if the message was referred\n */\n referred_product?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product ID\n */\n product_retailer_id: string;\n };\n };\n\n /**\n * Errors array, if the message had errors\n */\n errors?: Array<{\n /**\n * Error code\n */\n code: number;\n /**\n * Error title\n */\n title: string;\n /**\n * Error message\n */\n message: string;\n /**\n * Error details object\n */\n error_data?: {\n /**\n * Describes the error details\n */\n details: string;\n };\n }>;\n\n /**\n * Button object for button messages\n */\n button?: {\n /**\n * The payload for the button\n */\n payload: string;\n /**\n * Button text\n */\n text: string;\n };\n\n /**\n * The original message data as received from the webhook\n */\n originalData: any;\n}\n\n/**\n * Represents a non-message event received through the webhook\n */\nexport interface WebhookEvent {\n /**\n * The field type of the event\n */\n field: string;\n\n /**\n * The event data\n */\n value: any;\n}\n\n/**\n * Configuration for the webhook handler\n */\nexport interface WebhookConfig {\n /**\n * The URL path to listen on\n */\n path?: string;\n\n /**\n * The verification token for the webhook\n */\n verifyToken: string;\n\n /**\n * The public URL for the webhook\n */\n callbackUrl: string;\n}\n\n/**\n * Handler function for processing messages\n */\nexport type MessageHandler = (message: WebhookMessage) => void | Promise<void>;\n\n/**\n * Handler function for processing events\n */\nexport type EventHandler = (event: WebhookEvent) => void | Promise<void>;\n\n/**\n * Message types that can be received through the webhook\n */\nexport enum MessageType {\n TEXT = 'text',\n IMAGE = 'image',\n AUDIO = 'audio',\n VIDEO = 'video',\n DOCUMENT = 'document',\n STICKER = 'sticker',\n LOCATION = 'location',\n CONTACTS = 'contacts',\n BUTTON = 'button',\n INTERACTIVE = 'interactive',\n ORDER = 'order',\n SYSTEM = 'system',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Statuses that can be received in status updates\n */\nexport enum MessageStatus {\n DELIVERED = 'delivered',\n READ = 'read',\n SENT = 'sent',\n}\n\n/**\n * Event fields that can be received through the webhook\n */\nexport enum EventField {\n MESSAGES = 'messages',\n STATUSES = 'statuses',\n MESSAGE_TEMPLATE_STATUS_UPDATE = 'message_template_status_update',\n PHONE_NUMBER_QUALITY_UPDATE = 'phone_number_quality_update',\n PHONE_NUMBER_NAME_UPDATE = 'phone_number_name_update',\n UNKNOWN = 'unknown',\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,EAAA,kBAAAC,EAAA,gBAAAC,IAAA,eAAAC,EAAAL,GA4bO,IAAKI,OACRA,EAAA,KAAO,OACPA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,OAAS,SACTA,EAAA,YAAc,cACdA,EAAA,MAAQ,QACRA,EAAA,OAAS,SACTA,EAAA,QAAU,UAbFA,OAAA,IAmBAD,OACRA,EAAA,UAAY,YACZA,EAAA,KAAO,OACPA,EAAA,KAAO,OAHCA,OAAA,IASAD,OACRA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,yBAA2B,2BAC3BA,EAAA,QAAU,UANFA,OAAA","names":["webhook_exports","__export","EventField","MessageStatus","MessageType","__toCommonJS"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types/webhook.ts"],"sourcesContent":["/**\n * Represents a message received through the webhook\n * Based on Meta's documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#messages-object\n */\nexport interface WebhookMessage {\n /**\n * The message ID\n */\n id: string;\n\n /**\n * The sender's phone number\n */\n from: string;\n\n /**\n * The timestamp of the message\n */\n timestamp: string;\n\n /**\n * The type of message (text, image, etc.)\n */\n type: MessageType;\n\n /**\n * The phone number ID that received the message\n */\n phoneNumberId: string;\n\n /**\n * Text object for text messages\n */\n text?: {\n /**\n * The text content of the message\n */\n body: string;\n };\n\n /**\n * Image object for image messages\n */\n image?: {\n /**\n * The image caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the image\n */\n sha256?: string;\n /**\n * The ID for the image\n */\n id: string;\n /**\n * The MIME type of the image\n */\n mime_type: string;\n };\n\n /**\n * Video object for video messages\n */\n video?: {\n /**\n * The video caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the video\n */\n sha256?: string;\n /**\n * The ID for the video\n */\n id: string;\n /**\n * The MIME type of the video\n */\n mime_type: string;\n };\n\n /**\n * Audio object for audio messages\n */\n audio?: {\n /**\n * The ID for the audio file\n */\n id: string;\n /**\n * The MIME type of the audio file\n */\n mime_type: string;\n /**\n * Whether the audio is a voice message\n */\n voice?: boolean;\n };\n\n /**\n * Document object for document messages\n */\n document?: {\n /**\n * The document caption (if provided)\n */\n caption?: string;\n /**\n * The document filename\n */\n filename: string;\n /**\n * The SHA256 hash of the document\n */\n sha256?: string;\n /**\n * The ID for the document\n */\n id: string;\n /**\n * The MIME type of the document\n */\n mime_type: string;\n };\n\n /**\n * Sticker object for sticker messages\n */\n sticker?: {\n /**\n * The ID for the sticker\n */\n id: string;\n /**\n * Whether this is an animated sticker\n */\n animated: boolean;\n /**\n * The MIME type of the sticker\n */\n mime_type: string;\n };\n\n /**\n * Contacts object for contact messages\n */\n contacts?: Array<{\n /**\n * The contact's name\n */\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n middle_name?: string;\n suffix?: string;\n prefix?: string;\n };\n /**\n * The contact's phone numbers\n */\n phones?: Array<{\n phone: string;\n type?: string;\n wa_id?: string;\n }>;\n /**\n * The contact's emails\n */\n emails?: Array<{\n email: string;\n type?: string;\n }>;\n /**\n * The contact's addresses\n */\n addresses?: Array<{\n street?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n country_code?: string;\n type?: string;\n }>;\n /**\n * The contact's organizations\n */\n org?: {\n company?: string;\n department?: string;\n title?: string;\n };\n /**\n * The contact's URLs\n */\n urls?: Array<{\n url: string;\n type?: string;\n }>;\n /**\n * The contact's birthday (YYYY-MM-DD format)\n */\n birthday?: string;\n }>;\n\n /**\n * Location object for location messages\n */\n location?: {\n /**\n * Latitude of the location\n */\n latitude: number;\n /**\n * Longitude of the location\n */\n longitude: number;\n /**\n * Name of the location\n */\n name?: string;\n /**\n * Address of the location\n */\n address?: string;\n };\n\n /**\n * Interactive object for interactive messages\n */\n interactive?: {\n /**\n * Type of the interactive message\n */\n type: string;\n /**\n * ID for the button that was clicked\n */\n button_reply?: {\n id: string;\n title: string;\n };\n /**\n * ID for the list item that was selected\n */\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n };\n\n /**\n * System object for system messages (like user phone number changes)\n */\n system?: {\n /**\n * The type of system update\n */\n type: string;\n /**\n * User's identity if the update is a customer identity change\n */\n identity?: string;\n /**\n * Old and new phone numbers if the update is a phone number change\n */\n customer?: {\n /**\n * The previous phone number\n */\n previous_wa_id: string;\n /**\n * The new phone number\n */\n wa_id: string;\n };\n };\n\n /**\n * Order object for order messages\n */\n order?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product items in the order\n */\n product_items: Array<{\n /**\n * Product ID\n */\n product_retailer_id: string;\n /**\n * Quantity of the product\n */\n quantity: number;\n /**\n * Item price\n */\n item_price: number;\n /**\n * Currency code\n */\n currency: string;\n }>;\n /**\n * Text message included with the order\n */\n text?: string;\n };\n\n /**\n * Context object, included when a user replies or interacts\n */\n context?: {\n /**\n * ID of the message being replied to or interacted with\n */\n message_id: string;\n /**\n * ID of the forwarded message, if applicable\n */\n forwarded?: boolean;\n /**\n * Frequently forwarded status\n */\n frequently_forwarded?: boolean;\n /**\n * Original message information if the message was referred\n */\n referred_product?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product ID\n */\n product_retailer_id: string;\n };\n };\n\n /**\n * Errors array, if the message had errors\n */\n errors?: Array<{\n /**\n * Error code\n */\n code: number;\n /**\n * Error title\n */\n title: string;\n /**\n * Error message\n */\n message: string;\n /**\n * Error details object\n */\n error_data?: {\n /**\n * Describes the error details\n */\n details: string;\n };\n }>;\n\n /**\n * Button object for button messages\n */\n button?: {\n /**\n * The payload for the button\n */\n payload: string;\n /**\n * Button text\n */\n text: string;\n };\n\n /**\n * The original message data as received from the webhook\n */\n originalData: any;\n}\n\n/**\n * Represents a non-message event received through the webhook\n */\nexport interface WebhookEvent {\n /**\n * The field type of the event\n */\n field: string;\n\n /**\n * The event data\n */\n value: any;\n}\n\n/**\n * Handler function for processing messages\n */\nexport type MessageHandler = (message: WebhookMessage) => void | Promise<void>;\n\n/**\n * Handler function for processing events\n */\nexport type EventHandler = (event: WebhookEvent) => void | Promise<void>;\n\n/**\n * Message types that can be received through the webhook\n */\nexport enum MessageType {\n TEXT = 'text',\n IMAGE = 'image',\n AUDIO = 'audio',\n VIDEO = 'video',\n DOCUMENT = 'document',\n STICKER = 'sticker',\n LOCATION = 'location',\n CONTACTS = 'contacts',\n BUTTON = 'button',\n INTERACTIVE = 'interactive',\n ORDER = 'order',\n SYSTEM = 'system',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Statuses that can be received in status updates\n */\nexport enum MessageStatus {\n DELIVERED = 'delivered',\n READ = 'read',\n SENT = 'sent',\n}\n\n/**\n * Event fields that can be received through the webhook\n */\nexport enum EventField {\n MESSAGES = 'messages',\n STATUSES = 'statuses',\n MESSAGE_TEMPLATE_STATUS_UPDATE = 'message_template_status_update',\n PHONE_NUMBER_QUALITY_UPDATE = 'phone_number_quality_update',\n PHONE_NUMBER_NAME_UPDATE = 'phone_number_name_update',\n UNKNOWN = 'unknown',\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,EAAA,kBAAAC,EAAA,gBAAAC,IAAA,eAAAC,EAAAL,GAwaO,IAAKI,OACRA,EAAA,KAAO,OACPA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,OAAS,SACTA,EAAA,YAAc,cACdA,EAAA,MAAQ,QACRA,EAAA,OAAS,SACTA,EAAA,QAAU,UAbFA,OAAA,IAmBAD,OACRA,EAAA,UAAY,YACZA,EAAA,KAAO,OACPA,EAAA,KAAO,OAHCA,OAAA,IASAD,OACRA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,yBAA2B,2BAC3BA,EAAA,QAAU,UANFA,OAAA","names":["webhook_exports","__export","EventField","MessageStatus","MessageType","__toCommonJS"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/webhook.ts"],"sourcesContent":["/**\n * Represents a message received through the webhook\n * Based on Meta's documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#messages-object\n */\nexport interface WebhookMessage {\n /**\n * The message ID\n */\n id: string;\n\n /**\n * The sender's phone number\n */\n from: string;\n\n /**\n * The timestamp of the message\n */\n timestamp: string;\n\n /**\n * The type of message (text, image, etc.)\n */\n type: MessageType;\n\n /**\n * The phone number ID that received the message\n */\n phoneNumberId: string;\n\n /**\n * Text object for text messages\n */\n text?: {\n /**\n * The text content of the message\n */\n body: string;\n };\n\n /**\n * Image object for image messages\n */\n image?: {\n /**\n * The image caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the image\n */\n sha256?: string;\n /**\n * The ID for the image\n */\n id: string;\n /**\n * The MIME type of the image\n */\n mime_type: string;\n };\n\n /**\n * Video object for video messages\n */\n video?: {\n /**\n * The video caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the video\n */\n sha256?: string;\n /**\n * The ID for the video\n */\n id: string;\n /**\n * The MIME type of the video\n */\n mime_type: string;\n };\n\n /**\n * Audio object for audio messages\n */\n audio?: {\n /**\n * The ID for the audio file\n */\n id: string;\n /**\n * The MIME type of the audio file\n */\n mime_type: string;\n /**\n * Whether the audio is a voice message\n */\n voice?: boolean;\n };\n\n /**\n * Document object for document messages\n */\n document?: {\n /**\n * The document caption (if provided)\n */\n caption?: string;\n /**\n * The document filename\n */\n filename: string;\n /**\n * The SHA256 hash of the document\n */\n sha256?: string;\n /**\n * The ID for the document\n */\n id: string;\n /**\n * The MIME type of the document\n */\n mime_type: string;\n };\n\n /**\n * Sticker object for sticker messages\n */\n sticker?: {\n /**\n * The ID for the sticker\n */\n id: string;\n /**\n * Whether this is an animated sticker\n */\n animated: boolean;\n /**\n * The MIME type of the sticker\n */\n mime_type: string;\n };\n\n /**\n * Contacts object for contact messages\n */\n contacts?: Array<{\n /**\n * The contact's name\n */\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n middle_name?: string;\n suffix?: string;\n prefix?: string;\n };\n /**\n * The contact's phone numbers\n */\n phones?: Array<{\n phone: string;\n type?: string;\n wa_id?: string;\n }>;\n /**\n * The contact's emails\n */\n emails?: Array<{\n email: string;\n type?: string;\n }>;\n /**\n * The contact's addresses\n */\n addresses?: Array<{\n street?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n country_code?: string;\n type?: string;\n }>;\n /**\n * The contact's organizations\n */\n org?: {\n company?: string;\n department?: string;\n title?: string;\n };\n /**\n * The contact's URLs\n */\n urls?: Array<{\n url: string;\n type?: string;\n }>;\n /**\n * The contact's birthday (YYYY-MM-DD format)\n */\n birthday?: string;\n }>;\n\n /**\n * Location object for location messages\n */\n location?: {\n /**\n * Latitude of the location\n */\n latitude: number;\n /**\n * Longitude of the location\n */\n longitude: number;\n /**\n * Name of the location\n */\n name?: string;\n /**\n * Address of the location\n */\n address?: string;\n };\n\n /**\n * Interactive object for interactive messages\n */\n interactive?: {\n /**\n * Type of the interactive message\n */\n type: string;\n /**\n * ID for the button that was clicked\n */\n button_reply?: {\n id: string;\n title: string;\n };\n /**\n * ID for the list item that was selected\n */\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n };\n\n /**\n * System object for system messages (like user phone number changes)\n */\n system?: {\n /**\n * The type of system update\n */\n type: string;\n /**\n * User's identity if the update is a customer identity change\n */\n identity?: string;\n /**\n * Old and new phone numbers if the update is a phone number change\n */\n customer?: {\n /**\n * The previous phone number\n */\n previous_wa_id: string;\n /**\n * The new phone number\n */\n wa_id: string;\n };\n };\n\n /**\n * Order object for order messages\n */\n order?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product items in the order\n */\n product_items: Array<{\n /**\n * Product ID\n */\n product_retailer_id: string;\n /**\n * Quantity of the product\n */\n quantity: number;\n /**\n * Item price\n */\n item_price: number;\n /**\n * Currency code\n */\n currency: string;\n }>;\n /**\n * Text message included with the order\n */\n text?: string;\n };\n\n /**\n * Context object, included when a user replies or interacts\n */\n context?: {\n /**\n * ID of the message being replied to or interacted with\n */\n message_id: string;\n /**\n * ID of the forwarded message, if applicable\n */\n forwarded?: boolean;\n /**\n * Frequently forwarded status\n */\n frequently_forwarded?: boolean;\n /**\n * Original message information if the message was referred\n */\n referred_product?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product ID\n */\n product_retailer_id: string;\n };\n };\n\n /**\n * Errors array, if the message had errors\n */\n errors?: Array<{\n /**\n * Error code\n */\n code: number;\n /**\n * Error title\n */\n title: string;\n /**\n * Error message\n */\n message: string;\n /**\n * Error details object\n */\n error_data?: {\n /**\n * Describes the error details\n */\n details: string;\n };\n }>;\n\n /**\n * Button object for button messages\n */\n button?: {\n /**\n * The payload for the button\n */\n payload: string;\n /**\n * Button text\n */\n text: string;\n };\n\n /**\n * The original message data as received from the webhook\n */\n originalData: any;\n}\n\n/**\n * Represents a non-message event received through the webhook\n */\nexport interface WebhookEvent {\n /**\n * The field type of the event\n */\n field: string;\n\n /**\n * The event data\n */\n value: any;\n}\n\n/**\n * Configuration for the webhook handler\n */\nexport interface WebhookConfig {\n /**\n * The URL path to listen on\n */\n path?: string;\n\n /**\n * The verification token for the webhook\n */\n verifyToken: string;\n\n /**\n * The public URL for the webhook\n */\n callbackUrl: string;\n}\n\n/**\n * Handler function for processing messages\n */\nexport type MessageHandler = (message: WebhookMessage) => void | Promise<void>;\n\n/**\n * Handler function for processing events\n */\nexport type EventHandler = (event: WebhookEvent) => void | Promise<void>;\n\n/**\n * Message types that can be received through the webhook\n */\nexport enum MessageType {\n TEXT = 'text',\n IMAGE = 'image',\n AUDIO = 'audio',\n VIDEO = 'video',\n DOCUMENT = 'document',\n STICKER = 'sticker',\n LOCATION = 'location',\n CONTACTS = 'contacts',\n BUTTON = 'button',\n INTERACTIVE = 'interactive',\n ORDER = 'order',\n SYSTEM = 'system',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Statuses that can be received in status updates\n */\nexport enum MessageStatus {\n DELIVERED = 'delivered',\n READ = 'read',\n SENT = 'sent',\n}\n\n/**\n * Event fields that can be received through the webhook\n */\nexport enum EventField {\n MESSAGES = 'messages',\n STATUSES = 'statuses',\n MESSAGE_TEMPLATE_STATUS_UPDATE = 'message_template_status_update',\n PHONE_NUMBER_QUALITY_UPDATE = 'phone_number_quality_update',\n PHONE_NUMBER_NAME_UPDATE = 'phone_number_name_update',\n UNKNOWN = 'unknown',\n}\n"],"mappings":"AA4bO,IAAKA,OACRA,EAAA,KAAO,OACPA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,OAAS,SACTA,EAAA,YAAc,cACdA,EAAA,MAAQ,QACRA,EAAA,OAAS,SACTA,EAAA,QAAU,UAbFA,OAAA,IAmBAC,OACRA,EAAA,UAAY,YACZA,EAAA,KAAO,OACPA,EAAA,KAAO,OAHCA,OAAA,IASAC,OACRA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,yBAA2B,2BAC3BA,EAAA,QAAU,UANFA,OAAA","names":["MessageType","MessageStatus","EventField"]}
|
|
1
|
+
{"version":3,"sources":["../../src/types/webhook.ts"],"sourcesContent":["/**\n * Represents a message received through the webhook\n * Based on Meta's documentation: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#messages-object\n */\nexport interface WebhookMessage {\n /**\n * The message ID\n */\n id: string;\n\n /**\n * The sender's phone number\n */\n from: string;\n\n /**\n * The timestamp of the message\n */\n timestamp: string;\n\n /**\n * The type of message (text, image, etc.)\n */\n type: MessageType;\n\n /**\n * The phone number ID that received the message\n */\n phoneNumberId: string;\n\n /**\n * Text object for text messages\n */\n text?: {\n /**\n * The text content of the message\n */\n body: string;\n };\n\n /**\n * Image object for image messages\n */\n image?: {\n /**\n * The image caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the image\n */\n sha256?: string;\n /**\n * The ID for the image\n */\n id: string;\n /**\n * The MIME type of the image\n */\n mime_type: string;\n };\n\n /**\n * Video object for video messages\n */\n video?: {\n /**\n * The video caption (if provided)\n */\n caption?: string;\n /**\n * The SHA256 hash of the video\n */\n sha256?: string;\n /**\n * The ID for the video\n */\n id: string;\n /**\n * The MIME type of the video\n */\n mime_type: string;\n };\n\n /**\n * Audio object for audio messages\n */\n audio?: {\n /**\n * The ID for the audio file\n */\n id: string;\n /**\n * The MIME type of the audio file\n */\n mime_type: string;\n /**\n * Whether the audio is a voice message\n */\n voice?: boolean;\n };\n\n /**\n * Document object for document messages\n */\n document?: {\n /**\n * The document caption (if provided)\n */\n caption?: string;\n /**\n * The document filename\n */\n filename: string;\n /**\n * The SHA256 hash of the document\n */\n sha256?: string;\n /**\n * The ID for the document\n */\n id: string;\n /**\n * The MIME type of the document\n */\n mime_type: string;\n };\n\n /**\n * Sticker object for sticker messages\n */\n sticker?: {\n /**\n * The ID for the sticker\n */\n id: string;\n /**\n * Whether this is an animated sticker\n */\n animated: boolean;\n /**\n * The MIME type of the sticker\n */\n mime_type: string;\n };\n\n /**\n * Contacts object for contact messages\n */\n contacts?: Array<{\n /**\n * The contact's name\n */\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n middle_name?: string;\n suffix?: string;\n prefix?: string;\n };\n /**\n * The contact's phone numbers\n */\n phones?: Array<{\n phone: string;\n type?: string;\n wa_id?: string;\n }>;\n /**\n * The contact's emails\n */\n emails?: Array<{\n email: string;\n type?: string;\n }>;\n /**\n * The contact's addresses\n */\n addresses?: Array<{\n street?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n country_code?: string;\n type?: string;\n }>;\n /**\n * The contact's organizations\n */\n org?: {\n company?: string;\n department?: string;\n title?: string;\n };\n /**\n * The contact's URLs\n */\n urls?: Array<{\n url: string;\n type?: string;\n }>;\n /**\n * The contact's birthday (YYYY-MM-DD format)\n */\n birthday?: string;\n }>;\n\n /**\n * Location object for location messages\n */\n location?: {\n /**\n * Latitude of the location\n */\n latitude: number;\n /**\n * Longitude of the location\n */\n longitude: number;\n /**\n * Name of the location\n */\n name?: string;\n /**\n * Address of the location\n */\n address?: string;\n };\n\n /**\n * Interactive object for interactive messages\n */\n interactive?: {\n /**\n * Type of the interactive message\n */\n type: string;\n /**\n * ID for the button that was clicked\n */\n button_reply?: {\n id: string;\n title: string;\n };\n /**\n * ID for the list item that was selected\n */\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n };\n\n /**\n * System object for system messages (like user phone number changes)\n */\n system?: {\n /**\n * The type of system update\n */\n type: string;\n /**\n * User's identity if the update is a customer identity change\n */\n identity?: string;\n /**\n * Old and new phone numbers if the update is a phone number change\n */\n customer?: {\n /**\n * The previous phone number\n */\n previous_wa_id: string;\n /**\n * The new phone number\n */\n wa_id: string;\n };\n };\n\n /**\n * Order object for order messages\n */\n order?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product items in the order\n */\n product_items: Array<{\n /**\n * Product ID\n */\n product_retailer_id: string;\n /**\n * Quantity of the product\n */\n quantity: number;\n /**\n * Item price\n */\n item_price: number;\n /**\n * Currency code\n */\n currency: string;\n }>;\n /**\n * Text message included with the order\n */\n text?: string;\n };\n\n /**\n * Context object, included when a user replies or interacts\n */\n context?: {\n /**\n * ID of the message being replied to or interacted with\n */\n message_id: string;\n /**\n * ID of the forwarded message, if applicable\n */\n forwarded?: boolean;\n /**\n * Frequently forwarded status\n */\n frequently_forwarded?: boolean;\n /**\n * Original message information if the message was referred\n */\n referred_product?: {\n /**\n * Catalog ID\n */\n catalog_id: string;\n /**\n * Product ID\n */\n product_retailer_id: string;\n };\n };\n\n /**\n * Errors array, if the message had errors\n */\n errors?: Array<{\n /**\n * Error code\n */\n code: number;\n /**\n * Error title\n */\n title: string;\n /**\n * Error message\n */\n message: string;\n /**\n * Error details object\n */\n error_data?: {\n /**\n * Describes the error details\n */\n details: string;\n };\n }>;\n\n /**\n * Button object for button messages\n */\n button?: {\n /**\n * The payload for the button\n */\n payload: string;\n /**\n * Button text\n */\n text: string;\n };\n\n /**\n * The original message data as received from the webhook\n */\n originalData: any;\n}\n\n/**\n * Represents a non-message event received through the webhook\n */\nexport interface WebhookEvent {\n /**\n * The field type of the event\n */\n field: string;\n\n /**\n * The event data\n */\n value: any;\n}\n\n/**\n * Handler function for processing messages\n */\nexport type MessageHandler = (message: WebhookMessage) => void | Promise<void>;\n\n/**\n * Handler function for processing events\n */\nexport type EventHandler = (event: WebhookEvent) => void | Promise<void>;\n\n/**\n * Message types that can be received through the webhook\n */\nexport enum MessageType {\n TEXT = 'text',\n IMAGE = 'image',\n AUDIO = 'audio',\n VIDEO = 'video',\n DOCUMENT = 'document',\n STICKER = 'sticker',\n LOCATION = 'location',\n CONTACTS = 'contacts',\n BUTTON = 'button',\n INTERACTIVE = 'interactive',\n ORDER = 'order',\n SYSTEM = 'system',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Statuses that can be received in status updates\n */\nexport enum MessageStatus {\n DELIVERED = 'delivered',\n READ = 'read',\n SENT = 'sent',\n}\n\n/**\n * Event fields that can be received through the webhook\n */\nexport enum EventField {\n MESSAGES = 'messages',\n STATUSES = 'statuses',\n MESSAGE_TEMPLATE_STATUS_UPDATE = 'message_template_status_update',\n PHONE_NUMBER_QUALITY_UPDATE = 'phone_number_quality_update',\n PHONE_NUMBER_NAME_UPDATE = 'phone_number_name_update',\n UNKNOWN = 'unknown',\n}\n"],"mappings":"AAwaO,IAAKA,OACRA,EAAA,KAAO,OACPA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,MAAQ,QACRA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,OAAS,SACTA,EAAA,YAAc,cACdA,EAAA,MAAQ,QACRA,EAAA,OAAS,SACTA,EAAA,QAAU,UAbFA,OAAA,IAmBAC,OACRA,EAAA,UAAY,YACZA,EAAA,KAAO,OACPA,EAAA,KAAO,OAHCA,OAAA,IASAC,OACRA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,yBAA2B,2BAC3BA,EAAA,QAAU,UANFA,OAAA","names":["MessageType","MessageStatus","EventField"]}
|
package/dist/webhook.d.mts
CHANGED
|
@@ -2,72 +2,43 @@ import { WabaConfigType } from './types/config.mjs';
|
|
|
2
2
|
import { WebhookMessage, WebhookEvent } from './types/webhook.mjs';
|
|
3
3
|
import './enums-D7paGoTY.mjs';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Generic HTTP request interface that works across frameworks
|
|
7
|
-
*/
|
|
8
5
|
interface IRequest {
|
|
9
6
|
body: any;
|
|
10
|
-
query: Record<string, any
|
|
11
|
-
|
|
7
|
+
query: Record<string, any> | Partial<{
|
|
8
|
+
[key: string]: string | string[];
|
|
9
|
+
}>;
|
|
10
|
+
method?: string;
|
|
12
11
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Generic HTTP response interface that works across frameworks
|
|
15
|
-
*/
|
|
16
12
|
interface IResponse {
|
|
17
13
|
status: (code: number) => IResponse;
|
|
18
14
|
send: (body: any) => IResponse | void;
|
|
19
15
|
json: (body: any) => IResponse | void;
|
|
20
16
|
end: () => void;
|
|
21
17
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Express adapter for the WebhookHandler
|
|
24
|
-
*/
|
|
25
|
-
declare const expressAdapter: {
|
|
26
|
-
createRequest: (req: any) => IRequest;
|
|
27
|
-
createResponse: (res: any) => IResponse;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Next.js adapter for the WebhookHandler
|
|
31
|
-
*/
|
|
32
|
-
declare const nextJsAdapter: {
|
|
33
|
-
createRequest: (req: any) => IRequest;
|
|
34
|
-
createResponse: (res: any) => IResponse;
|
|
35
|
-
};
|
|
36
18
|
/**
|
|
37
19
|
* Webhook handler for WhatsApp Cloud API
|
|
38
20
|
*/
|
|
39
21
|
declare class WebhookHandler {
|
|
40
|
-
private server?;
|
|
41
22
|
private config;
|
|
42
|
-
private callbackUrl;
|
|
43
|
-
private verifyToken;
|
|
44
23
|
private messageHandlers;
|
|
45
24
|
private eventHandlers;
|
|
46
25
|
/**
|
|
47
26
|
* Create a new WebhookHandler
|
|
48
27
|
* @param config The WhatsApp configuration
|
|
49
|
-
* @param callbackUrl The public URL for the webhook
|
|
50
|
-
* @param verifyToken The verification token for the webhook
|
|
51
28
|
*/
|
|
52
|
-
constructor(config: WabaConfigType
|
|
29
|
+
constructor(config: WabaConfigType);
|
|
53
30
|
/**
|
|
54
31
|
* Handle a GET request for webhook verification
|
|
55
32
|
*/
|
|
56
|
-
handleVerificationRequest(req:
|
|
33
|
+
handleVerificationRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): void;
|
|
57
34
|
/**
|
|
58
35
|
* Handle a POST request for webhook events
|
|
59
36
|
*/
|
|
60
|
-
handleWebhookRequest(req:
|
|
37
|
+
handleWebhookRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): Promise<void>;
|
|
61
38
|
/**
|
|
62
39
|
* Handle webhook requests (both verification and events)
|
|
63
40
|
*/
|
|
64
41
|
handleRequest(req: IRequest, res: IResponse): void | Promise<void>;
|
|
65
|
-
/**
|
|
66
|
-
* Initialize the webhook with an Express app (legacy support)
|
|
67
|
-
* @param app Express application instance
|
|
68
|
-
* @param path The path to listen on, defaults to /webhook
|
|
69
|
-
*/
|
|
70
|
-
initialize(app: any, path?: string): void;
|
|
71
42
|
/**
|
|
72
43
|
* Process incoming messages
|
|
73
44
|
*/
|
|
@@ -90,4 +61,4 @@ declare class WebhookHandler {
|
|
|
90
61
|
onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void;
|
|
91
62
|
}
|
|
92
63
|
|
|
93
|
-
export { type IRequest, type IResponse, WebhookHandler as default
|
|
64
|
+
export { type IRequest, type IResponse, WebhookHandler as default };
|
package/dist/webhook.d.ts
CHANGED
|
@@ -2,72 +2,43 @@ import { WabaConfigType } from './types/config.js';
|
|
|
2
2
|
import { WebhookMessage, WebhookEvent } from './types/webhook.js';
|
|
3
3
|
import './enums-D7paGoTY.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Generic HTTP request interface that works across frameworks
|
|
7
|
-
*/
|
|
8
5
|
interface IRequest {
|
|
9
6
|
body: any;
|
|
10
|
-
query: Record<string, any
|
|
11
|
-
|
|
7
|
+
query: Record<string, any> | Partial<{
|
|
8
|
+
[key: string]: string | string[];
|
|
9
|
+
}>;
|
|
10
|
+
method?: string;
|
|
12
11
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Generic HTTP response interface that works across frameworks
|
|
15
|
-
*/
|
|
16
12
|
interface IResponse {
|
|
17
13
|
status: (code: number) => IResponse;
|
|
18
14
|
send: (body: any) => IResponse | void;
|
|
19
15
|
json: (body: any) => IResponse | void;
|
|
20
16
|
end: () => void;
|
|
21
17
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Express adapter for the WebhookHandler
|
|
24
|
-
*/
|
|
25
|
-
declare const expressAdapter: {
|
|
26
|
-
createRequest: (req: any) => IRequest;
|
|
27
|
-
createResponse: (res: any) => IResponse;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Next.js adapter for the WebhookHandler
|
|
31
|
-
*/
|
|
32
|
-
declare const nextJsAdapter: {
|
|
33
|
-
createRequest: (req: any) => IRequest;
|
|
34
|
-
createResponse: (res: any) => IResponse;
|
|
35
|
-
};
|
|
36
18
|
/**
|
|
37
19
|
* Webhook handler for WhatsApp Cloud API
|
|
38
20
|
*/
|
|
39
21
|
declare class WebhookHandler {
|
|
40
|
-
private server?;
|
|
41
22
|
private config;
|
|
42
|
-
private callbackUrl;
|
|
43
|
-
private verifyToken;
|
|
44
23
|
private messageHandlers;
|
|
45
24
|
private eventHandlers;
|
|
46
25
|
/**
|
|
47
26
|
* Create a new WebhookHandler
|
|
48
27
|
* @param config The WhatsApp configuration
|
|
49
|
-
* @param callbackUrl The public URL for the webhook
|
|
50
|
-
* @param verifyToken The verification token for the webhook
|
|
51
28
|
*/
|
|
52
|
-
constructor(config: WabaConfigType
|
|
29
|
+
constructor(config: WabaConfigType);
|
|
53
30
|
/**
|
|
54
31
|
* Handle a GET request for webhook verification
|
|
55
32
|
*/
|
|
56
|
-
handleVerificationRequest(req:
|
|
33
|
+
handleVerificationRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): void;
|
|
57
34
|
/**
|
|
58
35
|
* Handle a POST request for webhook events
|
|
59
36
|
*/
|
|
60
|
-
handleWebhookRequest(req:
|
|
37
|
+
handleWebhookRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): Promise<void>;
|
|
61
38
|
/**
|
|
62
39
|
* Handle webhook requests (both verification and events)
|
|
63
40
|
*/
|
|
64
41
|
handleRequest(req: IRequest, res: IResponse): void | Promise<void>;
|
|
65
|
-
/**
|
|
66
|
-
* Initialize the webhook with an Express app (legacy support)
|
|
67
|
-
* @param app Express application instance
|
|
68
|
-
* @param path The path to listen on, defaults to /webhook
|
|
69
|
-
*/
|
|
70
|
-
initialize(app: any, path?: string): void;
|
|
71
42
|
/**
|
|
72
43
|
* Process incoming messages
|
|
73
44
|
*/
|
|
@@ -90,4 +61,4 @@ declare class WebhookHandler {
|
|
|
90
61
|
onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void;
|
|
91
62
|
}
|
|
92
63
|
|
|
93
|
-
export { type IRequest, type IResponse, WebhookHandler as default
|
|
64
|
+
export { type IRequest, type IResponse, WebhookHandler as default };
|
package/dist/webhook.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var b=(o,e)=>{for(var t in e)l(o,t,{get:e[t],enumerable:!0})},f=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of u(e))!h.call(o,n)&&n!==t&&l(o,n,{get:()=>e[n],enumerable:!(r=p(e,n))||r.enumerable});return o};var y=o=>f(l({},"__esModule",{value:!0}),o);var _={};b(_,{default:()=>m});module.exports=y(_);var c=class{name;debug;constructor(e,t=!1){this.name=e,this.debug=t}log(...e){if(this.debug){let t=`[ ${Date.now()} ]`;this.name&&(t+=` - ${this.name}`),console.log.apply(console,[t,": ",...e])}}error(...e){let t=`[ ${Date.now()} ] - ERROR`;this.name&&(t+=` - ${this.name}`),console.error.apply(console,[t,": ",...e])}warn(...e){let t=`[ ${Date.now()} ] - WARN`;this.name&&(t+=` - ${this.name}`),console.warn.apply(console,[t,": ",...e])}info(...e){let t=`[ ${Date.now()} ] - INFO`;this.name&&(t+=` - ${this.name}`),console.info.apply(console,[t,": ",...e])}};var v="WEBHOOK",E=!1,d=new c(v,process.env.DEBUG==="true"||E),m=class{config;messageHandlers=new Map;eventHandlers=new Map;constructor(e){this.config=e,d.log("WebhookHandler instantiated!")}handleVerificationRequest(e,t){let r=e.query["hub.mode"],n=e.query["hub.verify_token"],s=e.query["hub.challenge"];r==="subscribe"&&n===this.config.WEBHOOK_VERIFICATION_TOKEN?(d.log("Webhook verified successfully"),t.status(200).send(s)):(d.log("Webhook verification failed"),t.status(403).end())}async handleWebhookRequest(e,t){let r=e.body;if(r.object!=="whatsapp_business_account"){d.log("Received webhook for non-WhatsApp event"),t.status(404).end();return}for(let n of r.entry)try{let s=n.changes;for(let a of s)a.field==="messages"?await this.processMessages(a.value):await this.processEvent(a.field,a.value)}catch(s){d.log(`Error processing webhook: ${s}`)}t.status(200).end()}handleRequest(e,t){if(e.method==="GET")return this.handleVerificationRequest(e,t);if(e.method==="POST")return this.handleWebhookRequest(e,t);t.status(405).end()}async processMessages(e){let r=e.metadata.phone_number_id,n=e.messages;if(n&&n.length>0)for(let s of n){let a=s.type,i={id:s.id,from:s.from,timestamp:s.timestamp,type:a,phoneNumberId:r,originalData:s};switch(a){case"text":i.text=s.text;break;case"image":i.image=s.image;break;case"video":i.video=s.video;break;case"audio":i.audio=s.audio;break;case"document":i.document=s.document;break;case"sticker":i.sticker=s.sticker;break;case"location":i.location=s.location;break;case"contacts":i.contacts=s.contacts;break;case"interactive":i.interactive=s.interactive;break;case"button":i.button=s.button;break;case"order":i.order=s.order;break;case"system":i.system=s.system;break;default:break}if(s.context&&(i.context=s.context),s.errors&&(i.errors=s.errors),this.messageHandlers.has(a)){let g=this.messageHandlers.get(a);g&&await Promise.resolve(g(i))}if(this.messageHandlers.has("*")){let g=this.messageHandlers.get("*");g&&await Promise.resolve(g(i))}}e.statuses&&e.statuses.length>0&&await this.processEvent("statuses",e)}async processEvent(e,t){let r={field:e,value:t};if(this.eventHandlers.has(e)){let n=this.eventHandlers.get(e);n&&await Promise.resolve(n(r))}if(this.eventHandlers.has("*")){let n=this.eventHandlers.get("*");n&&await Promise.resolve(n(r))}}onMessage(e,t){this.messageHandlers.set(e,t),d.log(`Registered handler for message type: ${e}`)}onEvent(e,t){this.eventHandlers.set(e,t),d.log(`Registered handler for event field: ${e}`)}};
|
|
2
2
|
//# sourceMappingURL=webhook.js.map
|
package/dist/webhook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhook.ts","../src/utils/logger.ts"],"sourcesContent":["import { Server } from 'http';\nimport { WabaConfigType } from './types/config';\n\nimport { EventField, MessageType, WebhookEvent, WebhookMessage } from './types/webhook';\nimport Logger from './utils/logger';\n\nconst LIB_NAME = 'WEBHOOK';\nconst LOG_LOCAL = false;\nconst LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);\n\n/**\n * Generic HTTP request interface that works across frameworks\n */\nexport interface IRequest {\n body: any;\n query: Record<string, any>;\n method: string;\n}\n\n/**\n * Generic HTTP response interface that works across frameworks\n */\nexport interface IResponse {\n status: (code: number) => IResponse;\n send: (body: any) => IResponse | void;\n json: (body: any) => IResponse | void;\n end: () => void;\n}\n\n/**\n * Express adapter for the WebhookHandler\n */\nexport const expressAdapter = {\n createRequest: (req: any): IRequest => ({\n body: req.body,\n query: req.query,\n method: req.method,\n }),\n createResponse: (res: any): IResponse => ({\n status: (code: number) => {\n res.status(code);\n return res;\n },\n send: (body: any) => res.send(body),\n json: (body: any) => res.json(body),\n end: () => res.end(),\n }),\n};\n\n/**\n * Next.js adapter for the WebhookHandler\n */\nexport const nextJsAdapter = {\n createRequest: (req: any): IRequest => ({\n body: req.body,\n query: req.query,\n method: req.method,\n }),\n createResponse: (res: any): IResponse => ({\n status: (code: number) => {\n res.status(code);\n return res;\n },\n send: (body: any) => res.send(body),\n json: (body: any) => res.json(body),\n end: () => res.end(),\n }),\n};\n\n/**\n * Webhook handler for WhatsApp Cloud API\n */\nexport default class WebhookHandler {\n private server?: Server;\n private config: WabaConfigType;\n private callbackUrl: string;\n private verifyToken: string;\n private messageHandlers: Map<string, (message: WebhookMessage) => void | Promise<void>> = new Map();\n private eventHandlers: Map<string, (event: WebhookEvent) => void | Promise<void>> = new Map();\n\n /**\n * Create a new WebhookHandler\n * @param config The WhatsApp configuration\n * @param callbackUrl The public URL for the webhook\n * @param verifyToken The verification token for the webhook\n */\n constructor(config: WabaConfigType, callbackUrl: string, verifyToken: string) {\n this.config = config;\n this.callbackUrl = callbackUrl;\n this.verifyToken = verifyToken;\n LOGGER.log('WebhookHandler instantiated!');\n }\n\n /**\n * Handle a GET request for webhook verification\n */\n public handleVerificationRequest(req: IRequest, res: IResponse): void {\n const mode = req.query['hub.mode'];\n const token = req.query['hub.verify_token'];\n const challenge = req.query['hub.challenge'];\n\n if (mode === 'subscribe' && token === this.verifyToken) {\n LOGGER.log('Webhook verified successfully');\n res.status(200).send(challenge);\n } else {\n LOGGER.log('Webhook verification failed');\n res.status(403).end();\n }\n }\n\n /**\n * Handle a POST request for webhook events\n */\n public async handleWebhookRequest(req: IRequest, res: IResponse): Promise<void> {\n const body = req.body;\n\n // Check this is a WhatsApp Business Account webhook\n if (body.object !== 'whatsapp_business_account') {\n LOGGER.log('Received webhook for non-WhatsApp event');\n res.status(404).end();\n return;\n }\n\n // Process each entry\n for (const entry of body.entry) {\n try {\n const changes = entry.changes;\n for (const change of changes) {\n if (change.field === EventField.MESSAGES) {\n await this.processMessages(change.value);\n } else {\n // Handle other event types\n await this.processEvent(change.field, change.value);\n }\n }\n } catch (error) {\n LOGGER.log(`Error processing webhook: ${error}`);\n }\n }\n\n // Always respond with 200 to acknowledge receipt\n res.status(200).end();\n }\n\n /**\n * Handle webhook requests (both verification and events)\n */\n public handleRequest(req: IRequest, res: IResponse): void | Promise<void> {\n if (req.method === 'GET') {\n return this.handleVerificationRequest(req, res);\n } else if (req.method === 'POST') {\n return this.handleWebhookRequest(req, res);\n } else {\n res.status(405).end(); // Method not allowed\n }\n }\n\n /**\n * Initialize the webhook with an Express app (legacy support)\n * @param app Express application instance\n * @param path The path to listen on, defaults to /webhook\n */\n public initialize(app: any, path: string = '/webhook'): void {\n // Set up middleware to handle requests\n app.all(path, async (req: any, res: any) => {\n const request = expressAdapter.createRequest(req);\n const response = expressAdapter.createResponse(res);\n await this.handleRequest(request, response);\n });\n\n LOGGER.log(`Webhook initialized at path: ${path}`);\n }\n\n /**\n * Process incoming messages\n */\n private async processMessages(value: any): Promise<void> {\n // Extract metadata\n const metadata = value.metadata;\n const phoneNumberId = metadata.phone_number_id;\n\n // Process messages if present\n if (value.messages && value.messages.length > 0) {\n for (const message of value.messages) {\n const messageType = message.type as MessageType;\n\n // Create the base message object\n const processedMessage: WebhookMessage = {\n id: message.id,\n from: message.from,\n timestamp: message.timestamp,\n type: messageType,\n phoneNumberId,\n originalData: message,\n };\n\n // Add type-specific data based on the message type\n switch (messageType) {\n case MessageType.TEXT:\n processedMessage.text = message.text;\n break;\n case MessageType.IMAGE:\n processedMessage.image = message.image;\n break;\n case MessageType.VIDEO:\n processedMessage.video = message.video;\n break;\n case MessageType.AUDIO:\n processedMessage.audio = message.audio;\n break;\n case MessageType.DOCUMENT:\n processedMessage.document = message.document;\n break;\n case MessageType.STICKER:\n processedMessage.sticker = message.sticker;\n break;\n case MessageType.LOCATION:\n processedMessage.location = message.location;\n break;\n case MessageType.CONTACTS:\n processedMessage.contacts = message.contacts;\n break;\n case MessageType.INTERACTIVE:\n processedMessage.interactive = message.interactive;\n break;\n case MessageType.BUTTON:\n processedMessage.button = message.button;\n break;\n case MessageType.ORDER:\n processedMessage.order = message.order;\n break;\n case MessageType.SYSTEM:\n processedMessage.system = message.system;\n break;\n default:\n // Unknown message type\n break;\n }\n\n // Add context if available\n if (message.context) {\n processedMessage.context = message.context;\n }\n\n // Add errors if available\n if (message.errors) {\n processedMessage.errors = message.errors;\n }\n\n // Dispatch to appropriate message handler\n if (this.messageHandlers.has(messageType)) {\n const handler = this.messageHandlers.get(messageType);\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n\n // Also dispatch to general message handler if exists\n if (this.messageHandlers.has('*')) {\n const handler = this.messageHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n }\n }\n\n // Process status messages if present\n if (value.statuses && value.statuses.length > 0) {\n // Process as events\n await this.processEvent(EventField.STATUSES, value);\n }\n }\n\n /**\n * Process other webhook events\n */\n private async processEvent(field: string, value: any): Promise<void> {\n const event: WebhookEvent = {\n field,\n value,\n };\n\n // Dispatch to appropriate event handler\n if (this.eventHandlers.has(field)) {\n const handler = this.eventHandlers.get(field);\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n\n // Also dispatch to general event handler if exists\n if (this.eventHandlers.has('*')) {\n const handler = this.eventHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n }\n\n /**\n * Register a message handler for a specific message type\n * @param type Message type to handle, or '*' for all types\n * @param handler The handler function\n */\n public onMessage(type: string, handler: (message: WebhookMessage) => void | Promise<void>): void {\n this.messageHandlers.set(type, handler);\n LOGGER.log(`Registered handler for message type: ${type}`);\n }\n\n /**\n * Register a general event handler\n * @param field Event field to handle, or '*' for all fields\n * @param handler The handler function\n */\n public onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void {\n this.eventHandlers.set(field, handler);\n LOGGER.log(`Registered handler for event field: ${field}`);\n }\n}\n","// @ts-nocheck\nimport type { LoggerInterface } from '../types/logger';\n\nexport default class Logger implements LoggerInterface {\n private name: string;\n private debug: boolean;\n\n constructor(name: string, debug: boolean = false) {\n this.name = name;\n this.debug = debug;\n }\n\n log(...data: any[]) {\n if (this.debug) {\n let prefix = `[ ${Date.now()} ]`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.log.apply(console, [prefix, ': ', ...data]);\n }\n }\n\n error(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - ERROR`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.error.apply(console, [prefix, ': ', ...data]);\n }\n\n warn(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - WARN`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.warn.apply(console, [prefix, ': ', ...data]);\n }\n\n info(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - INFO`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.info.apply(console, [prefix, ': ', ...data]);\n }\n}\n"],"mappings":"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","names":["webhook_exports","__export","WebhookHandler","expressAdapter","nextJsAdapter","__toCommonJS","Logger","name","debug","data","prefix","LIB_NAME","LOG_LOCAL","LOGGER","Logger","expressAdapter","req","res","code","body","nextJsAdapter","WebhookHandler","config","callbackUrl","verifyToken","mode","token","challenge","entry","changes","change","error","app","path","request","response","value","phoneNumberId","message","messageType","processedMessage","handler","field","event","type"]}
|
|
1
|
+
{"version":3,"sources":["../src/webhook.ts","../src/utils/logger.ts"],"sourcesContent":["import { WabaConfigType } from './types/config';\n\nimport { EventField, MessageType, WebhookEvent, WebhookMessage } from './types/webhook';\nimport Logger from './utils/logger';\n\nconst LIB_NAME = 'WEBHOOK';\nconst LOG_LOCAL = false;\nconst LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);\n\nexport interface IRequest {\n body: any;\n query:\n | Record<string, any>\n | Partial<{\n [key: string]: string | string[];\n }>;\n method?: string;\n}\nexport interface IResponse {\n status: (code: number) => IResponse;\n send: (body: any) => IResponse | void;\n json: (body: any) => IResponse | void;\n end: () => void;\n}\n\n/**\n * Webhook handler for WhatsApp Cloud API\n */\nexport default class WebhookHandler {\n private config: WabaConfigType;\n private messageHandlers: Map<string, (message: WebhookMessage) => void | Promise<void>> = new Map();\n private eventHandlers: Map<string, (event: WebhookEvent) => void | Promise<void>> = new Map();\n\n /**\n * Create a new WebhookHandler\n * @param config The WhatsApp configuration\n */\n constructor(config: WabaConfigType) {\n this.config = config;\n LOGGER.log('WebhookHandler instantiated!');\n }\n\n /**\n * Handle a GET request for webhook verification\n */\n public handleVerificationRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): void {\n const mode = req.query['hub.mode'];\n const token = req.query['hub.verify_token'];\n const challenge = req.query['hub.challenge'];\n\n if (mode === 'subscribe' && token === this.config.WEBHOOK_VERIFICATION_TOKEN) {\n LOGGER.log('Webhook verified successfully');\n res.status(200).send(challenge);\n } else {\n LOGGER.log('Webhook verification failed');\n res.status(403).end();\n }\n }\n\n /**\n * Handle a POST request for webhook events\n */\n public async handleWebhookRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): Promise<void> {\n const body = req.body;\n\n // Check this is a WhatsApp Business Account webhook\n if (body.object !== 'whatsapp_business_account') {\n LOGGER.log('Received webhook for non-WhatsApp event');\n res.status(404).end();\n return;\n }\n\n // Process each entry\n for (const entry of body.entry) {\n try {\n const changes = entry.changes;\n for (const change of changes) {\n if (change.field === EventField.MESSAGES) {\n await this.processMessages(change.value);\n } else {\n // Handle other event types\n await this.processEvent(change.field, change.value);\n }\n }\n } catch (error) {\n LOGGER.log(`Error processing webhook: ${error}`);\n }\n }\n\n // Always respond with 200 to acknowledge receipt\n res.status(200).end();\n }\n\n /**\n * Handle webhook requests (both verification and events)\n */\n public handleRequest(req: IRequest, res: IResponse): void | Promise<void> {\n if (req.method === 'GET') {\n return this.handleVerificationRequest(req, res);\n } else if (req.method === 'POST') {\n return this.handleWebhookRequest(req, res);\n } else {\n res.status(405).end(); // Method not allowed\n }\n }\n\n // /**\n // * Initialize the webhook with an Express app (legacy support)\n // * @param app Express application instance\n // * @param path The path to listen on, defaults to /webhook\n // */\n // public initialize(app: any, path: string = '/webhook'): void {\n // // Set up middleware to handle requests\n // app.all(path, async (req: any, res: any) => {\n // const request = expressAdapter.createRequest(req);\n // const response = expressAdapter.createResponse(res);\n // await this.handleRequest(request, response);\n // });\n\n // LOGGER.log(`Webhook initialized at path: ${path}`);\n // }\n\n /**\n * Process incoming messages\n */\n private async processMessages(value: any): Promise<void> {\n // Extract metadata\n const metadata = value.metadata;\n const phoneNumberId = metadata.phone_number_id;\n const messages = value.messages as WebhookMessage[];\n\n // Process messages if present\n if (messages && messages.length > 0) {\n for (const message of messages) {\n const messageType = message.type;\n\n // Create the base message object\n const processedMessage: WebhookMessage = {\n id: message.id,\n from: message.from,\n timestamp: message.timestamp,\n type: messageType,\n phoneNumberId,\n originalData: message,\n };\n\n // Add type-specific data based on the message type\n switch (messageType) {\n case MessageType.TEXT:\n processedMessage.text = message.text;\n break;\n case MessageType.IMAGE:\n processedMessage.image = message.image;\n break;\n case MessageType.VIDEO:\n processedMessage.video = message.video;\n break;\n case MessageType.AUDIO:\n processedMessage.audio = message.audio;\n break;\n case MessageType.DOCUMENT:\n processedMessage.document = message.document;\n break;\n case MessageType.STICKER:\n processedMessage.sticker = message.sticker;\n break;\n case MessageType.LOCATION:\n processedMessage.location = message.location;\n break;\n case MessageType.CONTACTS:\n processedMessage.contacts = message.contacts;\n break;\n case MessageType.INTERACTIVE:\n processedMessage.interactive = message.interactive;\n break;\n case MessageType.BUTTON:\n processedMessage.button = message.button;\n break;\n case MessageType.ORDER:\n processedMessage.order = message.order;\n break;\n case MessageType.SYSTEM:\n processedMessage.system = message.system;\n break;\n default:\n // Unknown message type\n break;\n }\n\n // Add context if available\n if (message.context) {\n processedMessage.context = message.context;\n }\n\n // Add errors if available\n if (message.errors) {\n processedMessage.errors = message.errors;\n }\n\n // Dispatch to appropriate message handler\n if (this.messageHandlers.has(messageType)) {\n const handler = this.messageHandlers.get(messageType);\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n\n // Also dispatch to general message handler if exists\n if (this.messageHandlers.has('*')) {\n const handler = this.messageHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n }\n }\n\n // Process status messages if present\n if (value.statuses && value.statuses.length > 0) {\n // Process as events\n await this.processEvent(EventField.STATUSES, value);\n }\n }\n\n /**\n * Process other webhook events\n */\n private async processEvent(field: string, value: any): Promise<void> {\n const event: WebhookEvent = {\n field,\n value,\n };\n\n // Dispatch to appropriate event handler\n if (this.eventHandlers.has(field)) {\n const handler = this.eventHandlers.get(field);\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n\n // Also dispatch to general event handler if exists\n if (this.eventHandlers.has('*')) {\n const handler = this.eventHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n }\n\n /**\n * Register a message handler for a specific message type\n * @param type Message type to handle, or '*' for all types\n * @param handler The handler function\n */\n public onMessage(type: string, handler: (message: WebhookMessage) => void | Promise<void>): void {\n this.messageHandlers.set(type, handler);\n LOGGER.log(`Registered handler for message type: ${type}`);\n }\n\n /**\n * Register a general event handler\n * @param field Event field to handle, or '*' for all fields\n * @param handler The handler function\n */\n public onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void {\n this.eventHandlers.set(field, handler);\n LOGGER.log(`Registered handler for event field: ${field}`);\n }\n}\n","// @ts-nocheck\nimport type { LoggerInterface } from '../types/logger';\n\nexport default class Logger implements LoggerInterface {\n private name: string;\n private debug: boolean;\n\n constructor(name: string, debug: boolean = false) {\n this.name = name;\n this.debug = debug;\n }\n\n log(...data: any[]) {\n if (this.debug) {\n let prefix = `[ ${Date.now()} ]`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.log.apply(console, [prefix, ': ', ...data]);\n }\n }\n\n error(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - ERROR`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.error.apply(console, [prefix, ': ', ...data]);\n }\n\n warn(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - WARN`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.warn.apply(console, [prefix, ': ', ...data]);\n }\n\n info(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - INFO`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.info.apply(console, [prefix, ': ', ...data]);\n }\n}\n"],"mappings":"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","names":["webhook_exports","__export","WebhookHandler","__toCommonJS","Logger","name","debug","data","prefix","LIB_NAME","LOG_LOCAL","LOGGER","Logger","WebhookHandler","config","req","res","mode","token","challenge","body","entry","changes","change","error","value","phoneNumberId","messages","message","messageType","processedMessage","handler","field","event","type"]}
|
package/dist/webhook.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var g=class{name;debug;constructor(e,t=!1){this.name=e,this.debug=t}log(...e){if(this.debug){let t=`[ ${Date.now()} ]`;this.name&&(t+=` - ${this.name}`),console.log.apply(console,[t,": ",...e])}}error(...e){let t=`[ ${Date.now()} ] - ERROR`;this.name&&(t+=` - ${this.name}`),console.error.apply(console,[t,": ",...e])}warn(...e){let t=`[ ${Date.now()} ] - WARN`;this.name&&(t+=` - ${this.name}`),console.warn.apply(console,[t,": ",...e])}info(...e){let t=`[ ${Date.now()} ] - INFO`;this.name&&(t+=` - ${this.name}`),console.info.apply(console,[t,": ",...e])}};var l="WEBHOOK",p=!1,a=new g(l,process.env.DEBUG==="true"||p),c=class{config;messageHandlers=new Map;eventHandlers=new Map;constructor(e){this.config=e,a.log("WebhookHandler instantiated!")}handleVerificationRequest(e,t){let r=e.query["hub.mode"],i=e.query["hub.verify_token"],s=e.query["hub.challenge"];r==="subscribe"&&i===this.config.WEBHOOK_VERIFICATION_TOKEN?(a.log("Webhook verified successfully"),t.status(200).send(s)):(a.log("Webhook verification failed"),t.status(403).end())}async handleWebhookRequest(e,t){let r=e.body;if(r.object!=="whatsapp_business_account"){a.log("Received webhook for non-WhatsApp event"),t.status(404).end();return}for(let i of r.entry)try{let s=i.changes;for(let o of s)o.field==="messages"?await this.processMessages(o.value):await this.processEvent(o.field,o.value)}catch(s){a.log(`Error processing webhook: ${s}`)}t.status(200).end()}handleRequest(e,t){if(e.method==="GET")return this.handleVerificationRequest(e,t);if(e.method==="POST")return this.handleWebhookRequest(e,t);t.status(405).end()}async processMessages(e){let r=e.metadata.phone_number_id,i=e.messages;if(i&&i.length>0)for(let s of i){let o=s.type,n={id:s.id,from:s.from,timestamp:s.timestamp,type:o,phoneNumberId:r,originalData:s};switch(o){case"text":n.text=s.text;break;case"image":n.image=s.image;break;case"video":n.video=s.video;break;case"audio":n.audio=s.audio;break;case"document":n.document=s.document;break;case"sticker":n.sticker=s.sticker;break;case"location":n.location=s.location;break;case"contacts":n.contacts=s.contacts;break;case"interactive":n.interactive=s.interactive;break;case"button":n.button=s.button;break;case"order":n.order=s.order;break;case"system":n.system=s.system;break;default:break}if(s.context&&(n.context=s.context),s.errors&&(n.errors=s.errors),this.messageHandlers.has(o)){let d=this.messageHandlers.get(o);d&&await Promise.resolve(d(n))}if(this.messageHandlers.has("*")){let d=this.messageHandlers.get("*");d&&await Promise.resolve(d(n))}}e.statuses&&e.statuses.length>0&&await this.processEvent("statuses",e)}async processEvent(e,t){let r={field:e,value:t};if(this.eventHandlers.has(e)){let i=this.eventHandlers.get(e);i&&await Promise.resolve(i(r))}if(this.eventHandlers.has("*")){let i=this.eventHandlers.get("*");i&&await Promise.resolve(i(r))}}onMessage(e,t){this.messageHandlers.set(e,t),a.log(`Registered handler for message type: ${e}`)}onEvent(e,t){this.eventHandlers.set(e,t),a.log(`Registered handler for event field: ${e}`)}};export{c as default};
|
|
2
2
|
//# sourceMappingURL=webhook.mjs.map
|
package/dist/webhook.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/logger.ts","../src/webhook.ts"],"sourcesContent":["// @ts-nocheck\nimport type { LoggerInterface } from '../types/logger';\n\nexport default class Logger implements LoggerInterface {\n private name: string;\n private debug: boolean;\n\n constructor(name: string, debug: boolean = false) {\n this.name = name;\n this.debug = debug;\n }\n\n log(...data: any[]) {\n if (this.debug) {\n let prefix = `[ ${Date.now()} ]`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.log.apply(console, [prefix, ': ', ...data]);\n }\n }\n\n error(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - ERROR`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.error.apply(console, [prefix, ': ', ...data]);\n }\n\n warn(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - WARN`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.warn.apply(console, [prefix, ': ', ...data]);\n }\n\n info(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - INFO`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.info.apply(console, [prefix, ': ', ...data]);\n }\n}\n","import { Server } from 'http';\nimport { WabaConfigType } from './types/config';\n\nimport { EventField, MessageType, WebhookEvent, WebhookMessage } from './types/webhook';\nimport Logger from './utils/logger';\n\nconst LIB_NAME = 'WEBHOOK';\nconst LOG_LOCAL = false;\nconst LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);\n\n/**\n * Generic HTTP request interface that works across frameworks\n */\nexport interface IRequest {\n body: any;\n query: Record<string, any>;\n method: string;\n}\n\n/**\n * Generic HTTP response interface that works across frameworks\n */\nexport interface IResponse {\n status: (code: number) => IResponse;\n send: (body: any) => IResponse | void;\n json: (body: any) => IResponse | void;\n end: () => void;\n}\n\n/**\n * Express adapter for the WebhookHandler\n */\nexport const expressAdapter = {\n createRequest: (req: any): IRequest => ({\n body: req.body,\n query: req.query,\n method: req.method,\n }),\n createResponse: (res: any): IResponse => ({\n status: (code: number) => {\n res.status(code);\n return res;\n },\n send: (body: any) => res.send(body),\n json: (body: any) => res.json(body),\n end: () => res.end(),\n }),\n};\n\n/**\n * Next.js adapter for the WebhookHandler\n */\nexport const nextJsAdapter = {\n createRequest: (req: any): IRequest => ({\n body: req.body,\n query: req.query,\n method: req.method,\n }),\n createResponse: (res: any): IResponse => ({\n status: (code: number) => {\n res.status(code);\n return res;\n },\n send: (body: any) => res.send(body),\n json: (body: any) => res.json(body),\n end: () => res.end(),\n }),\n};\n\n/**\n * Webhook handler for WhatsApp Cloud API\n */\nexport default class WebhookHandler {\n private server?: Server;\n private config: WabaConfigType;\n private callbackUrl: string;\n private verifyToken: string;\n private messageHandlers: Map<string, (message: WebhookMessage) => void | Promise<void>> = new Map();\n private eventHandlers: Map<string, (event: WebhookEvent) => void | Promise<void>> = new Map();\n\n /**\n * Create a new WebhookHandler\n * @param config The WhatsApp configuration\n * @param callbackUrl The public URL for the webhook\n * @param verifyToken The verification token for the webhook\n */\n constructor(config: WabaConfigType, callbackUrl: string, verifyToken: string) {\n this.config = config;\n this.callbackUrl = callbackUrl;\n this.verifyToken = verifyToken;\n LOGGER.log('WebhookHandler instantiated!');\n }\n\n /**\n * Handle a GET request for webhook verification\n */\n public handleVerificationRequest(req: IRequest, res: IResponse): void {\n const mode = req.query['hub.mode'];\n const token = req.query['hub.verify_token'];\n const challenge = req.query['hub.challenge'];\n\n if (mode === 'subscribe' && token === this.verifyToken) {\n LOGGER.log('Webhook verified successfully');\n res.status(200).send(challenge);\n } else {\n LOGGER.log('Webhook verification failed');\n res.status(403).end();\n }\n }\n\n /**\n * Handle a POST request for webhook events\n */\n public async handleWebhookRequest(req: IRequest, res: IResponse): Promise<void> {\n const body = req.body;\n\n // Check this is a WhatsApp Business Account webhook\n if (body.object !== 'whatsapp_business_account') {\n LOGGER.log('Received webhook for non-WhatsApp event');\n res.status(404).end();\n return;\n }\n\n // Process each entry\n for (const entry of body.entry) {\n try {\n const changes = entry.changes;\n for (const change of changes) {\n if (change.field === EventField.MESSAGES) {\n await this.processMessages(change.value);\n } else {\n // Handle other event types\n await this.processEvent(change.field, change.value);\n }\n }\n } catch (error) {\n LOGGER.log(`Error processing webhook: ${error}`);\n }\n }\n\n // Always respond with 200 to acknowledge receipt\n res.status(200).end();\n }\n\n /**\n * Handle webhook requests (both verification and events)\n */\n public handleRequest(req: IRequest, res: IResponse): void | Promise<void> {\n if (req.method === 'GET') {\n return this.handleVerificationRequest(req, res);\n } else if (req.method === 'POST') {\n return this.handleWebhookRequest(req, res);\n } else {\n res.status(405).end(); // Method not allowed\n }\n }\n\n /**\n * Initialize the webhook with an Express app (legacy support)\n * @param app Express application instance\n * @param path The path to listen on, defaults to /webhook\n */\n public initialize(app: any, path: string = '/webhook'): void {\n // Set up middleware to handle requests\n app.all(path, async (req: any, res: any) => {\n const request = expressAdapter.createRequest(req);\n const response = expressAdapter.createResponse(res);\n await this.handleRequest(request, response);\n });\n\n LOGGER.log(`Webhook initialized at path: ${path}`);\n }\n\n /**\n * Process incoming messages\n */\n private async processMessages(value: any): Promise<void> {\n // Extract metadata\n const metadata = value.metadata;\n const phoneNumberId = metadata.phone_number_id;\n\n // Process messages if present\n if (value.messages && value.messages.length > 0) {\n for (const message of value.messages) {\n const messageType = message.type as MessageType;\n\n // Create the base message object\n const processedMessage: WebhookMessage = {\n id: message.id,\n from: message.from,\n timestamp: message.timestamp,\n type: messageType,\n phoneNumberId,\n originalData: message,\n };\n\n // Add type-specific data based on the message type\n switch (messageType) {\n case MessageType.TEXT:\n processedMessage.text = message.text;\n break;\n case MessageType.IMAGE:\n processedMessage.image = message.image;\n break;\n case MessageType.VIDEO:\n processedMessage.video = message.video;\n break;\n case MessageType.AUDIO:\n processedMessage.audio = message.audio;\n break;\n case MessageType.DOCUMENT:\n processedMessage.document = message.document;\n break;\n case MessageType.STICKER:\n processedMessage.sticker = message.sticker;\n break;\n case MessageType.LOCATION:\n processedMessage.location = message.location;\n break;\n case MessageType.CONTACTS:\n processedMessage.contacts = message.contacts;\n break;\n case MessageType.INTERACTIVE:\n processedMessage.interactive = message.interactive;\n break;\n case MessageType.BUTTON:\n processedMessage.button = message.button;\n break;\n case MessageType.ORDER:\n processedMessage.order = message.order;\n break;\n case MessageType.SYSTEM:\n processedMessage.system = message.system;\n break;\n default:\n // Unknown message type\n break;\n }\n\n // Add context if available\n if (message.context) {\n processedMessage.context = message.context;\n }\n\n // Add errors if available\n if (message.errors) {\n processedMessage.errors = message.errors;\n }\n\n // Dispatch to appropriate message handler\n if (this.messageHandlers.has(messageType)) {\n const handler = this.messageHandlers.get(messageType);\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n\n // Also dispatch to general message handler if exists\n if (this.messageHandlers.has('*')) {\n const handler = this.messageHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n }\n }\n\n // Process status messages if present\n if (value.statuses && value.statuses.length > 0) {\n // Process as events\n await this.processEvent(EventField.STATUSES, value);\n }\n }\n\n /**\n * Process other webhook events\n */\n private async processEvent(field: string, value: any): Promise<void> {\n const event: WebhookEvent = {\n field,\n value,\n };\n\n // Dispatch to appropriate event handler\n if (this.eventHandlers.has(field)) {\n const handler = this.eventHandlers.get(field);\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n\n // Also dispatch to general event handler if exists\n if (this.eventHandlers.has('*')) {\n const handler = this.eventHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n }\n\n /**\n * Register a message handler for a specific message type\n * @param type Message type to handle, or '*' for all types\n * @param handler The handler function\n */\n public onMessage(type: string, handler: (message: WebhookMessage) => void | Promise<void>): void {\n this.messageHandlers.set(type, handler);\n LOGGER.log(`Registered handler for message type: ${type}`);\n }\n\n /**\n * Register a general event handler\n * @param field Event field to handle, or '*' for all fields\n * @param handler The handler function\n */\n public onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void {\n this.eventHandlers.set(field, handler);\n LOGGER.log(`Registered handler for event field: ${field}`);\n }\n}\n"],"mappings":"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","names":["Logger","name","debug","data","prefix","LIB_NAME","LOG_LOCAL","LOGGER","Logger","expressAdapter","req","res","code","body","nextJsAdapter","WebhookHandler","config","callbackUrl","verifyToken","mode","token","challenge","entry","changes","change","error","app","path","request","response","value","phoneNumberId","message","messageType","processedMessage","handler","field","event","type"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/logger.ts","../src/webhook.ts"],"sourcesContent":["// @ts-nocheck\nimport type { LoggerInterface } from '../types/logger';\n\nexport default class Logger implements LoggerInterface {\n private name: string;\n private debug: boolean;\n\n constructor(name: string, debug: boolean = false) {\n this.name = name;\n this.debug = debug;\n }\n\n log(...data: any[]) {\n if (this.debug) {\n let prefix = `[ ${Date.now()} ]`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.log.apply(console, [prefix, ': ', ...data]);\n }\n }\n\n error(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - ERROR`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.error.apply(console, [prefix, ': ', ...data]);\n }\n\n warn(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - WARN`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.warn.apply(console, [prefix, ': ', ...data]);\n }\n\n info(...data: any[]) {\n let prefix = `[ ${Date.now()} ] - INFO`;\n if (this.name) {\n prefix += ` - ${this.name}`;\n }\n console.info.apply(console, [prefix, ': ', ...data]);\n }\n}\n","import { WabaConfigType } from './types/config';\n\nimport { EventField, MessageType, WebhookEvent, WebhookMessage } from './types/webhook';\nimport Logger from './utils/logger';\n\nconst LIB_NAME = 'WEBHOOK';\nconst LOG_LOCAL = false;\nconst LOGGER = new Logger(LIB_NAME, process.env.DEBUG === 'true' || LOG_LOCAL);\n\nexport interface IRequest {\n body: any;\n query:\n | Record<string, any>\n | Partial<{\n [key: string]: string | string[];\n }>;\n method?: string;\n}\nexport interface IResponse {\n status: (code: number) => IResponse;\n send: (body: any) => IResponse | void;\n json: (body: any) => IResponse | void;\n end: () => void;\n}\n\n/**\n * Webhook handler for WhatsApp Cloud API\n */\nexport default class WebhookHandler {\n private config: WabaConfigType;\n private messageHandlers: Map<string, (message: WebhookMessage) => void | Promise<void>> = new Map();\n private eventHandlers: Map<string, (event: WebhookEvent) => void | Promise<void>> = new Map();\n\n /**\n * Create a new WebhookHandler\n * @param config The WhatsApp configuration\n */\n constructor(config: WabaConfigType) {\n this.config = config;\n LOGGER.log('WebhookHandler instantiated!');\n }\n\n /**\n * Handle a GET request for webhook verification\n */\n public handleVerificationRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): void {\n const mode = req.query['hub.mode'];\n const token = req.query['hub.verify_token'];\n const challenge = req.query['hub.challenge'];\n\n if (mode === 'subscribe' && token === this.config.WEBHOOK_VERIFICATION_TOKEN) {\n LOGGER.log('Webhook verified successfully');\n res.status(200).send(challenge);\n } else {\n LOGGER.log('Webhook verification failed');\n res.status(403).end();\n }\n }\n\n /**\n * Handle a POST request for webhook events\n */\n public async handleWebhookRequest<Req extends IRequest, Res extends IResponse>(req: Req, res: Res): Promise<void> {\n const body = req.body;\n\n // Check this is a WhatsApp Business Account webhook\n if (body.object !== 'whatsapp_business_account') {\n LOGGER.log('Received webhook for non-WhatsApp event');\n res.status(404).end();\n return;\n }\n\n // Process each entry\n for (const entry of body.entry) {\n try {\n const changes = entry.changes;\n for (const change of changes) {\n if (change.field === EventField.MESSAGES) {\n await this.processMessages(change.value);\n } else {\n // Handle other event types\n await this.processEvent(change.field, change.value);\n }\n }\n } catch (error) {\n LOGGER.log(`Error processing webhook: ${error}`);\n }\n }\n\n // Always respond with 200 to acknowledge receipt\n res.status(200).end();\n }\n\n /**\n * Handle webhook requests (both verification and events)\n */\n public handleRequest(req: IRequest, res: IResponse): void | Promise<void> {\n if (req.method === 'GET') {\n return this.handleVerificationRequest(req, res);\n } else if (req.method === 'POST') {\n return this.handleWebhookRequest(req, res);\n } else {\n res.status(405).end(); // Method not allowed\n }\n }\n\n // /**\n // * Initialize the webhook with an Express app (legacy support)\n // * @param app Express application instance\n // * @param path The path to listen on, defaults to /webhook\n // */\n // public initialize(app: any, path: string = '/webhook'): void {\n // // Set up middleware to handle requests\n // app.all(path, async (req: any, res: any) => {\n // const request = expressAdapter.createRequest(req);\n // const response = expressAdapter.createResponse(res);\n // await this.handleRequest(request, response);\n // });\n\n // LOGGER.log(`Webhook initialized at path: ${path}`);\n // }\n\n /**\n * Process incoming messages\n */\n private async processMessages(value: any): Promise<void> {\n // Extract metadata\n const metadata = value.metadata;\n const phoneNumberId = metadata.phone_number_id;\n const messages = value.messages as WebhookMessage[];\n\n // Process messages if present\n if (messages && messages.length > 0) {\n for (const message of messages) {\n const messageType = message.type;\n\n // Create the base message object\n const processedMessage: WebhookMessage = {\n id: message.id,\n from: message.from,\n timestamp: message.timestamp,\n type: messageType,\n phoneNumberId,\n originalData: message,\n };\n\n // Add type-specific data based on the message type\n switch (messageType) {\n case MessageType.TEXT:\n processedMessage.text = message.text;\n break;\n case MessageType.IMAGE:\n processedMessage.image = message.image;\n break;\n case MessageType.VIDEO:\n processedMessage.video = message.video;\n break;\n case MessageType.AUDIO:\n processedMessage.audio = message.audio;\n break;\n case MessageType.DOCUMENT:\n processedMessage.document = message.document;\n break;\n case MessageType.STICKER:\n processedMessage.sticker = message.sticker;\n break;\n case MessageType.LOCATION:\n processedMessage.location = message.location;\n break;\n case MessageType.CONTACTS:\n processedMessage.contacts = message.contacts;\n break;\n case MessageType.INTERACTIVE:\n processedMessage.interactive = message.interactive;\n break;\n case MessageType.BUTTON:\n processedMessage.button = message.button;\n break;\n case MessageType.ORDER:\n processedMessage.order = message.order;\n break;\n case MessageType.SYSTEM:\n processedMessage.system = message.system;\n break;\n default:\n // Unknown message type\n break;\n }\n\n // Add context if available\n if (message.context) {\n processedMessage.context = message.context;\n }\n\n // Add errors if available\n if (message.errors) {\n processedMessage.errors = message.errors;\n }\n\n // Dispatch to appropriate message handler\n if (this.messageHandlers.has(messageType)) {\n const handler = this.messageHandlers.get(messageType);\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n\n // Also dispatch to general message handler if exists\n if (this.messageHandlers.has('*')) {\n const handler = this.messageHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(processedMessage));\n }\n }\n }\n }\n\n // Process status messages if present\n if (value.statuses && value.statuses.length > 0) {\n // Process as events\n await this.processEvent(EventField.STATUSES, value);\n }\n }\n\n /**\n * Process other webhook events\n */\n private async processEvent(field: string, value: any): Promise<void> {\n const event: WebhookEvent = {\n field,\n value,\n };\n\n // Dispatch to appropriate event handler\n if (this.eventHandlers.has(field)) {\n const handler = this.eventHandlers.get(field);\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n\n // Also dispatch to general event handler if exists\n if (this.eventHandlers.has('*')) {\n const handler = this.eventHandlers.get('*');\n if (handler) {\n await Promise.resolve(handler(event));\n }\n }\n }\n\n /**\n * Register a message handler for a specific message type\n * @param type Message type to handle, or '*' for all types\n * @param handler The handler function\n */\n public onMessage(type: string, handler: (message: WebhookMessage) => void | Promise<void>): void {\n this.messageHandlers.set(type, handler);\n LOGGER.log(`Registered handler for message type: ${type}`);\n }\n\n /**\n * Register a general event handler\n * @param field Event field to handle, or '*' for all fields\n * @param handler The handler function\n */\n public onEvent(field: string, handler: (event: WebhookEvent) => void | Promise<void>): void {\n this.eventHandlers.set(field, handler);\n LOGGER.log(`Registered handler for event field: ${field}`);\n }\n}\n"],"mappings":"AAGA,IAAqBA,EAArB,KAAuD,CAC3C,KACA,MAER,YAAYC,EAAcC,EAAiB,GAAO,CAC9C,KAAK,KAAOD,EACZ,KAAK,MAAQC,CACjB,CAEA,OAAOC,EAAa,CAChB,GAAI,KAAK,MAAO,CACZ,IAAIC,EAAS,KAAK,KAAK,IAAI,CAAC,KACxB,KAAK,OACLA,GAAU,MAAM,KAAK,IAAI,IAE7B,QAAQ,IAAI,MAAM,QAAS,CAACA,EAAQ,KAAM,GAAGD,CAAI,CAAC,CACtD,CACJ,CAEA,SAASA,EAAa,CAClB,IAAIC,EAAS,KAAK,KAAK,IAAI,CAAC,aACxB,KAAK,OACLA,GAAU,MAAM,KAAK,IAAI,IAE7B,QAAQ,MAAM,MAAM,QAAS,CAACA,EAAQ,KAAM,GAAGD,CAAI,CAAC,CACxD,CAEA,QAAQA,EAAa,CACjB,IAAIC,EAAS,KAAK,KAAK,IAAI,CAAC,YACxB,KAAK,OACLA,GAAU,MAAM,KAAK,IAAI,IAE7B,QAAQ,KAAK,MAAM,QAAS,CAACA,EAAQ,KAAM,GAAGD,CAAI,CAAC,CACvD,CAEA,QAAQA,EAAa,CACjB,IAAIC,EAAS,KAAK,KAAK,IAAI,CAAC,YACxB,KAAK,OACLA,GAAU,MAAM,KAAK,IAAI,IAE7B,QAAQ,KAAK,MAAM,QAAS,CAACA,EAAQ,KAAM,GAAGD,CAAI,CAAC,CACvD,CACJ,ECxCA,IAAME,EAAW,UACXC,EAAY,GACZC,EAAS,IAAIC,EAAOH,EAAU,QAAQ,IAAI,QAAU,QAAUC,CAAS,EAqBxDG,EAArB,KAAoC,CACxB,OACA,gBAAkF,IAAI,IACtF,cAA4E,IAAI,IAMxF,YAAYC,EAAwB,CAChC,KAAK,OAASA,EACdH,EAAO,IAAI,8BAA8B,CAC7C,CAKO,0BAAuEI,EAAUC,EAAgB,CACpG,IAAMC,EAAOF,EAAI,MAAM,UAAU,EAC3BG,EAAQH,EAAI,MAAM,kBAAkB,EACpCI,EAAYJ,EAAI,MAAM,eAAe,EAEvCE,IAAS,aAAeC,IAAU,KAAK,OAAO,4BAC9CP,EAAO,IAAI,+BAA+B,EAC1CK,EAAI,OAAO,GAAG,EAAE,KAAKG,CAAS,IAE9BR,EAAO,IAAI,6BAA6B,EACxCK,EAAI,OAAO,GAAG,EAAE,IAAI,EAE5B,CAKA,MAAa,qBAAkED,EAAUC,EAAyB,CAC9G,IAAMI,EAAOL,EAAI,KAGjB,GAAIK,EAAK,SAAW,4BAA6B,CAC7CT,EAAO,IAAI,yCAAyC,EACpDK,EAAI,OAAO,GAAG,EAAE,IAAI,EACpB,MACJ,CAGA,QAAWK,KAASD,EAAK,MACrB,GAAI,CACA,IAAME,EAAUD,EAAM,QACtB,QAAWE,KAAUD,EACbC,EAAO,QAAU,WACjB,MAAM,KAAK,gBAAgBA,EAAO,KAAK,EAGvC,MAAM,KAAK,aAAaA,EAAO,MAAOA,EAAO,KAAK,CAG9D,OAASC,EAAO,CACZb,EAAO,IAAI,6BAA6Ba,CAAK,EAAE,CACnD,CAIJR,EAAI,OAAO,GAAG,EAAE,IAAI,CACxB,CAKO,cAAcD,EAAeC,EAAsC,CACtE,GAAID,EAAI,SAAW,MACf,OAAO,KAAK,0BAA0BA,EAAKC,CAAG,EAC3C,GAAID,EAAI,SAAW,OACtB,OAAO,KAAK,qBAAqBA,EAAKC,CAAG,EAEzCA,EAAI,OAAO,GAAG,EAAE,IAAI,CAE5B,CAqBA,MAAc,gBAAgBS,EAA2B,CAGrD,IAAMC,EADWD,EAAM,SACQ,gBACzBE,EAAWF,EAAM,SAGvB,GAAIE,GAAYA,EAAS,OAAS,EAC9B,QAAWC,KAAWD,EAAU,CAC5B,IAAME,EAAcD,EAAQ,KAGtBE,EAAmC,CACrC,GAAIF,EAAQ,GACZ,KAAMA,EAAQ,KACd,UAAWA,EAAQ,UACnB,KAAMC,EACN,cAAAH,EACA,aAAcE,CAClB,EAGA,OAAQC,EAAa,CACjB,WACIC,EAAiB,KAAOF,EAAQ,KAChC,MACJ,YACIE,EAAiB,MAAQF,EAAQ,MACjC,MACJ,YACIE,EAAiB,MAAQF,EAAQ,MACjC,MACJ,YACIE,EAAiB,MAAQF,EAAQ,MACjC,MACJ,eACIE,EAAiB,SAAWF,EAAQ,SACpC,MACJ,cACIE,EAAiB,QAAUF,EAAQ,QACnC,MACJ,eACIE,EAAiB,SAAWF,EAAQ,SACpC,MACJ,eACIE,EAAiB,SAAWF,EAAQ,SACpC,MACJ,kBACIE,EAAiB,YAAcF,EAAQ,YACvC,MACJ,aACIE,EAAiB,OAASF,EAAQ,OAClC,MACJ,YACIE,EAAiB,MAAQF,EAAQ,MACjC,MACJ,aACIE,EAAiB,OAASF,EAAQ,OAClC,MACJ,QAEI,KACR,CAaA,GAVIA,EAAQ,UACRE,EAAiB,QAAUF,EAAQ,SAInCA,EAAQ,SACRE,EAAiB,OAASF,EAAQ,QAIlC,KAAK,gBAAgB,IAAIC,CAAW,EAAG,CACvC,IAAME,EAAU,KAAK,gBAAgB,IAAIF,CAAW,EAChDE,GACA,MAAM,QAAQ,QAAQA,EAAQD,CAAgB,CAAC,CAEvD,CAGA,GAAI,KAAK,gBAAgB,IAAI,GAAG,EAAG,CAC/B,IAAMC,EAAU,KAAK,gBAAgB,IAAI,GAAG,EACxCA,GACA,MAAM,QAAQ,QAAQA,EAAQD,CAAgB,CAAC,CAEvD,CACJ,CAIAL,EAAM,UAAYA,EAAM,SAAS,OAAS,GAE1C,MAAM,KAAK,wBAAkCA,CAAK,CAE1D,CAKA,MAAc,aAAaO,EAAeP,EAA2B,CACjE,IAAMQ,EAAsB,CACxB,MAAAD,EACA,MAAAP,CACJ,EAGA,GAAI,KAAK,cAAc,IAAIO,CAAK,EAAG,CAC/B,IAAMD,EAAU,KAAK,cAAc,IAAIC,CAAK,EACxCD,GACA,MAAM,QAAQ,QAAQA,EAAQE,CAAK,CAAC,CAE5C,CAGA,GAAI,KAAK,cAAc,IAAI,GAAG,EAAG,CAC7B,IAAMF,EAAU,KAAK,cAAc,IAAI,GAAG,EACtCA,GACA,MAAM,QAAQ,QAAQA,EAAQE,CAAK,CAAC,CAE5C,CACJ,CAOO,UAAUC,EAAcH,EAAkE,CAC7F,KAAK,gBAAgB,IAAIG,EAAMH,CAAO,EACtCpB,EAAO,IAAI,wCAAwCuB,CAAI,EAAE,CAC7D,CAOO,QAAQF,EAAeD,EAA8D,CACxF,KAAK,cAAc,IAAIC,EAAOD,CAAO,EACrCpB,EAAO,IAAI,uCAAuCqB,CAAK,EAAE,CAC7D,CACJ","names":["Logger","name","debug","data","prefix","LIB_NAME","LOG_LOCAL","LOGGER","Logger","WebhookHandler","config","req","res","mode","token","challenge","body","entry","changes","change","error","value","phoneNumberId","messages","message","messageType","processedMessage","handler","field","event","type"]}
|
package/package.json
CHANGED