wuzapi 1.6.6 → 1.6.7
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/README.md +22 -1
- package/dist/types/webhook.d.ts +35 -1
- package/dist/webhook.js +4 -0
- package/dist/webhook.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -954,6 +954,25 @@ switch (messageType) {
|
|
|
954
954
|
);
|
|
955
955
|
break;
|
|
956
956
|
|
|
957
|
+
case MessageType.STICKER:
|
|
958
|
+
const stickerMsg = webhookPayload.event.Message.stickerMessage;
|
|
959
|
+
console.log(
|
|
960
|
+
"Sticker:",
|
|
961
|
+
stickerMsg.isAnimated ? "Animated" : "Static",
|
|
962
|
+
stickerMsg.mimetype
|
|
963
|
+
);
|
|
964
|
+
break;
|
|
965
|
+
|
|
966
|
+
case MessageType.REACTION:
|
|
967
|
+
const reactionMsg = webhookPayload.event.Message.reactionMessage;
|
|
968
|
+
console.log(
|
|
969
|
+
"Reaction:",
|
|
970
|
+
reactionMsg.text,
|
|
971
|
+
"to message",
|
|
972
|
+
reactionMsg.key.ID
|
|
973
|
+
);
|
|
974
|
+
break;
|
|
975
|
+
|
|
957
976
|
case MessageType.POLL_CREATION:
|
|
958
977
|
const pollMsg = webhookPayload.event.Message.pollCreationMessageV3;
|
|
959
978
|
console.log("Poll:", pollMsg.name, `${pollMsg.options.length} options`);
|
|
@@ -975,11 +994,13 @@ enum MessageType {
|
|
|
975
994
|
TEXT = "conversation", // Simple text messages
|
|
976
995
|
EXTENDED_TEXT = "extendedTextMessage", // Rich text messages
|
|
977
996
|
IMAGE = "imageMessage", // Photos, screenshots
|
|
978
|
-
VIDEO = "videoMessage", // Video files
|
|
997
|
+
VIDEO = "videoMessage", // Video files, GIFs
|
|
979
998
|
AUDIO = "audioMessage", // Audio files, voice messages
|
|
980
999
|
DOCUMENT = "documentMessage", // PDFs, Word docs, etc.
|
|
981
1000
|
CONTACT = "contactMessage", // Shared contacts
|
|
982
1001
|
LOCATION = "locationMessage", // Location pins
|
|
1002
|
+
STICKER = "stickerMessage", // Stickers (animated/static)
|
|
1003
|
+
REACTION = "reactionMessage", // Message reactions (emoji)
|
|
983
1004
|
POLL_CREATION = "pollCreationMessageV3", // Polls (groups only)
|
|
984
1005
|
EDITED = "editedMessage", // Edited messages
|
|
985
1006
|
PROTOCOL = "protocolMessage", // System messages
|
package/dist/types/webhook.d.ts
CHANGED
|
@@ -180,6 +180,8 @@ export interface WebhookVideoMessage {
|
|
|
180
180
|
fileEncSHA256: string;
|
|
181
181
|
fileLength: number;
|
|
182
182
|
fileSHA256: string;
|
|
183
|
+
gifAttribution?: number;
|
|
184
|
+
gifPlayback?: boolean;
|
|
183
185
|
height: number;
|
|
184
186
|
mediaKey: string;
|
|
185
187
|
mediaKeyTimestamp: number;
|
|
@@ -189,7 +191,7 @@ export interface WebhookVideoMessage {
|
|
|
189
191
|
thumbnailDirectPath?: string;
|
|
190
192
|
thumbnailEncSHA256?: string;
|
|
191
193
|
thumbnailSHA256?: string;
|
|
192
|
-
videoSourceType
|
|
194
|
+
videoSourceType?: number;
|
|
193
195
|
width: number;
|
|
194
196
|
}
|
|
195
197
|
export interface WebhookAudioMessage {
|
|
@@ -243,6 +245,31 @@ export interface WebhookLocationMessage {
|
|
|
243
245
|
degreesLatitude: number;
|
|
244
246
|
degreesLongitude: number;
|
|
245
247
|
}
|
|
248
|
+
export interface WebhookStickerMessage {
|
|
249
|
+
URL: string;
|
|
250
|
+
contextInfo?: WebhookContextInfo;
|
|
251
|
+
directPath: string;
|
|
252
|
+
fileEncSHA256: string;
|
|
253
|
+
fileLength: number;
|
|
254
|
+
fileSHA256: string;
|
|
255
|
+
firstFrameLength?: number;
|
|
256
|
+
firstFrameSidecar?: string;
|
|
257
|
+
height: number;
|
|
258
|
+
isAiSticker?: boolean;
|
|
259
|
+
isAnimated?: boolean;
|
|
260
|
+
isAvatar?: boolean;
|
|
261
|
+
isLottie?: boolean;
|
|
262
|
+
mediaKey: string;
|
|
263
|
+
mediaKeyTimestamp: number;
|
|
264
|
+
mimetype: string;
|
|
265
|
+
stickerSentTS?: number;
|
|
266
|
+
width: number;
|
|
267
|
+
}
|
|
268
|
+
export interface WebhookReactionMessage {
|
|
269
|
+
key: WebhookMessageKey;
|
|
270
|
+
senderTimestampMS?: number;
|
|
271
|
+
text?: string;
|
|
272
|
+
}
|
|
246
273
|
export interface WebhookEditedMessage {
|
|
247
274
|
message?: unknown;
|
|
248
275
|
timestampMS?: string;
|
|
@@ -276,9 +303,14 @@ export interface WebhookGenericMessage {
|
|
|
276
303
|
contactMessage?: WebhookContactMessage;
|
|
277
304
|
pollCreationMessageV3?: WebhookPollCreationMessageV3;
|
|
278
305
|
locationMessage?: WebhookLocationMessage;
|
|
306
|
+
stickerMessage?: WebhookStickerMessage;
|
|
307
|
+
reactionMessage?: WebhookReactionMessage;
|
|
279
308
|
editedMessage?: WebhookEditedMessage;
|
|
280
309
|
protocolMessage?: {
|
|
281
310
|
type?: number;
|
|
311
|
+
editedMessage?: WebhookGenericMessage;
|
|
312
|
+
key?: WebhookMessageKey;
|
|
313
|
+
timestampMS?: number;
|
|
282
314
|
historySyncNotification?: WebhookHistorySyncNotification;
|
|
283
315
|
initialSecurityNotificationSettingSync?: {
|
|
284
316
|
securityNotificationEnabled: boolean;
|
|
@@ -299,6 +331,8 @@ export declare enum MessageType {
|
|
|
299
331
|
CONTACT = "contactMessage",
|
|
300
332
|
POLL_CREATION = "pollCreationMessageV3",
|
|
301
333
|
LOCATION = "locationMessage",
|
|
334
|
+
STICKER = "stickerMessage",
|
|
335
|
+
REACTION = "reactionMessage",
|
|
302
336
|
EDITED = "editedMessage",
|
|
303
337
|
PROTOCOL = "protocolMessage",
|
|
304
338
|
DEVICE_SENT = "deviceSentMessage",
|
package/dist/webhook.js
CHANGED
|
@@ -60,6 +60,8 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
|
60
60
|
MessageType2["CONTACT"] = "contactMessage";
|
|
61
61
|
MessageType2["POLL_CREATION"] = "pollCreationMessageV3";
|
|
62
62
|
MessageType2["LOCATION"] = "locationMessage";
|
|
63
|
+
MessageType2["STICKER"] = "stickerMessage";
|
|
64
|
+
MessageType2["REACTION"] = "reactionMessage";
|
|
63
65
|
MessageType2["EDITED"] = "editedMessage";
|
|
64
66
|
MessageType2["PROTOCOL"] = "protocolMessage";
|
|
65
67
|
MessageType2["DEVICE_SENT"] = "deviceSentMessage";
|
|
@@ -91,6 +93,8 @@ function discoverMessageType(message) {
|
|
|
91
93
|
if (message.documentMessage) return "documentMessage";
|
|
92
94
|
if (message.contactMessage) return "contactMessage";
|
|
93
95
|
if (message.locationMessage) return "locationMessage";
|
|
96
|
+
if (message.stickerMessage) return "stickerMessage";
|
|
97
|
+
if (message.reactionMessage) return "reactionMessage";
|
|
94
98
|
if (message.pollCreationMessageV3) return "pollCreationMessageV3";
|
|
95
99
|
if (message.editedMessage) return "editedMessage";
|
|
96
100
|
if (message.protocolMessage) return "protocolMessage";
|
package/dist/webhook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.js","sources":["../src/types/webhook.ts"],"sourcesContent":["// Import types that are identical from other modules\nimport type { VerifiedName } from \"./user.js\";\n\n// Webhook endpoints types\n\n// Webhook event types (events that can be subscribed to via webhooks)\nexport enum WebhookEventType {\n MESSAGE = \"Message\",\n UNDECRYPTABLE_MESSAGE = \"UndecryptableMessage\",\n RECEIPT = \"Receipt\",\n READ_RECEIPT = \"ReadReceipt\",\n MEDIA_RETRY = \"MediaRetry\",\n GROUP_INFO = \"GroupInfo\",\n JOINED_GROUP = \"JoinedGroup\",\n PICTURE = \"Picture\",\n BLOCKLIST_CHANGE = \"BlocklistChange\",\n BLOCKLIST = \"Blocklist\",\n CONNECTED = \"Connected\",\n DISCONNECTED = \"Disconnected\",\n CONNECT_FAILURE = \"ConnectFailure\",\n KEEP_ALIVE_RESTORED = \"KeepAliveRestored\",\n KEEP_ALIVE_TIMEOUT = \"KeepAliveTimeout\",\n LOGGED_OUT = \"LoggedOut\",\n CLIENT_OUTDATED = \"ClientOutdated\",\n TEMPORARY_BAN = \"TemporaryBan\",\n STREAM_ERROR = \"StreamError\",\n STREAM_REPLACED = \"StreamReplaced\",\n PAIR_SUCCESS = \"PairSuccess\",\n PAIR_ERROR = \"PairError\",\n QR = \"QR\",\n QR_SCANNED_WITHOUT_MULTIDEVICE = \"QRScannedWithoutMultidevice\",\n PRIVACY_SETTINGS = \"PrivacySettings\",\n PUSH_NAME_SETTING = \"PushNameSetting\",\n USER_ABOUT = \"UserAbout\",\n APP_STATE = \"AppState\",\n APP_STATE_SYNC_COMPLETE = \"AppStateSyncComplete\",\n HISTORY_SYNC = \"HistorySync\",\n OFFLINE_SYNC_COMPLETED = \"OfflineSyncCompleted\",\n OFFLINE_SYNC_PREVIEW = \"OfflineSyncPreview\",\n CALL_OFFER = \"CallOffer\",\n CALL_ACCEPT = \"CallAccept\",\n CALL_TERMINATE = \"CallTerminate\",\n CALL_OFFER_NOTICE = \"CallOfferNotice\",\n CALL_RELAY_LATENCY = \"CallRelayLatency\",\n PRESENCE = \"Presence\",\n CHAT_PRESENCE = \"ChatPresence\",\n IDENTITY_CHANGE = \"IdentityChange\",\n CAT_REFRESH_ERROR = \"CATRefreshError\",\n NEWSLETTER_JOIN = \"NewsletterJoin\",\n NEWSLETTER_LEAVE = \"NewsletterLeave\",\n NEWSLETTER_MUTE_CHANGE = \"NewsletterMuteChange\",\n NEWSLETTER_LIVE_UPDATE = \"NewsletterLiveUpdate\",\n FB_MESSAGE = \"FBMessage\",\n ALL = \"All\",\n}\n\n// Helper to get all webhook event values as string array\nexport const WEBHOOK_EVENTS = Object.values(WebhookEventType);\n\n// Type for webhook event names\nexport type WebhookEvent = keyof typeof WebhookEventType;\n\nexport interface SetWebhookRequest {\n webhook: string;\n events: (WebhookEvent | string)[];\n}\n\nexport interface SetWebhookResponse {\n WebhookURL: string;\n Events: string[];\n}\n\nexport interface GetWebhookResponse {\n subscribe: string[];\n webhook: string;\n}\n\nexport interface UpdateWebhookRequest {\n webhook?: string;\n events?: (WebhookEvent | string)[];\n Active?: boolean;\n}\n\nexport interface UpdateWebhookResponse {\n WebhookURL: string;\n Events: string[];\n active: boolean;\n}\n\nexport interface DeleteWebhookResponse {\n Details: string;\n}\n\n// Webhook payload types (what your webhook endpoint receives)\n\nexport interface S3MediaInfo {\n url: string;\n key: string;\n bucket: string;\n size: number;\n mimeType: string;\n fileName: string;\n}\n\n// Base interface that all webhook payloads extend from\nexport interface WebhookPayloadBase<T = unknown> {\n event: T;\n type: string;\n token: string;\n state?: string; // Optional state field (e.g., \"Read\" or \"Delivered\" for ReadReceipt events)\n}\n\n// Standard webhook payload with optional media\nexport interface WebhookPayload<T = unknown> extends WebhookPayloadBase<T> {\n s3?: S3MediaInfo;\n base64?: string;\n mimeType?: string;\n fileName?: string;\n}\n\n// Specific webhook payload types for different media delivery modes\n\n// S3 only delivery\nexport interface S3OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n}\n\n// Base64 only delivery\nexport interface Base64OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Both S3 and Base64 delivery\nexport interface BothMediaWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Union type for all possible webhook payloads\nexport type AnyWebhookPayload<T = unknown> =\n | WebhookPayload<T>\n | S3OnlyWebhookPayload<T>\n | Base64OnlyWebhookPayload<T>\n | BothMediaWebhookPayload<T>;\n\n// Shared message and media interfaces for reusability across webhook events\n//\n// Note: Webhook events may have different structures than the corresponding\n// WhatsApp events in events.ts. Webhook events use flat structures with\n// string-based JIDs and ISO timestamp strings, while internal events use\n// structured JID objects and Date objects.\n\n// Common context info structures\nexport interface WebhookMessageContextInfo {\n deviceListMetadata?: WebhookDeviceListMetadata;\n deviceListMetadataVersion?: number;\n messageSecret?: string; // Encryption secret (string format for webhook)\n limitSharingV2?: {\n initiatedByMe: boolean;\n trigger: number;\n };\n}\n\nexport interface WebhookDeviceListMetadata {\n senderKeyHash?: string; // Base64 string format for webhook (vs Uint8Array in message.ts)\n senderTimestamp?: number;\n recipientKeyHash?: string; // Base64 string format for webhook\n recipientTimestamp?: number;\n senderAccountType?: number; // Webhook-specific field\n receiverAccountType?: number; // Webhook-specific field\n}\n\nexport interface WebhookContextInfo {\n disappearingMode?: {\n initiator: number;\n initiatedByMe?: boolean; // Webhook-specific field\n trigger?: number; // Webhook-specific field\n };\n ephemeralSettingTimestamp?: number;\n expiration?: number;\n forwardingScore?: number;\n isForwarded?: boolean;\n pairedMediaType?: number;\n statusSourceType?: number;\n featureEligibilities?: {\n canBeReshared?: boolean;\n };\n}\n\n// Common message types that are reused across different webhook events\nexport interface WebhookExtendedTextMessage {\n text: string;\n contextInfo?: WebhookContextInfo;\n inviteLinkGroupTypeV2?: number; // Webhook-specific field\n previewType?: number; // Webhook-specific field\n}\n\nexport interface WebhookImageMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n height: number;\n imageSourceType: number; // Webhook-specific field\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n midQualityFileSHA256: string; // Mid quality file hash (webhook-specific)\n mimetype: string; // MIME type (e.g., \"image/jpeg\")\n scanLengths: number[]; // Progressive scan lengths (webhook-specific)\n scansSidecar: string; // Progressive scan sidecar data (webhook-specific)\n firstScanLength?: number; // First scan length (webhook-specific)\n firstScanSidecar?: string; // First scan sidecar (webhook-specific)\n width: number;\n}\n\nexport interface WebhookVideoMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n accessibilityLabel?: string;\n caption?: string;\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n externalShareFullVideoDurationInSeconds?: number; // Webhook-specific field\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n height: number;\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"video/mp4\")\n seconds: number; // Video duration in seconds\n streamingSidecar?: string; // Streaming sidecar data for video streaming\n thumbnailDirectPath?: string; // Thumbnail direct path (webhook-specific)\n thumbnailEncSHA256?: string; // Thumbnail encrypted SHA256 (webhook-specific)\n thumbnailSHA256?: string; // Thumbnail SHA256 (webhook-specific)\n videoSourceType: number; // Webhook-specific field\n width: number;\n}\n\nexport interface WebhookAudioMessage {\n URL?: string; // Uppercase for webhook\n contextInfo?: WebhookContextInfo;\n directPath?: string;\n fileEncSHA256?: string; // String format for webhook\n fileLength?: number;\n fileSHA256?: string; // String format for webhook\n mediaKey?: string; // String format for webhook\n mediaKeyTimestamp?: number;\n mimetype?: string;\n seconds?: number;\n ptt?: boolean; // Push to talk (voice message) - Note: payload uses uppercase \"PTT\"\n streamingSidecar?: string; // Streaming sidecar data for audio streaming (webhook-specific)\n waveform?: string; // Base64 encoded waveform for voice messages (webhook-specific)\n}\n\nexport interface WebhookDocumentMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contactVcard: boolean; // Whether this is a contact vCard (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileName: string; // Original file name\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application/pdf\")\n pageCount?: number; // Number of pages in the document (webhook-specific field)\n title: string; // Document title (usually filename without extension)\n}\n\nexport interface WebhookContactMessage {\n contextInfo?: WebhookContextInfo;\n displayName: string; // Display name of the contact\n vcard: string; // vCard data in standard vCard format\n}\n\nexport interface WebhookPollCreationMessageV3 {\n contextInfo?: WebhookContextInfo;\n name: string; // Poll question/title\n options: Array<{\n optionHash: string; // Hash for the option\n optionName: string; // Display text for the option\n }>;\n pollContentType: number; // Type of poll content\n selectableOptionsCount: number; // Number of options that can be selected (0 = single choice, >0 = multiple choice)\n}\n\nexport interface WebhookLocationMessage {\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail of the location (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n degreesLatitude: number; // Latitude coordinate\n degreesLongitude: number; // Longitude coordinate\n}\n\nexport interface WebhookEditedMessage {\n message?: unknown; // The edited message content\n timestampMS?: string; // Edit timestamp\n editedMessageID?: string; // ID of original message being edited\n}\n\n// Message key structure\nexport interface WebhookMessageKey {\n ID: string; // Uppercase field name for webhook (vs lowercase 'id' in message.ts)\n fromMe: boolean; // Required in webhook (vs optional in message.ts)\n participant?: string; // JID in string format\n remoteJID: string; // Uppercase JID field name for webhook (vs 'remoteJid' in message.ts)\n}\n\n// User receipt structure\nexport interface UserReceipt {\n userJID?: string;\n receiptTimestamp?: number;\n readTimestamp?: number;\n playedTimestamp?: number;\n}\n\n// Reaction structure\nexport interface WebhookReaction {\n key?: WebhookMessageKey;\n text?: string;\n senderTimestampMS?: number;\n}\n\n// Generic message wrapper for webhook payloads\nexport interface WebhookGenericMessage {\n messageContextInfo?: WebhookMessageContextInfo;\n conversation?: string; // Simple text message\n extendedTextMessage?: WebhookExtendedTextMessage;\n imageMessage?: WebhookImageMessage;\n videoMessage?: WebhookVideoMessage;\n audioMessage?: WebhookAudioMessage;\n documentMessage?: WebhookDocumentMessage;\n contactMessage?: WebhookContactMessage;\n pollCreationMessageV3?: WebhookPollCreationMessageV3;\n locationMessage?: WebhookLocationMessage;\n editedMessage?: WebhookEditedMessage;\n protocolMessage?: {\n type?: number;\n historySyncNotification?: WebhookHistorySyncNotification;\n initialSecurityNotificationSettingSync?: {\n securityNotificationEnabled: boolean;\n };\n };\n deviceSentMessage?: {\n destinationJID: string;\n message: WebhookGenericMessage;\n };\n}\n\n// Message types enum for easier handling of different message types\nexport enum MessageType {\n TEXT = \"conversation\",\n EXTENDED_TEXT = \"extendedTextMessage\",\n IMAGE = \"imageMessage\",\n VIDEO = \"videoMessage\",\n AUDIO = \"audioMessage\",\n DOCUMENT = \"documentMessage\",\n CONTACT = \"contactMessage\",\n POLL_CREATION = \"pollCreationMessageV3\",\n LOCATION = \"locationMessage\",\n EDITED = \"editedMessage\",\n PROTOCOL = \"protocolMessage\",\n DEVICE_SENT = \"deviceSentMessage\",\n UNKNOWN = \"unknown\",\n}\n// History sync notification structure\nexport interface WebhookHistorySyncNotification {\n chunkOrder?: number;\n directPath: string;\n encHandle: string; // Webhook-specific field\n fileEncSHA256: string; // String format for webhook\n fileLength: number;\n fileSHA256: string; // String format for webhook\n mediaKey: string; // String format for webhook\n progress?: number;\n syncType: number;\n}\n\n// Using VerifiedName imported from user.ts (identical interface)\n\n// Specific webhook event data interfaces\n\n// QR webhook event data (based on observed webhook payload)\n// Note: For QR events, the event field is actually just the string \"code\"\n// We represent this as an empty interface since the real data is at payload level\nexport interface QRWebhookEvent {\n // The event field contains just the string \"code\"\n // The actual QR code data is in qrCodeBase64 at the payload level\n}\n\n// Connected webhook event data (based on observed webhook payload)\n// Note: For Connected events, the event field is an empty object {}\nexport interface ConnectedWebhookEvent {\n // The event field contains an empty object {}\n // No additional data is provided for Connected events\n}\n\n// ReadReceipt webhook event data (based on observed webhook payload)\n// Maps to Receipt event type but with webhook-specific structure\nexport interface ReadReceiptWebhookEvent {\n AddressingMode: string;\n BroadcastListOwner: string;\n Chat: string; // JID in string format (e.g., \"554198387899-1431900789@g.us\")\n IsFromMe: boolean;\n IsGroup: boolean;\n MessageIDs: string[];\n MessageSender: string;\n RecipientAlt: string;\n Sender: string; // JID in string format (e.g., \"554198387899@s.whatsapp.net\")\n SenderAlt: string;\n Timestamp: string; // ISO string timestamp\n Type: string; // Receipt type (e.g., \"read\")\n}\n\n// HistorySync webhook event data (based on observed webhook payload)\n// Contains different types of historical data - can be pastParticipants, statusV3Messages, conversations, etc.\nexport interface HistorySyncWebhookEvent {\n Data: {\n // Variant 1: Past participants data (groups and stickers)\n pastParticipants?: Array<{\n groupJID: string; // JID in string format (e.g., \"120363388053770128@g.us\")\n pastParticipants: Array<{\n leaveReason: number; // 0 = left voluntarily, 1 = kicked/removed\n leaveTS: number; // Unix timestamp\n userJID: string; // JID in string format\n }>;\n }>;\n recentStickers?: Array<{\n URL: string; // Full WhatsApp media URL\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash\n height: number;\n isLottie: boolean; // Whether it's an animated Lottie sticker\n lastStickerSentTS: number; // Unix timestamp of last usage\n mediaKey: string; // Media encryption key\n mimetype: string; // MIME type (e.g., \"image/webp\")\n weight: number; // Usage weight/frequency\n width: number;\n }>;\n\n // Variant 2: Status messages data (stories/status updates)\n statusV3Messages?: Array<{\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n participant: string; // JID in string format\n reportingTokenInfo?: {\n reportingTag: string;\n };\n }>;\n\n // Variant 3: Conversation histories data\n conversations?: Array<{\n ID: string; // JID in string format (chat identifier)\n messages: Array<{\n message: {\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n messageC2STimestamp?: number; // Client to server timestamp\n ephemeralStartTimestamp?: number; // Ephemeral message start timestamp\n originalSelfAuthorUserJIDString?: string; // Original author for messages sent by self\n status?: number; // Message status (3=delivered, 4=read, 5=played)\n userReceipt?: UserReceipt[];\n reactions?: WebhookReaction[];\n reportingTokenInfo?: {\n reportingTag: string;\n };\n };\n msgOrderID: number; // Message order ID\n }>;\n }>;\n phoneNumberToLidMappings?: Array<{\n lidJID: string; // LID JID (e.g., \"165434221441206@lid\")\n pnJID: string; // Phone number JID (e.g., \"554199392033@s.whatsapp.net\")\n }>;\n\n // Common fields for all variants\n chunkOrder?: number; // Chunk order for paginated sync\n progress?: number; // Sync progress\n syncType: number; // Sync operation type\n };\n}\n\n// Message webhook event data (based on observed webhook payload)\n// Complex structure similar to MessageEvent in events.ts but with webhook-specific format\nexport interface MessageWebhookEvent {\n Info: {\n AddressingMode: string;\n BroadcastListOwner: string;\n Category: string;\n Chat: string; // JID in string format\n DeviceSentMeta: {\n DestinationJID: string;\n Phash: string;\n } | null;\n Edit: string;\n ID: string;\n IsFromMe: boolean;\n IsGroup: boolean;\n MediaType: string;\n MsgBotInfo: {\n EditSenderTimestampMS: string; // ISO timestamp\n EditTargetID: string;\n EditType: string;\n };\n MsgMetaInfo: {\n DeprecatedLIDSession: unknown | null;\n TargetID: string;\n TargetSender: string;\n ThreadMessageID: string;\n ThreadMessageSenderJID: string;\n };\n Multicast: boolean;\n PushName: string;\n RecipientAlt: string;\n Sender: string; // JID in string format\n SenderAlt: string;\n ServerID: number;\n Timestamp: string; // ISO string timestamp\n Type: string; // Message type (e.g., \"text\")\n VerifiedName: VerifiedName | null;\n };\n IsDocumentWithCaption: boolean;\n IsEdit: boolean;\n IsEphemeral: boolean;\n IsLottieSticker: boolean;\n IsViewOnce: boolean;\n IsViewOnceV2: boolean;\n IsViewOnceV2Extension: boolean;\n Message: WebhookGenericMessage; // Using webhook-specific message structure\n NewsletterMeta: unknown | null;\n RawMessage: WebhookGenericMessage; // Using webhook-specific message structure\n RetryCount: number;\n SourceWebMsg: unknown | null;\n UnavailableRequestID: string;\n}\n\n// Typed webhook payloads for specific events\nexport type QRWebhookPayload = AnyWebhookPayload<QRWebhookEvent> & {\n qrCodeBase64: string; // QR code as base64 data URL\n};\nexport type ConnectedWebhookPayload = AnyWebhookPayload<ConnectedWebhookEvent>;\nexport type ReadReceiptWebhookPayload =\n AnyWebhookPayload<ReadReceiptWebhookEvent>;\nexport type HistorySyncWebhookPayload =\n AnyWebhookPayload<HistorySyncWebhookEvent>;\nexport type MessageWebhookPayload = AnyWebhookPayload<MessageWebhookEvent>;\n\n// Webhook event mapping types for type-safe handling\nexport interface WebhookEventMap {\n QR: QRWebhookEvent;\n Connected: ConnectedWebhookEvent;\n ReadReceipt: ReadReceiptWebhookEvent;\n HistorySync: HistorySyncWebhookEvent;\n Message: MessageWebhookEvent;\n // Add more webhook event mappings here as they are discovered\n}\n\n// Type-safe webhook handler function type\nexport type WebhookEventHandler<T extends keyof WebhookEventMap> = (\n payload: AnyWebhookPayload<WebhookEventMap[T]>\n) => void | Promise<void>;\n\n// Union type for all specific webhook payloads\nexport type SpecificWebhookPayload =\n | QRWebhookPayload\n | ConnectedWebhookPayload\n | ReadReceiptWebhookPayload\n | HistorySyncWebhookPayload\n | MessageWebhookPayload;\n\n// Type guard to check if payload is a specific webhook event type\nexport function isWebhookEventType<T extends keyof WebhookEventMap>(\n payload: WebhookPayloadBase,\n eventType: T\n): payload is AnyWebhookPayload<WebhookEventMap[T]> {\n return payload.type === eventType;\n}\n\n// Helper type guards\nexport function hasS3Media(\n payload: WebhookPayloadBase\n): payload is S3OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).s3;\n}\n\nexport function hasBase64Media(\n payload: WebhookPayloadBase\n): payload is Base64OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).base64;\n}\n\nexport function hasBothMedia(\n payload: WebhookPayloadBase\n): payload is BothMediaWebhookPayload {\n return hasS3Media(payload) && hasBase64Media(payload);\n}\n\n// Helper type guard to check if payload has token (all webhook payloads should)\nexport function isValidWebhookPayload(\n payload: unknown\n): payload is WebhookPayloadBase {\n return (\n typeof payload === \"object\" &&\n payload !== null &&\n \"event\" in payload &&\n \"type\" in payload &&\n \"token\" in payload\n );\n}\n\n/**\n * Utility function to discover the type of a GenericMessage\n * @param message - The GenericMessage to analyze\n * @returns MessageType enum value indicating the message type\n *\n * @example\n * ```typescript\n * import { discoverMessageType, MessageType } from \"wuzapi\";\n *\n * const messageType = discoverMessageType(webhookPayload.event.Message);\n *\n * switch (messageType) {\n * case MessageType.IMAGE:\n * console.log(\"Received an image message\");\n * break;\n * case MessageType.EXTENDED_TEXT:\n * console.log(\"Received a text message\");\n * break;\n * // ... handle other types\n * }\n * ```\n */\nexport function discoverMessageType(\n message: WebhookGenericMessage\n): MessageType {\n if (!message) return MessageType.UNKNOWN;\n\n // Check for each message type in order of most common to least common\n if (message.conversation) return MessageType.TEXT;\n if (message.extendedTextMessage) return MessageType.EXTENDED_TEXT;\n if (message.imageMessage) return MessageType.IMAGE;\n if (message.videoMessage) return MessageType.VIDEO;\n if (message.audioMessage) return MessageType.AUDIO;\n if (message.documentMessage) return MessageType.DOCUMENT;\n if (message.contactMessage) return MessageType.CONTACT;\n if (message.locationMessage) return MessageType.LOCATION;\n if (message.pollCreationMessageV3) return MessageType.POLL_CREATION;\n if (message.editedMessage) return MessageType.EDITED;\n if (message.protocolMessage) return MessageType.PROTOCOL;\n if (message.deviceSentMessage) return MessageType.DEVICE_SENT;\n\n return MessageType.UNKNOWN;\n}\n"],"names":["WebhookEventType","MessageType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"webhook.js","sources":["../src/types/webhook.ts"],"sourcesContent":["// Import types that are identical from other modules\nimport type { VerifiedName } from \"./user.js\";\n\n// Webhook endpoints types\n\n// Webhook event types (events that can be subscribed to via webhooks)\nexport enum WebhookEventType {\n MESSAGE = \"Message\",\n UNDECRYPTABLE_MESSAGE = \"UndecryptableMessage\",\n RECEIPT = \"Receipt\",\n READ_RECEIPT = \"ReadReceipt\",\n MEDIA_RETRY = \"MediaRetry\",\n GROUP_INFO = \"GroupInfo\",\n JOINED_GROUP = \"JoinedGroup\",\n PICTURE = \"Picture\",\n BLOCKLIST_CHANGE = \"BlocklistChange\",\n BLOCKLIST = \"Blocklist\",\n CONNECTED = \"Connected\",\n DISCONNECTED = \"Disconnected\",\n CONNECT_FAILURE = \"ConnectFailure\",\n KEEP_ALIVE_RESTORED = \"KeepAliveRestored\",\n KEEP_ALIVE_TIMEOUT = \"KeepAliveTimeout\",\n LOGGED_OUT = \"LoggedOut\",\n CLIENT_OUTDATED = \"ClientOutdated\",\n TEMPORARY_BAN = \"TemporaryBan\",\n STREAM_ERROR = \"StreamError\",\n STREAM_REPLACED = \"StreamReplaced\",\n PAIR_SUCCESS = \"PairSuccess\",\n PAIR_ERROR = \"PairError\",\n QR = \"QR\",\n QR_SCANNED_WITHOUT_MULTIDEVICE = \"QRScannedWithoutMultidevice\",\n PRIVACY_SETTINGS = \"PrivacySettings\",\n PUSH_NAME_SETTING = \"PushNameSetting\",\n USER_ABOUT = \"UserAbout\",\n APP_STATE = \"AppState\",\n APP_STATE_SYNC_COMPLETE = \"AppStateSyncComplete\",\n HISTORY_SYNC = \"HistorySync\",\n OFFLINE_SYNC_COMPLETED = \"OfflineSyncCompleted\",\n OFFLINE_SYNC_PREVIEW = \"OfflineSyncPreview\",\n CALL_OFFER = \"CallOffer\",\n CALL_ACCEPT = \"CallAccept\",\n CALL_TERMINATE = \"CallTerminate\",\n CALL_OFFER_NOTICE = \"CallOfferNotice\",\n CALL_RELAY_LATENCY = \"CallRelayLatency\",\n PRESENCE = \"Presence\",\n CHAT_PRESENCE = \"ChatPresence\",\n IDENTITY_CHANGE = \"IdentityChange\",\n CAT_REFRESH_ERROR = \"CATRefreshError\",\n NEWSLETTER_JOIN = \"NewsletterJoin\",\n NEWSLETTER_LEAVE = \"NewsletterLeave\",\n NEWSLETTER_MUTE_CHANGE = \"NewsletterMuteChange\",\n NEWSLETTER_LIVE_UPDATE = \"NewsletterLiveUpdate\",\n FB_MESSAGE = \"FBMessage\",\n ALL = \"All\",\n}\n\n// Helper to get all webhook event values as string array\nexport const WEBHOOK_EVENTS = Object.values(WebhookEventType);\n\n// Type for webhook event names\nexport type WebhookEvent = keyof typeof WebhookEventType;\n\nexport interface SetWebhookRequest {\n webhook: string;\n events: (WebhookEvent | string)[];\n}\n\nexport interface SetWebhookResponse {\n WebhookURL: string;\n Events: string[];\n}\n\nexport interface GetWebhookResponse {\n subscribe: string[];\n webhook: string;\n}\n\nexport interface UpdateWebhookRequest {\n webhook?: string;\n events?: (WebhookEvent | string)[];\n Active?: boolean;\n}\n\nexport interface UpdateWebhookResponse {\n WebhookURL: string;\n Events: string[];\n active: boolean;\n}\n\nexport interface DeleteWebhookResponse {\n Details: string;\n}\n\n// Webhook payload types (what your webhook endpoint receives)\n\nexport interface S3MediaInfo {\n url: string;\n key: string;\n bucket: string;\n size: number;\n mimeType: string;\n fileName: string;\n}\n\n// Base interface that all webhook payloads extend from\nexport interface WebhookPayloadBase<T = unknown> {\n event: T;\n type: string;\n token: string;\n state?: string; // Optional state field (e.g., \"Read\" or \"Delivered\" for ReadReceipt events)\n}\n\n// Standard webhook payload with optional media\nexport interface WebhookPayload<T = unknown> extends WebhookPayloadBase<T> {\n s3?: S3MediaInfo;\n base64?: string;\n mimeType?: string;\n fileName?: string;\n}\n\n// Specific webhook payload types for different media delivery modes\n\n// S3 only delivery\nexport interface S3OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n}\n\n// Base64 only delivery\nexport interface Base64OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Both S3 and Base64 delivery\nexport interface BothMediaWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Union type for all possible webhook payloads\nexport type AnyWebhookPayload<T = unknown> =\n | WebhookPayload<T>\n | S3OnlyWebhookPayload<T>\n | Base64OnlyWebhookPayload<T>\n | BothMediaWebhookPayload<T>;\n\n// Shared message and media interfaces for reusability across webhook events\n//\n// Note: Webhook events may have different structures than the corresponding\n// WhatsApp events in events.ts. Webhook events use flat structures with\n// string-based JIDs and ISO timestamp strings, while internal events use\n// structured JID objects and Date objects.\n\n// Common context info structures\nexport interface WebhookMessageContextInfo {\n deviceListMetadata?: WebhookDeviceListMetadata;\n deviceListMetadataVersion?: number;\n messageSecret?: string; // Encryption secret (string format for webhook)\n limitSharingV2?: {\n initiatedByMe: boolean;\n trigger: number;\n };\n}\n\nexport interface WebhookDeviceListMetadata {\n senderKeyHash?: string; // Base64 string format for webhook (vs Uint8Array in message.ts)\n senderTimestamp?: number;\n recipientKeyHash?: string; // Base64 string format for webhook\n recipientTimestamp?: number;\n senderAccountType?: number; // Webhook-specific field\n receiverAccountType?: number; // Webhook-specific field\n}\n\nexport interface WebhookContextInfo {\n disappearingMode?: {\n initiator: number;\n initiatedByMe?: boolean; // Webhook-specific field\n trigger?: number; // Webhook-specific field\n };\n ephemeralSettingTimestamp?: number;\n expiration?: number;\n forwardingScore?: number;\n isForwarded?: boolean;\n pairedMediaType?: number;\n statusSourceType?: number;\n featureEligibilities?: {\n canBeReshared?: boolean;\n };\n}\n\n// Common message types that are reused across different webhook events\nexport interface WebhookExtendedTextMessage {\n text: string;\n contextInfo?: WebhookContextInfo;\n inviteLinkGroupTypeV2?: number; // Webhook-specific field\n previewType?: number; // Webhook-specific field\n}\n\nexport interface WebhookImageMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n height: number;\n imageSourceType: number; // Webhook-specific field\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n midQualityFileSHA256: string; // Mid quality file hash (webhook-specific)\n mimetype: string; // MIME type (e.g., \"image/jpeg\")\n scanLengths: number[]; // Progressive scan lengths (webhook-specific)\n scansSidecar: string; // Progressive scan sidecar data (webhook-specific)\n firstScanLength?: number; // First scan length (webhook-specific)\n firstScanSidecar?: string; // First scan sidecar (webhook-specific)\n width: number;\n}\n\nexport interface WebhookVideoMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n accessibilityLabel?: string;\n caption?: string;\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n externalShareFullVideoDurationInSeconds?: number; // Webhook-specific field\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n gifAttribution?: number; // GIF attribution type (0=none, 1=giphy, 2=tenor, etc.) (webhook-specific)\n gifPlayback?: boolean; // Whether this video should be played as a GIF (webhook-specific)\n height: number;\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"video/mp4\")\n seconds: number; // Video duration in seconds\n streamingSidecar?: string; // Streaming sidecar data for video streaming\n thumbnailDirectPath?: string; // Thumbnail direct path (webhook-specific)\n thumbnailEncSHA256?: string; // Thumbnail encrypted SHA256 (webhook-specific)\n thumbnailSHA256?: string; // Thumbnail SHA256 (webhook-specific)\n videoSourceType?: number; // Webhook-specific field\n width: number;\n}\n\nexport interface WebhookAudioMessage {\n URL?: string; // Uppercase for webhook\n contextInfo?: WebhookContextInfo;\n directPath?: string;\n fileEncSHA256?: string; // String format for webhook\n fileLength?: number;\n fileSHA256?: string; // String format for webhook\n mediaKey?: string; // String format for webhook\n mediaKeyTimestamp?: number;\n mimetype?: string;\n seconds?: number;\n ptt?: boolean; // Push to talk (voice message) - Note: payload uses uppercase \"PTT\"\n streamingSidecar?: string; // Streaming sidecar data for audio streaming (webhook-specific)\n waveform?: string; // Base64 encoded waveform for voice messages (webhook-specific)\n}\n\nexport interface WebhookDocumentMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contactVcard: boolean; // Whether this is a contact vCard (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileName: string; // Original file name\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application/pdf\")\n pageCount?: number; // Number of pages in the document (webhook-specific field)\n title: string; // Document title (usually filename without extension)\n}\n\nexport interface WebhookContactMessage {\n contextInfo?: WebhookContextInfo;\n displayName: string; // Display name of the contact\n vcard: string; // vCard data in standard vCard format\n}\n\nexport interface WebhookPollCreationMessageV3 {\n contextInfo?: WebhookContextInfo;\n name: string; // Poll question/title\n options: Array<{\n optionHash: string; // Hash for the option\n optionName: string; // Display text for the option\n }>;\n pollContentType: number; // Type of poll content\n selectableOptionsCount: number; // Number of options that can be selected (0 = single choice, >0 = multiple choice)\n}\n\nexport interface WebhookLocationMessage {\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail of the location (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n degreesLatitude: number; // Latitude coordinate\n degreesLongitude: number; // Longitude coordinate\n}\n\nexport interface WebhookStickerMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n firstFrameLength?: number; // First frame length for animated stickers (webhook-specific)\n firstFrameSidecar?: string; // First frame sidecar data (webhook-specific)\n height: number; // Sticker height\n isAiSticker?: boolean; // Whether this is an AI-generated sticker (webhook-specific)\n isAnimated?: boolean; // Whether this is an animated sticker (webhook-specific)\n isAvatar?: boolean; // Whether this is an avatar sticker (webhook-specific)\n isLottie?: boolean; // Whether this is a Lottie sticker (webhook-specific)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (typically \"image/webp\" for stickers)\n stickerSentTS?: number; // Sticker sent timestamp (webhook-specific field)\n width: number; // Sticker width\n}\n\nexport interface WebhookReactionMessage {\n key: WebhookMessageKey; // Key of the message being reacted to\n senderTimestampMS?: number; // Timestamp when reaction was sent\n text?: string; // The reaction emoji/text\n}\n\nexport interface WebhookEditedMessage {\n message?: unknown; // The edited message content\n timestampMS?: string; // Edit timestamp\n editedMessageID?: string; // ID of original message being edited\n}\n\n// Message key structure\nexport interface WebhookMessageKey {\n ID: string; // Uppercase field name for webhook (vs lowercase 'id' in message.ts)\n fromMe: boolean; // Required in webhook (vs optional in message.ts)\n participant?: string; // JID in string format\n remoteJID: string; // Uppercase JID field name for webhook (vs 'remoteJid' in message.ts)\n}\n\n// User receipt structure\nexport interface UserReceipt {\n userJID?: string;\n receiptTimestamp?: number;\n readTimestamp?: number;\n playedTimestamp?: number;\n}\n\n// Reaction structure\nexport interface WebhookReaction {\n key?: WebhookMessageKey;\n text?: string;\n senderTimestampMS?: number;\n}\n\n// Generic message wrapper for webhook payloads\nexport interface WebhookGenericMessage {\n messageContextInfo?: WebhookMessageContextInfo;\n conversation?: string; // Simple text message\n extendedTextMessage?: WebhookExtendedTextMessage;\n imageMessage?: WebhookImageMessage;\n videoMessage?: WebhookVideoMessage;\n audioMessage?: WebhookAudioMessage;\n documentMessage?: WebhookDocumentMessage;\n contactMessage?: WebhookContactMessage;\n pollCreationMessageV3?: WebhookPollCreationMessageV3;\n locationMessage?: WebhookLocationMessage;\n stickerMessage?: WebhookStickerMessage;\n reactionMessage?: WebhookReactionMessage;\n editedMessage?: WebhookEditedMessage;\n protocolMessage?: {\n type?: number;\n editedMessage?: WebhookGenericMessage; // Nested edited message in protocol messages\n key?: WebhookMessageKey; // Message key for protocol messages\n timestampMS?: number; // Edit timestamp\n historySyncNotification?: WebhookHistorySyncNotification;\n initialSecurityNotificationSettingSync?: {\n securityNotificationEnabled: boolean;\n };\n };\n deviceSentMessage?: {\n destinationJID: string;\n message: WebhookGenericMessage;\n };\n}\n\n// Message types enum for easier handling of different message types\nexport enum MessageType {\n TEXT = \"conversation\",\n EXTENDED_TEXT = \"extendedTextMessage\",\n IMAGE = \"imageMessage\",\n VIDEO = \"videoMessage\",\n AUDIO = \"audioMessage\",\n DOCUMENT = \"documentMessage\",\n CONTACT = \"contactMessage\",\n POLL_CREATION = \"pollCreationMessageV3\",\n LOCATION = \"locationMessage\",\n STICKER = \"stickerMessage\",\n REACTION = \"reactionMessage\",\n EDITED = \"editedMessage\",\n PROTOCOL = \"protocolMessage\",\n DEVICE_SENT = \"deviceSentMessage\",\n UNKNOWN = \"unknown\",\n}\n// History sync notification structure\nexport interface WebhookHistorySyncNotification {\n chunkOrder?: number;\n directPath: string;\n encHandle: string; // Webhook-specific field\n fileEncSHA256: string; // String format for webhook\n fileLength: number;\n fileSHA256: string; // String format for webhook\n mediaKey: string; // String format for webhook\n progress?: number;\n syncType: number;\n}\n\n// Using VerifiedName imported from user.ts (identical interface)\n\n// Specific webhook event data interfaces\n\n// QR webhook event data (based on observed webhook payload)\n// Note: For QR events, the event field is actually just the string \"code\"\n// We represent this as an empty interface since the real data is at payload level\nexport interface QRWebhookEvent {\n // The event field contains just the string \"code\"\n // The actual QR code data is in qrCodeBase64 at the payload level\n}\n\n// Connected webhook event data (based on observed webhook payload)\n// Note: For Connected events, the event field is an empty object {}\nexport interface ConnectedWebhookEvent {\n // The event field contains an empty object {}\n // No additional data is provided for Connected events\n}\n\n// ReadReceipt webhook event data (based on observed webhook payload)\n// Maps to Receipt event type but with webhook-specific structure\nexport interface ReadReceiptWebhookEvent {\n AddressingMode: string;\n BroadcastListOwner: string;\n Chat: string; // JID in string format (e.g., \"554198387899-1431900789@g.us\")\n IsFromMe: boolean;\n IsGroup: boolean;\n MessageIDs: string[];\n MessageSender: string;\n RecipientAlt: string;\n Sender: string; // JID in string format (e.g., \"554198387899@s.whatsapp.net\")\n SenderAlt: string;\n Timestamp: string; // ISO string timestamp\n Type: string; // Receipt type (e.g., \"read\")\n}\n\n// HistorySync webhook event data (based on observed webhook payload)\n// Contains different types of historical data - can be pastParticipants, statusV3Messages, conversations, etc.\nexport interface HistorySyncWebhookEvent {\n Data: {\n // Variant 1: Past participants data (groups and stickers)\n pastParticipants?: Array<{\n groupJID: string; // JID in string format (e.g., \"120363388053770128@g.us\")\n pastParticipants: Array<{\n leaveReason: number; // 0 = left voluntarily, 1 = kicked/removed\n leaveTS: number; // Unix timestamp\n userJID: string; // JID in string format\n }>;\n }>;\n recentStickers?: Array<{\n URL: string; // Full WhatsApp media URL\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash\n height: number;\n isLottie: boolean; // Whether it's an animated Lottie sticker\n lastStickerSentTS: number; // Unix timestamp of last usage\n mediaKey: string; // Media encryption key\n mimetype: string; // MIME type (e.g., \"image/webp\")\n weight: number; // Usage weight/frequency\n width: number;\n }>;\n\n // Variant 2: Status messages data (stories/status updates)\n statusV3Messages?: Array<{\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n participant: string; // JID in string format\n reportingTokenInfo?: {\n reportingTag: string;\n };\n }>;\n\n // Variant 3: Conversation histories data\n conversations?: Array<{\n ID: string; // JID in string format (chat identifier)\n messages: Array<{\n message: {\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n messageC2STimestamp?: number; // Client to server timestamp\n ephemeralStartTimestamp?: number; // Ephemeral message start timestamp\n originalSelfAuthorUserJIDString?: string; // Original author for messages sent by self\n status?: number; // Message status (3=delivered, 4=read, 5=played)\n userReceipt?: UserReceipt[];\n reactions?: WebhookReaction[];\n reportingTokenInfo?: {\n reportingTag: string;\n };\n };\n msgOrderID: number; // Message order ID\n }>;\n }>;\n phoneNumberToLidMappings?: Array<{\n lidJID: string; // LID JID (e.g., \"165434221441206@lid\")\n pnJID: string; // Phone number JID (e.g., \"554199392033@s.whatsapp.net\")\n }>;\n\n // Common fields for all variants\n chunkOrder?: number; // Chunk order for paginated sync\n progress?: number; // Sync progress\n syncType: number; // Sync operation type\n };\n}\n\n// Message webhook event data (based on observed webhook payload)\n// Complex structure similar to MessageEvent in events.ts but with webhook-specific format\nexport interface MessageWebhookEvent {\n Info: {\n AddressingMode: string;\n BroadcastListOwner: string;\n Category: string;\n Chat: string; // JID in string format\n DeviceSentMeta: {\n DestinationJID: string;\n Phash: string;\n } | null;\n Edit: string;\n ID: string;\n IsFromMe: boolean;\n IsGroup: boolean;\n MediaType: string;\n MsgBotInfo: {\n EditSenderTimestampMS: string; // ISO timestamp\n EditTargetID: string;\n EditType: string;\n };\n MsgMetaInfo: {\n DeprecatedLIDSession: unknown | null;\n TargetID: string;\n TargetSender: string;\n ThreadMessageID: string;\n ThreadMessageSenderJID: string;\n };\n Multicast: boolean;\n PushName: string;\n RecipientAlt: string;\n Sender: string; // JID in string format\n SenderAlt: string;\n ServerID: number;\n Timestamp: string; // ISO string timestamp\n Type: string; // Message type (e.g., \"text\")\n VerifiedName: VerifiedName | null;\n };\n IsDocumentWithCaption: boolean;\n IsEdit: boolean;\n IsEphemeral: boolean;\n IsLottieSticker: boolean;\n IsViewOnce: boolean;\n IsViewOnceV2: boolean;\n IsViewOnceV2Extension: boolean;\n Message: WebhookGenericMessage; // Using webhook-specific message structure\n NewsletterMeta: unknown | null;\n RawMessage: WebhookGenericMessage; // Using webhook-specific message structure\n RetryCount: number;\n SourceWebMsg: unknown | null;\n UnavailableRequestID: string;\n}\n\n// Typed webhook payloads for specific events\nexport type QRWebhookPayload = AnyWebhookPayload<QRWebhookEvent> & {\n qrCodeBase64: string; // QR code as base64 data URL\n};\nexport type ConnectedWebhookPayload = AnyWebhookPayload<ConnectedWebhookEvent>;\nexport type ReadReceiptWebhookPayload =\n AnyWebhookPayload<ReadReceiptWebhookEvent>;\nexport type HistorySyncWebhookPayload =\n AnyWebhookPayload<HistorySyncWebhookEvent>;\nexport type MessageWebhookPayload = AnyWebhookPayload<MessageWebhookEvent>;\n\n// Webhook event mapping types for type-safe handling\nexport interface WebhookEventMap {\n QR: QRWebhookEvent;\n Connected: ConnectedWebhookEvent;\n ReadReceipt: ReadReceiptWebhookEvent;\n HistorySync: HistorySyncWebhookEvent;\n Message: MessageWebhookEvent;\n // Add more webhook event mappings here as they are discovered\n}\n\n// Type-safe webhook handler function type\nexport type WebhookEventHandler<T extends keyof WebhookEventMap> = (\n payload: AnyWebhookPayload<WebhookEventMap[T]>\n) => void | Promise<void>;\n\n// Union type for all specific webhook payloads\nexport type SpecificWebhookPayload =\n | QRWebhookPayload\n | ConnectedWebhookPayload\n | ReadReceiptWebhookPayload\n | HistorySyncWebhookPayload\n | MessageWebhookPayload;\n\n// Type guard to check if payload is a specific webhook event type\nexport function isWebhookEventType<T extends keyof WebhookEventMap>(\n payload: WebhookPayloadBase,\n eventType: T\n): payload is AnyWebhookPayload<WebhookEventMap[T]> {\n return payload.type === eventType;\n}\n\n// Helper type guards\nexport function hasS3Media(\n payload: WebhookPayloadBase\n): payload is S3OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).s3;\n}\n\nexport function hasBase64Media(\n payload: WebhookPayloadBase\n): payload is Base64OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).base64;\n}\n\nexport function hasBothMedia(\n payload: WebhookPayloadBase\n): payload is BothMediaWebhookPayload {\n return hasS3Media(payload) && hasBase64Media(payload);\n}\n\n// Helper type guard to check if payload has token (all webhook payloads should)\nexport function isValidWebhookPayload(\n payload: unknown\n): payload is WebhookPayloadBase {\n return (\n typeof payload === \"object\" &&\n payload !== null &&\n \"event\" in payload &&\n \"type\" in payload &&\n \"token\" in payload\n );\n}\n\n/**\n * Utility function to discover the type of a GenericMessage\n * @param message - The GenericMessage to analyze\n * @returns MessageType enum value indicating the message type\n *\n * @example\n * ```typescript\n * import { discoverMessageType, MessageType } from \"wuzapi\";\n *\n * const messageType = discoverMessageType(webhookPayload.event.Message);\n *\n * switch (messageType) {\n * case MessageType.IMAGE:\n * console.log(\"Received an image message\");\n * break;\n * case MessageType.EXTENDED_TEXT:\n * console.log(\"Received a text message\");\n * break;\n * // ... handle other types\n * }\n * ```\n */\nexport function discoverMessageType(\n message: WebhookGenericMessage\n): MessageType {\n if (!message) return MessageType.UNKNOWN;\n\n // Check for each message type in order of most common to least common\n if (message.conversation) return MessageType.TEXT;\n if (message.extendedTextMessage) return MessageType.EXTENDED_TEXT;\n if (message.imageMessage) return MessageType.IMAGE;\n if (message.videoMessage) return MessageType.VIDEO;\n if (message.audioMessage) return MessageType.AUDIO;\n if (message.documentMessage) return MessageType.DOCUMENT;\n if (message.contactMessage) return MessageType.CONTACT;\n if (message.locationMessage) return MessageType.LOCATION;\n if (message.stickerMessage) return MessageType.STICKER;\n if (message.reactionMessage) return MessageType.REACTION;\n if (message.pollCreationMessageV3) return MessageType.POLL_CREATION;\n if (message.editedMessage) return MessageType.EDITED;\n if (message.protocolMessage) return MessageType.PROTOCOL;\n if (message.deviceSentMessage) return MessageType.DEVICE_SENT;\n\n return MessageType.UNKNOWN;\n}\n"],"names":["WebhookEventType","MessageType"],"mappings":"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"}
|