UNPKG

@warriorteam/messenger-sdk

Version:

TypeScript SDK for Facebook Messenger Platform API with Conversations support

1,658 lines (1,633 loc) 112 kB
interface ClientConfig { accessToken?: string; version: string; baseUrl?: string; timeout?: number; maxRetries?: number; } interface APIOptions { accessToken?: string; } interface RequestOptions { method: 'GET' | 'POST' | 'DELETE'; path: string; body?: any; query?: Record<string, string | number | boolean>; accessToken?: string; } declare class HTTPClient { private readonly config; constructor(config: ClientConfig); request<T>(options: RequestOptions): Promise<T>; private buildUrl; private makeRequest; private handleResponse; private delay; } interface Recipient { id?: string; phone_number?: string; user_ref?: string; comment_id?: string; post_id?: string; name?: { first_name: string; last_name: string; }; } interface QuickReply$1 { content_type: 'text' | 'user_phone_number' | 'user_email'; title?: string; payload?: string; image_url?: string; } interface Message$2 { text?: string; attachment?: Attachment; quick_replies?: QuickReply$1[]; metadata?: string; } interface Attachment { type: 'image' | 'audio' | 'video' | 'file' | 'template'; payload: AttachmentPayload$1 | TemplatePayload; } interface AttachmentPayload$1 { url?: string; attachment_id?: string; is_reusable?: boolean; } interface TemplatePayload { template_type: 'generic' | 'button' | 'media' | 'product'; elements?: any[]; buttons?: any[]; [key: string]: any; } type SenderAction = 'mark_seen' | 'typing_on' | 'typing_off' | 'react' | 'unreact'; interface ReactionPayload { message_id: string; reaction?: string; } type MessagingType = 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG'; interface SendMessageRequest { recipient: Recipient; messaging_type: MessagingType; message?: Message$2; sender_action?: SenderAction; sender_action_payload?: ReactionPayload; notification_type?: 'REGULAR' | 'SILENT_PUSH' | 'NO_PUSH'; tag?: string; } interface SendMessageResponse { recipient_id?: string; message_id: string; attachment_id?: string; } interface MessengerError { message: string; type: string; code: number; error_subcode?: number; fbtrace_id: string; } interface ErrorResponse { error: MessengerError; } type AttachmentType$1 = 'image' | 'audio' | 'video' | 'file'; interface AttachmentUploadRequest { type: AttachmentType$1; url: string; is_reusable?: boolean; } interface AttachmentUploadResponse { attachment_id: string; } declare class SendAPI { private httpClient; constructor(httpClient: HTTPClient); message(request: SendMessageRequest, options?: APIOptions): Promise<SendMessageResponse>; action(recipientId: string, action: SenderAction, options?: APIOptions & { payload?: ReactionPayload; }): Promise<SendMessageResponse>; typingOn(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; typingOff(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; markSeen(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; setTyping(recipientId: string, state: boolean, options?: APIOptions): Promise<SendMessageResponse>; markRead(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; addReaction(recipientId: string, content: { messageId: string; emoji: string; }, options?: APIOptions): Promise<SendMessageResponse>; removeReaction(recipientId: string, messageId: string, options?: APIOptions): Promise<SendMessageResponse>; /** * Send an attachment using a previously uploaded attachment_id */ attachment(options: { recipient: Recipient; type: AttachmentType$1; attachment_id: string; messaging_type?: 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG'; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; /** * Upload and send an attachment from URL in a single request */ attachmentFromUrl(options: { recipient: Recipient; type: AttachmentType$1; url: string; messaging_type?: 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG'; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; } declare class AttachmentsAPI { private httpClient; constructor(httpClient: HTTPClient); upload(request: AttachmentUploadRequest, options?: APIOptions): Promise<AttachmentUploadResponse>; } interface UserId { id: string; } type ModerationAction = 'block_user' | 'unblock_user' | 'ban_user' | 'unban_user' | 'move_to_spam'; interface ModerateConversationsRequest { user_ids: UserId[]; actions: ModerationAction[]; } interface ModerateConversationsResponse { result: 'success' | 'failure'; } declare class ModerationAPI { private httpClient; constructor(httpClient: HTTPClient); /** * Moderate conversations with specified actions * Up to 10 user IDs and up to 2 actions per request */ moderate(request: ModerateConversationsRequest, options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Block a user from messaging the page * Prevents messaging but user can still interact with page content on Facebook */ blockUser(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Unblock a user to allow messaging again */ unblockUser(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Ban a user from both messaging and Facebook interactions * More restrictive than blocking - prevents all interactions * Note: Cannot ban user who was unbanned in last 48 hours */ banUser(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Unban a user to restore all interactions * Note: Banned user cannot be unblocked, they must be unbanned first */ unbanUser(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Move conversation to spam folder in Meta Business Suite Inbox */ moveToSpam(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; /** * Block user and move to spam (common moderation action) */ blockAndSpam(userIds: string | string[], options?: APIOptions): Promise<ModerateConversationsResponse>; } interface Button { type: 'web_url' | 'postback' | 'phone_number' | 'game_play' | 'account_link' | 'account_unlink'; title?: string; url?: string; payload?: string; webview_height_ratio?: 'compact' | 'tall' | 'full'; messenger_extensions?: boolean; fallback_url?: string; webview_share_button?: 'hide' | 'show'; game_metadata?: { player_id?: string; context_id?: string; }; } interface DefaultAction { type: 'web_url'; url: string; webview_height_ratio?: 'compact' | 'tall' | 'full'; messenger_extensions?: boolean; fallback_url?: string; webview_share_button?: 'hide' | 'show'; } interface GenericTemplateElement { title: string; subtitle?: string; image_url?: string; default_action?: DefaultAction; buttons?: Button[]; } interface GenericTemplatePayload { template_type: 'generic'; elements: GenericTemplateElement[]; image_aspect_ratio?: 'horizontal' | 'square'; } interface ButtonTemplatePayload { template_type: 'button'; text: string; buttons: Button[]; } interface MediaTemplateElement { media_type: 'image' | 'video'; url?: string; attachment_id?: string; buttons?: Button[]; sharable?: boolean; } interface MediaTemplatePayload { template_type: 'media'; elements: [MediaTemplateElement]; } interface ProductTemplateElement { id: string; } interface ProductTemplatePayload { template_type: 'product'; elements: ProductTemplateElement[]; } declare class TemplatesAPI { private httpClient; constructor(httpClient: HTTPClient); generic(options: { recipient: Recipient; elements: GenericTemplateElement[]; messaging_type?: MessagingType; image_aspect_ratio?: 'horizontal' | 'square'; notification_type?: 'REGULAR' | 'SILENT_PUSH' | 'NO_PUSH'; tag?: string; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; button(options: { recipient: Recipient; text: string; buttons: Button[]; messaging_type?: MessagingType; notification_type?: 'REGULAR' | 'SILENT_PUSH' | 'NO_PUSH'; tag?: string; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; media(options: { recipient: Recipient; element: MediaTemplateElement; messaging_type?: MessagingType; notification_type?: 'REGULAR' | 'SILENT_PUSH' | 'NO_PUSH'; tag?: string; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; product(options: { recipient: Recipient; elements: ProductTemplateElement[]; messaging_type?: MessagingType; notification_type?: 'REGULAR' | 'SILENT_PUSH' | 'NO_PUSH'; tag?: string; }, apiOptions?: APIOptions): Promise<SendMessageResponse>; } type ProfileField = 'id' | 'name' | 'first_name' | 'last_name' | 'profile_pic' | 'locale' | 'timezone' | 'gender'; interface GetProfileRequest { psid: string; fields?: ProfileField[]; } interface UserProfile { id?: string; name?: string; first_name?: string; last_name?: string; profile_pic?: string; locale?: string; timezone?: number; gender?: string; } declare class ProfileAPI { private httpClient; constructor(httpClient: HTTPClient); /** * Get user profile information using PSID * Requires "Advanced User Profile Access" feature */ get(request: GetProfileRequest, options?: APIOptions): Promise<UserProfile>; /** * Get user profile with default fields (first_name, last_name, profile_pic) */ getBasic(psid: string, options?: APIOptions): Promise<UserProfile>; /** * Get comprehensive user profile with all available fields */ getFull(psid: string, options?: APIOptions): Promise<UserProfile>; /** * Get user's name (first_name and last_name) */ getName(psid: string, options?: APIOptions): Promise<UserProfile>; /** * Get user's profile picture URL */ getProfilePicture(psid: string, options?: APIOptions): Promise<UserProfile>; } /** * Facebook Messenger Platform - Conversations API Types * * Type definitions for retrieving conversations and messages between users and Pages/Instagram Business accounts. * * @see https://developers.facebook.com/docs/messenger-platform/conversations */ /** * Platform type for conversations */ type ConversationPlatform = 'instagram' | 'messenger'; /** * Conversation folder types */ type ConversationFolder = 'inbox' | 'pending' | 'spam'; /** * Basic conversation information */ interface Conversation { /** The conversation ID */ id: string; /** Timestamp of the most recent message (Unix timestamp) */ updated_time: string; } /** * Participant in a conversation */ interface ConversationParticipant { /** Instagram-scoped ID or Page-scoped ID of a person, or Page ID, or Instagram Business Account ID */ id: string; /** Email of the person or Page (Messenger only) */ email?: string; /** Name of the person or Page (Messenger only) */ name?: string; /** Instagram username of a person or your Instagram Business Account (Instagram only) */ username?: string; } /** * Detailed conversation with messages and participants */ interface ConversationDetail { /** The conversation ID */ id: string; /** Messages in the conversation */ messages?: { data: MessageBasic[]; paging?: { cursors?: { before?: string; after?: string; }; next?: string; previous?: string; }; }; /** Participants in the conversation */ participants?: { data: ConversationParticipant[]; }; /** Timestamp of the most recent message */ updated_time?: string; } /** * Basic message information (ID and timestamp) */ interface MessageBasic { /** The message ID */ id: string; /** When the message was created (ISO 8601 timestamp) */ created_time: string; } /** * Message sender/recipient information */ interface MessageParticipant { /** Instagram-scoped ID or Page-scoped ID or Instagram Business Account ID */ id: string; /** Email (Messenger only) */ email?: string; /** Name (Messenger only) */ name?: string; /** Instagram username (Instagram only) */ username?: string; } /** * Message attachment types */ type MessageAttachmentType = 'image' | 'video' | 'audio' | 'file'; /** * Image data in attachment */ interface ImageData { /** Preview URL of the image */ preview_url?: string; /** Full URL of the image */ url?: string; /** Width in pixels */ width?: number; /** Height in pixels */ height?: number; /** Max width in pixels */ max_width?: number; /** Max height in pixels */ max_height?: number; /** URL of animated GIF preview */ animated_gif_preview_url?: string; /** URL of animated GIF */ animated_gif_url?: string; /** Whether to render as sticker */ render_as_sticker?: boolean; } /** * Video data in attachment */ interface VideoData { /** URL of the video */ url?: string; /** Width in pixels */ width?: number; /** Height in pixels */ height?: number; /** Preview URL */ preview_url?: string; } /** * Generic template in attachment */ interface GenericTemplate { /** Call-to-action button */ cta?: { title?: string; type?: string; url?: string; }; /** Media URL */ media_url?: string; /** Subtitle text */ subtitle?: string; /** Title text */ title?: string; } /** * Message attachment */ interface MessageAttachment$1 { /** Attachment ID */ id?: string; /** File URL */ file_url?: string; /** Image data */ image_data?: ImageData; /** Video data */ video_data?: VideoData; /** Generic template */ generic_template?: GenericTemplate; /** File name */ name?: string; } /** * Reaction to a message */ interface MessageReaction { /** Emoji reaction (e.g., "❤️", "😂", "👍") */ reaction: string; /** Users who reacted with this emoji */ users: Array<{ id: string; username?: string; }>; } /** * Reply information */ interface ReplyInfo { /** Message ID being replied to */ mid: string; /** Whether this is a self-reply (reply to own message) */ is_self_reply?: boolean; } /** * Story share/mention */ interface StoryShare { /** CDN URL of the story */ link: string; /** Story ID */ id: string; } /** * Product in a share */ interface SharedProduct { /** Product ID (0 if business can't see this product) */ id: string; /** ID assigned by the retailer */ retailer_id?: string; /** Product image URL */ image_url?: string; /** Product name */ name?: string; /** Product price */ price?: string; } /** * Share template payload */ interface ShareTemplatePayload { product?: { elements?: { data: SharedProduct[]; }; }; } /** * Shared content */ interface MessageShare { /** Share template */ template?: { payload?: ShareTemplatePayload; }; } /** * Message tags */ interface MessageTag { /** Tag name (e.g., "inbox", "read", "source:chat") */ name: string; } /** * Detailed message information */ interface Message$1 { /** The message ID */ id: string; /** When the message was created */ created_time: string; /** Sender information */ from?: MessageParticipant; /** Recipient information */ to?: { data: MessageParticipant[]; }; /** Text content of the message (empty if no text) */ message?: string; /** Message attachments */ attachments?: { data: MessageAttachment$1[]; }; /** Reactions to the message */ reactions?: { data: MessageReaction[]; }; /** Shared content (posts, products, etc.) */ shares?: { data: MessageShare[]; }; /** Story reply or mention */ story?: StoryShare; /** Reply information */ reply_to?: ReplyInfo; /** Message tags */ tags?: { data: MessageTag[]; }; /** Whether the message contains unsupported content */ is_unsupported?: boolean; } /** * Request parameters for listing conversations */ interface ListConversationsParams { /** Platform to filter by */ platform?: ConversationPlatform; /** User ID to find conversations with specific user */ user_id?: string; /** Folder to filter by */ folder?: ConversationFolder; /** Number of conversations to return */ limit?: number; /** Pagination cursor */ after?: string; /** Pagination cursor */ before?: string; } /** * Request parameters for getting conversation details */ interface GetConversationParams { /** Fields to retrieve (e.g., 'messages', 'participants') */ fields?: string[]; /** Number of messages to return */ limit?: number; /** Pagination cursor */ after?: string; /** Pagination cursor */ before?: string; } /** * Request parameters for getting message details */ interface GetMessageParams { /** Fields to retrieve */ fields?: string[]; } /** * Response for listing conversations */ interface ListConversationsResponse { data: Conversation[]; paging?: { cursors?: { before?: string; after?: string; }; next?: string; previous?: string; }; } /** * Response for getting messages in a conversation */ interface ListMessagesResponse { data: MessageBasic[]; paging?: { cursors?: { before?: string; after?: string; }; next?: string; previous?: string; }; } /** * Conversations API Resource * * Handles retrieving conversations and messages between users and Pages/Instagram Business accounts. * * @see https://developers.facebook.com/docs/messenger-platform/conversations */ /** * Conversations API class for retrieving conversation and message data * * @example * ```typescript * const messenger = new Messenger({ accessToken: 'PAGE_TOKEN' }); * * // List all conversations * const conversations = await messenger.conversations.list('PAGE_ID', { * platform: 'messenger' * }); * * // Get conversation details * const conversation = await messenger.conversations.get('CONVERSATION_ID'); * * // Get message details * const message = await messenger.conversations.getMessage('MESSAGE_ID'); * ``` */ declare class ConversationsAPI { private httpClient; constructor(httpClient: HTTPClient); /** * Get a list of conversations for a Page or Instagram Business Account * * @param pageId - The Page ID or Instagram Business Account ID * @param params - Optional parameters for filtering and pagination * @param options - Optional request options (e.g., token override) * @returns List of conversations * * @example * ```typescript * // List Messenger conversations * const conversations = await messenger.conversations.list('PAGE_ID', { * platform: 'messenger', * limit: 25 * }); * * // Find conversation with specific user * const userConvos = await messenger.conversations.list('PAGE_ID', { * platform: 'instagram', * user_id: 'USER_INSTAGRAM_SCOPED_ID' * }); * * // Paginate through conversations * const nextPage = await messenger.conversations.list('PAGE_ID', { * platform: 'messenger', * after: conversations.paging?.cursors?.after * }); * ``` */ list(pageId: string, params?: ListConversationsParams, options?: APIOptions): Promise<ListConversationsResponse>; /** * Get details about a specific conversation * * @param conversationId - The conversation ID * @param params - Optional parameters for fields and pagination * @param options - Optional request options (e.g., token override) * @returns Conversation details * * @example * ```typescript * // Get conversation with messages * const conversation = await messenger.conversations.get('CONVERSATION_ID', { * fields: ['messages', 'participants'] * }); * * // Get only participants * const participants = await messenger.conversations.get('CONVERSATION_ID', { * fields: ['participants'] * }); * ``` */ get(conversationId: string, params?: GetConversationParams, options?: APIOptions): Promise<ConversationDetail>; /** * Get messages in a conversation * * @param conversationId - The conversation ID * @param params - Optional parameters for pagination * @param options - Optional request options (e.g., token override) * @returns List of messages * * @example * ```typescript * // Get messages in a conversation * const messages = await messenger.conversations.getMessages('CONVERSATION_ID', { * limit: 20 * }); * * // Paginate through messages * const nextPage = await messenger.conversations.getMessages('CONVERSATION_ID', { * after: messages.paging?.cursors?.after * }); * ``` */ getMessages(conversationId: string, params?: { limit?: number; after?: string; before?: string; }, options?: APIOptions): Promise<ListMessagesResponse>; /** * Get details about a specific message * * Note: You can only retrieve details for the 20 most recent messages in a conversation. * Older messages will return an error indicating the message was deleted. * * @param messageId - The message ID * @param params - Optional parameters for fields to retrieve * @param options - Optional request options (e.g., token override) * @returns Message details * * @example * ```typescript * // Get full message details * const message = await messenger.conversations.getMessage('MESSAGE_ID', { * fields: ['id', 'created_time', 'from', 'to', 'message', 'attachments', 'reactions'] * }); * * // Get basic message info * const basicMessage = await messenger.conversations.getMessage('MESSAGE_ID'); * ``` */ getMessage(messageId: string, params?: GetMessageParams, options?: APIOptions): Promise<Message$1>; /** * Get the 20 most recent messages in a conversation with full details * * This is a convenience method that retrieves message IDs and then fetches * full details for each message. Note that only the 20 most recent messages * can have their details retrieved. * * @param conversationId - The conversation ID * @param options - Optional request options (e.g., token override) * @returns Array of detailed messages * * @example * ```typescript * // Get recent messages with full details * const messages = await messenger.conversations.getRecentMessages('CONVERSATION_ID'); * * for (const message of messages) { * console.log(`${message.from?.username}: ${message.message}`); * } * ``` */ getRecentMessages(conversationId: string, options?: APIOptions): Promise<Message$1[]>; /** * Find a conversation between a Page and a specific user * * This is a convenience method that finds a conversation with a specific user. * * @param pageId - The Page ID or Instagram Business Account ID * @param userId - The user's Instagram-scoped ID or Page-scoped ID * @param platform - The platform ('instagram' or 'messenger') * @param options - Optional request options (e.g., token override) * @returns The conversation ID, or null if not found * * @example * ```typescript * // Find conversation with Instagram user * const conversationId = await messenger.conversations.findByUser( * 'PAGE_ID', * 'USER_INSTAGRAM_SCOPED_ID', * 'instagram' * ); * * if (conversationId) { * const messages = await messenger.conversations.getRecentMessages(conversationId); * } * ``` */ findByUser(pageId: string, userId: string, platform: 'instagram' | 'messenger', options?: APIOptions): Promise<string | null>; } interface MessengerConfig { accessToken?: string; version?: string; baseUrl?: string; timeout?: number; maxRetries?: number; } declare class Messenger { readonly send: SendAPI; readonly attachments: AttachmentsAPI; readonly moderation: ModerationAPI; readonly templates: TemplatesAPI; readonly profile: ProfileAPI; readonly conversations: ConversationsAPI; private readonly httpClient; constructor(config?: MessengerConfig); private validateConfig; } /** * Facebook Messenger Platform - Base Webhook Types * * This file contains the common base types and interfaces shared across * all webhook event types. It provides the foundation for a properly * structured type system with inheritance and discriminated unions. * * @module webhooks/base-types */ /** * Common sender interface for all webhook events. * Represents the user who initiated the action. */ interface WebhookSender { /** * Page-scoped ID (PSID) of the user. * This is the unique identifier for the user within the context of your page. */ id: string; /** * User reference provided by the chat plugin, if applicable. * Only present for chat plugin events where the user hasn't been identified yet. */ user_ref?: string; } /** * Common recipient interface for all webhook events. * Represents the Facebook Page that received the event. */ interface WebhookRecipient { /** Facebook Page ID that received the event */ id: string; } /** * Base interface for all webhook events. * Contains the common properties shared by all event types. */ interface BaseWebhookEvent { /** Information about the user who initiated the event */ sender: WebhookSender; /** Information about the page that received the event */ recipient: WebhookRecipient; /** * Unix timestamp when the event occurred (in milliseconds since epoch). * Represents when the action was performed, not when the webhook was sent. */ timestamp: number; } /** * Webhook event types enum with discriminator values. * Used for type narrowing in discriminated unions. */ declare enum WebhookEventType { MESSAGE = "message", MESSAGE_ECHO = "message_echo", MESSAGE_EDIT = "message_edit", MESSAGE_REACTION = "reaction", MESSAGE_READ = "read", MESSAGING_FEEDBACK = "messaging_feedback", MESSAGING_POSTBACK = "postback", FEED = "feed", VIDEOS = "videos", LIVE_VIDEOS = "live_videos" } /** * Generic webhook entry structure. * Represents a single entry in the webhook payload. */ interface WebhookEntry<T extends BaseWebhookEvent = BaseWebhookEvent> { /** Unique ID of the page */ id: string; /** Time of update (epoch time in milliseconds) */ time: number; /** Array of messaging events */ messaging: T[]; } /** * Generic webhook payload structure. * This is the top-level structure received from Facebook webhooks. */ interface WebhookPayload<T extends BaseWebhookEvent = BaseWebhookEvent> { /** Always 'page' for Messenger webhooks */ object: 'page'; /** Array of entry objects containing the actual events */ entry: WebhookEntry<T>[]; } /** * Generic webhook entry structure for Page webhooks (uses 'changes' instead of 'messaging'). * Represents a single entry in a Page webhook payload. */ interface PageWebhookEntry<T = any> { /** Unique ID of the page */ id: string; /** Time of update (epoch time in milliseconds) */ time: number; /** Array of change events */ changes: T[]; } /** * Generic webhook payload structure for Page webhooks. * This is the top-level structure received from Facebook Page webhooks. */ interface PageWebhookPayload<T = any> { /** Always 'page' for Page webhooks */ object: 'page'; /** Array of entry objects containing the actual events */ entry: PageWebhookEntry<T>[]; } /** * Extract all events from a Page webhook payload (uses 'changes' array) * * @param payload - The Page webhook payload to extract events from * @returns Array of Page webhook events */ declare function extractPageEvents<T>(payload: PageWebhookPayload<T>): T[]; /** * Common processing context for all webhook events */ interface BaseProcessingContext { /** The user who initiated the event (PSID or user_ref) */ senderId?: string; /** User reference for anonymous users */ userRef?: string; /** The page that received the event */ recipientId: string; /** When the event occurred */ timestamp: number; /** Whether the sender is identified (has PSID) */ isIdentifiedUser: boolean; /** Human-readable datetime for the event timestamp */ eventDate: Date; } /** * Get event types from a Page webhook payload (uses 'changes' array) * * @param payload - The Page webhook payload to extract event types from * @returns Array of unique WebhookEventType values found in the payload * * @example * ```typescript * const eventTypes = getPageWebhookEventTypes(payload); * console.log('Page events:', eventTypes); // [WebhookEventType.FEED, WebhookEventType.VIDEOS] * * if (eventTypes.includes(WebhookEventType.FEED)) { * // Process feed events * } * ``` */ declare function getPageWebhookEventTypes(payload: PageWebhookPayload): WebhookEventType[]; /** * Facebook Messenger Platform - Message Edits Webhook Types * * These types represent the webhook event structure for message_edits events. * Triggered when a user edits a previously sent message. * * @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/message-edits/ */ /** * Represents the edited message information */ interface MessageEdit { /** * Unique message identifier for the edited message */ mid: string; /** * New message content after the edit. * Contains the updated text of the message. */ text: string; /** * Number of times the message has been edited. * Maximum value is 5 (client-side constraint). */ num_edit: number; } /** * Main webhook event structure for message edits with discriminator * * This event is triggered when a user edits a previously sent message. * The webhook provides the updated message content and edit count. * * @example * ```json * { * "type": "message_edit", * "sender": { * "id": "1234567890123456" * }, * "recipient": { * "id": "9876543210987654" * }, * "timestamp": 1458668856463, * "message_edit": { * "mid": "mid.1458668856218:ed81099e15d3f4f233", * "text": "This is the updated message content", * "num_edit": 2 * } * } * ``` */ interface MessageEditWebhookEvent extends BaseWebhookEvent { /** Discriminator for type narrowing */ type: WebhookEventType.MESSAGE_EDIT; /** Details about the edited message */ message_edit: MessageEdit; } /** * Complete webhook payload structure that includes the message edit event * along with other webhook metadata */ interface MessageEditWebhookPayload extends WebhookPayload<MessageEditWebhookEvent> { } /** * Type guard to check if a webhook event is a message edit event * * @param event - The webhook event to check * @returns True if the event contains a message_edit property * * @example * ```typescript * if (isMessageEditEvent(event)) { * // TypeScript now knows event has message_edit property * console.log(`Message edited ${event.message_edit.num_edit} times`); * } * ``` */ declare function isMessageEditEvent(event: any): event is MessageEditWebhookEvent; /** * Utility type for common message edit properties that might be used in processing */ interface MessageEditProcessingContext extends BaseProcessingContext { /** The edited message ID */ messageId: string; /** Updated message content */ updatedText: string; /** Number of edits made */ editCount: number; } /** * Helper function to extract processing context from a message edit event * * @param event - The message edit webhook event * @returns Simplified processing context * * @example * ```typescript * const context = extractMessageEditContext(webhookEvent); * console.log(`User ${context.senderId} edited message to: "${context.updatedText}"`); * ``` */ declare function extractMessageEditContext(event: MessageEditWebhookEvent): MessageEditProcessingContext; /** * Constants related to message editing limits and constraints */ declare const MESSAGE_EDIT_CONSTANTS: { /** Maximum number of edits allowed per message */ readonly MAX_EDITS: 5; /** Webhook event type identifier */ readonly EVENT_TYPE: "message_edit"; }; /** * Facebook Messenger Platform Message Reactions Webhook Types * * These types define the structure of webhook events received when users * react to messages in Messenger conversations. * * @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/message-reactions */ /** * Types of reactions that can be applied to messages in Messenger. * These are the predefined reaction types supported by Facebook. */ declare enum MessageReactionType { /** Standard like reaction */ LIKE = "like", /** Dislike reaction */ DISLIKE = "dislike", /** Love reaction (heart) */ LOVE = "love", /** Sad reaction */ SAD = "sad", /** Angry reaction */ ANGRY = "angry", /** Wow/surprised reaction */ WOW = "wow", /** Smile/laugh reaction */ SMILE = "smile", /** Other/unrecognized emoji reactions */ OTHER = "other" } /** * Actions that can be performed on message reactions. */ declare enum MessageReactionAction { /** Adding a reaction to a message */ REACT = "react", /** Removing a reaction from a message */ UNREACT = "unreact" } /** * Contains the detailed information about the reaction. */ interface MessageReactionData { /** * The type of reaction applied to the message. * Can be one of the predefined types or "other" for unrecognized emojis. */ reaction: MessageReactionType; /** * The UTF-8 emoji representation of the reaction (optional). * Example: "\u{2764}\u{FE0F}" for heart emoji */ emoji?: string; /** * The action performed - either adding or removing the reaction. */ action: MessageReactionAction; /** * The message ID that the reaction was applied to. * This corresponds to the 'mid' field of the original message. */ mid: string; } /** * Complete webhook event structure for message reactions with discriminator. * This is the main payload received when a user reacts to a message. */ interface MessageReactionWebhookEvent extends BaseWebhookEvent { /** Discriminator for type narrowing */ type: WebhookEventType.MESSAGE_REACTION; /** Detailed information about the reaction */ reaction: MessageReactionData; } /** * The complete webhook payload containing the message reaction event. * This matches the structure of the webhook POST request body. */ interface MessageReactionWebhookPayload extends WebhookPayload<MessageReactionWebhookEvent> { } /** * Context object for processing message reaction webhooks. * Useful for handlers that need additional processing information. */ interface MessageReactionProcessingContext { /** The original webhook event */ event: MessageReactionWebhookEvent; /** Page ID that received the reaction */ pageId: string; /** User ID who performed the reaction */ userId: string; /** ID of the message that was reacted to */ messageId: string; /** Whether this is a new reaction (true) or removal (false) */ isReactionAdded: boolean; /** The type of reaction */ reactionType: MessageReactionType; /** Raw emoji string if available */ emoji?: string; /** Timestamp when the reaction occurred */ timestamp: Date; } /** * Helper type for reaction statistics and aggregation. * Useful for tracking reaction counts on messages. */ interface MessageReactionStats { /** The message ID these stats apply to */ messageId: string; /** Count of each reaction type */ reactions: { [K in MessageReactionType]?: number; }; /** Total number of reactions */ totalReactions: number; /** Last updated timestamp */ lastUpdated: Date; } /** * Configuration options for handling message reaction webhooks. */ interface MessageReactionWebhookConfig { /** Whether to track reaction statistics */ enableStats?: boolean; /** Whether to handle emoji reactions beyond predefined types */ handleCustomEmojis?: boolean; /** Maximum age of reactions to process (in milliseconds) */ maxReactionAge?: number; /** Whether to validate webhook signatures */ validateSignature?: boolean; } /** * Facebook Messenger Platform - Message Reads Webhook Types * * These types represent the webhook event structure for message_reads events. * Triggered when a user reads messages sent by a Page. * * The message_reads webhook event indicates that all messages up to a certain * watermark timestamp have been read by the recipient. * * @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/message-reads/ */ /** * Represents the read receipt information */ interface MessageRead { /** * Watermark timestamp indicating all messages up to this point have been read. * This is a Unix timestamp in milliseconds. * All messages with a timestamp less than or equal to this value have been read. */ watermark: number; } /** * Main webhook event structure for message reads with discriminator * * This event is triggered when a user reads messages sent by a Page. * The watermark indicates the timestamp up to which all messages have been read. * * @example * ```json * { * "type": "read", * "sender": { * "id": "1234567890123456" * }, * "recipient": { * "id": "9876543210987654" * }, * "timestamp": 1458668856463, * "read": { * "watermark": 1458668856253 * } * } * ``` */ interface MessageReadsWebhookEvent extends BaseWebhookEvent { /** Discriminator for type narrowing */ type: WebhookEventType.MESSAGE_READ; /** Read receipt information containing the watermark */ read: MessageRead; } /** * Complete webhook payload structure that includes the message reads event * along with other webhook metadata */ interface MessageReadsWebhookPayload extends WebhookPayload<MessageReadsWebhookEvent> { } /** * Type guard to check if a webhook event is a message reads event * * @param event - The webhook event to check * @returns True if the event contains a read property * * @example * ```typescript * if (isMessageReadsEvent(event)) { * // TypeScript now knows event has read property * console.log(`Messages read up to timestamp: ${event.read.watermark}`); * } * ``` */ declare function isMessageReadsEvent(event: any): event is MessageReadsWebhookEvent; /** * Utility type for extracting just the read data from a webhook event */ type MessageReadData = MessageRead; /** * Utility type for common message reads properties that might be used in processing */ interface MessageReadsProcessingContext { /** The user who read the messages */ senderId: string; /** The page that sent the messages */ recipientId: string; /** Timestamp up to which all messages have been read */ watermarkTimestamp: number; /** When the read event occurred */ readTimestamp: number; /** * Human-readable datetime for the watermark timestamp. * Useful for logging and debugging. */ watermarkDate: Date; /** * Human-readable datetime for the read event timestamp. * Useful for logging and debugging. */ readDate: Date; } /** * Helper function to extract processing context from a message reads event * * @param event - The message reads webhook event * @returns Simplified processing context with additional computed fields * * @example * ```typescript * const context = extractMessageReadsContext(webhookEvent); * console.log(`User ${context.senderId} read messages up to ${context.watermarkDate.toISOString()}`); * ``` */ declare function extractMessageReadsContext(event: MessageReadsWebhookEvent): MessageReadsProcessingContext; /** * Helper function to check if a specific message timestamp was read * * @param messageTimestamp - The timestamp of the message to check * @param watermark - The watermark timestamp from the read event * @returns True if the message with the given timestamp has been read * * @example * ```typescript * const messageTime = 1458668855000; * const watermark = 1458668856253; * * if (isMessageRead(messageTime, watermark)) { * console.log('This message has been read'); * } * ``` */ declare function isMessageRead(messageTimestamp: number, watermark: number): boolean; /** * Helper function to determine which messages in a list have been read * * @param messages - Array of messages with timestamp property * @param watermark - The watermark timestamp from the read event * @returns Array of messages that have been read * * @example * ```typescript * const messages = [ * { id: '1', timestamp: 1458668855000, text: 'Hello' }, * { id: '2', timestamp: 1458668857000, text: 'World' } * ]; * const watermark = 1458668856253; * * const readMessages = getReadMessages(messages, watermark); * // Returns only the first message as it's before the watermark * ``` */ declare function getReadMessages<T extends { timestamp: number; }>(messages: T[], watermark: number): T[]; /** * Helper function to get the count of read messages from a list * * @param messages - Array of messages with timestamp property * @param watermark - The watermark timestamp from the read event * @returns Number of messages that have been read * * @example * ```typescript * const messages = [ * { id: '1', timestamp: 1458668855000 }, * { id: '2', timestamp: 1458668857000 } * ]; * const watermark = 1458668856253; * * const readCount = getReadMessageCount(messages, watermark); * // Returns 1 * ``` */ declare function getReadMessageCount<T extends { timestamp: number; }>(messages: T[], watermark: number): number; /** * Constants related to message reads functionality */ declare const MESSAGE_READS_CONSTANTS: { /** Webhook event type identifier */ readonly EVENT_TYPE: "message_reads"; /** * Property name in the webhook event that contains read data. * Used for type guards and event identification. */ readonly READ_PROPERTY: "read"; }; /** * Type for the watermark timestamp * Represents a Unix timestamp in milliseconds indicating read status */ type WatermarkTimestamp = number; /** * Facebook Messenger Platform - Messaging Postbacks Webhook Types * * These types represent the webhook event structure for messaging_postbacks events. * Triggered when a user clicks on a postback button, Get Started button, or persistent menu item. * * @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_postbacks */ /** * Represents referral information for postbacks that originated from external sources * * This object is included when a postback is triggered as part of a conversation * that was started via m.me links, Click to Messenger ads, Messenger QR codes, * or the Welcome Screen. */ interface PostbackReferral { /** * Arbitrary data that was included in the original referral. * This is the custom parameter you set when creating the referral link. */ ref?: string; /** * Source of the referral. Indicates how the conversation was initiated. * Common values include: * - "SHORTLINK" - from m.me links * - "ADS" - from Click to Messenger ads * - "MESSENGER_CODE" - from Messenger QR codes */ source?: string; ad_id?: string; ads_context_data?: { ad_title?: string; photo_url?: string; video_url?: string; post_id?: string; }; /** * Type of referral action that initiated the conversation. * Common value is "OPEN_THREAD" for most referral types. */ type?: string; } /** * Represents the postback data in a messaging postback webhook event */ interface PostbackData { /** * Message ID associated with the postback. * Unique identifier for the message that contained the postback button. */ mid?: string; /** * Title of the postback button that was clicked. * This is the user-visible text that was displayed on the button. */ title?: string; /** * Developer-defined payload that was associated with the postback button. * This contains the custom data you specified when creating the button. * Maximum length is 1000 characters. */ payload: string; /** * Referral information if the postback is part of a referred conversation. * Only present when the conversation was initiated through external sources * like m.me links, ads, QR codes, or Welcome Screen. */ referral?: PostbackReferral; } /** * Main webhook event structure for messaging postbacks with discriminator * * This event is triggered when a user interacts with postback buttons, * including regular postback buttons, Get Started button, and persistent menu items. * * @example * Basic postback from a button click: * ```json * { * "type": "postback", * "sender": { * "id": "1234567890123456" * }, * "recipient": { * "id": "9876543210987654" * }, * "timestamp": 1527459824, * "postback": { * "mid": "m_AG5Hz2Uq7tuwNEhXfYYKj8mJEM_QPpz5jdHtHaW", * "title": "Get Started", * "payload": "GET_STARTED_PAYLOAD" * } * } * ``` * * @example * Postback with referral data from m.me link: * ```json * { * "type": "postback", * "sender": { * "user_ref": "unique_ref_param" * }, * "recipient": { * "id": "9876543210987654" * }, * "timestamp": 1527459824, * "postback": { * "title": "Contact Sales", * "payload": "CONTACT_SALES", * "referral": { * "ref": "landing_page_ad_campaign", * "source": "SHORTLINK", * "type": "OPEN_THREAD" * } * } * } * ``` */ interface MessagingPostbackWebhookEvent extends BaseWebhookEvent { /** Discriminator for type narrowing */ type: WebhookEventType.MESSAGING_POSTBACK; /** Details about the postback that was triggered */ postback: PostbackData; } /** * Complete webhook payload structure that includes the messaging postback event * along with other webhook metadata */ interface MessagingPostbackWebhookPayload extends WebhookPayload<MessagingPostbackWebhookEvent> { } /** * Type guard to check if a webhook event is a messaging postback event * * @param event - The webhook event to check * @returns True if the event contains a postback property * * @example * ```typescript * if (isMessagingPostbackEvent(event)) { * // TypeScript now knows event has postback property * console.log(`User clicked: ${event.postback.title}`); * console.log(`Payload: ${event.postback.payload}`); * } * ``` */ declare function isMessagingPostbackEvent(event: any): event is MessagingPostbackWebhookEvent; /** * Type guard to check if a postback event includes referral data * * @param event - The messaging postback event to check * @returns True if the event contains referral information * * @example * ```typescript * if (hasReferralData(event)) { * // Handle referred conversation * console.log(`Referred from: ${event.postback.referral.source}`); * console.log(`Ref parameter: ${event.postback.referral.ref}`); * } * ``` */ declare function hasReferralData(event: MessagingPostbackWebhookEvent): event is MessagingPostbackWebhookEvent & { postback: PostbackData & { referral: PostbackReferral; }; }; /** * Type guard to check if sender is identified (has PSID) vs anonymous (has user_ref) * * @param sender - The sender object to check * @returns True if sender has a PSID (is identified) * * @example * ```typescript * if (isIdentifiedSender(event.sender)) { * // User has been identified and has a PSID * console.log(`User PSID: ${event.sender.id}`); * } else { * // Anonymous user with user_ref (likely from chat plugin) * console.log(`Anonymous user ref: ${event.sender.user_ref}`); * } * ``` */ declare function isIdentifiedSender(sender: WebhookSender): sender is WebhookSender & { id: string; }; /** * Utility type for extracting just the postback data from a webhook event */ type PostbackEventData = PostbackData; /** * Utility type for common postback properties that might be used in processing */ interface PostbackProcessingContext { /** The postback payload data */ payload: string; /** The user who t