UNPKG

@warriorteam/messenger-sdk

Version:

TypeScript SDK for Facebook Messenger Platform API

1,633 lines (1,605 loc) 70.9 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; 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$1 { 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'; type MessagingType = 'RESPONSE' | 'UPDATE' | 'MESSAGE_TAG'; interface SendMessageRequest { recipient: Recipient; messaging_type: MessagingType; message?: Message$1; sender_action?: SenderAction; 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): Promise<SendMessageResponse>; typingOn(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; typingOff(recipientId: string, options?: APIOptions): Promise<SendMessageResponse>; markSeen(recipientId: 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>; } 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; 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_EDIT = "message_edit", MESSAGE_REACTION = "reaction", MESSAGE_READ = "read", MESSAGING_FEEDBACK = "messaging_feedback", MESSAGING_POSTBACK = "postback" } /** * 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>[]; } /** * 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; } /** * 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; /** * 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 triggered the postback (PSID or user_ref) */ senderId?: string; /** User reference for anonymous users */ userRef?: string; /** The page that received the postback */ recipientId: string; /** Button title if available */ buttonTitle?: string; /** Message ID if available */ messageId?: string; /** When the postback occurred */ timestamp: number; /** Referral context if present */ referralContext?: { ref?: string; source?: string; type?: string; }; /** Whether this is from a referred conversation */ isReferred: boolean; /** Whether the sender is identified (has PSID) */ isIdentifiedUser: boolean; } /** * Helper function to extract processing context from a messaging postback event * * @param event - The messaging postback webhook event * @returns Simplified processing context with all relevant data * * @example * ```typescript * const context = extractPostbackContext(webhookEvent); * * if (context.isReferred) { * console.log(`New conversation from ${context.referralContext?.source}`); * } * * if (context.isIdentifiedUser) { * console.log(`Known user ${context.senderId} clicked: ${context.payload}`); * } else { * console.log(`Anonymous user ${context.userRef} clicked: ${context.payload}`); * } * ``` */ declare function extractPostbackContext(event: MessagingPostbackWebhookEvent): PostbackProcessingContext; /** * Common postback payload patterns used in Messenger bots */ declare const COMMON_POSTBACK_PAYLOADS: { /** Get Started button payload */ readonly GET_STARTED: "GET_STARTED"; /** Main menu navigation */ readonly MAIN_MENU: "MAIN_MENU"; /** Help/Support options */ readonly HELP: "HELP"; readonly SUPPORT: "SUPPORT"; /** Contact information */ readonly CONTACT: "CONTACT"; readonly CONTACT_SALES: "CONTACT_SALES"; readonly CONTACT_SUPPORT: "CONTACT_SUPPORT"; /** Navigation actions */ readonly BACK: "BACK"; readonly NEXT: "NEXT"; readonly CANCEL: "CANCEL"; /** User preferences */ readonly SETTINGS: "SETTINGS"; readonly PREFERENCES: "PREFERENCES"; }; /** * Constants related to postback events and constraints */ declare const POSTBACK_CONSTANTS: { /** Maximum payload length in characters */ readonly MAX_PAYLOAD_LENGTH: 1000; /** Webhook event type identifier */ readonly EVENT_TYPE: "postback"; /** Common referral sources */ readonly REFERRAL_SOURCES: { readonly SHORTLINK: "SHORTLINK"; readonly ADS: "ADS"; readonly MESSENGER_CODE: "MESSENGER_CODE"; }; /** Common referral types */ readonly REFERRAL_TYPES: { readonly OPEN_THREAD: "OPEN_THREAD"; }; }; /** * Type for postback payload values - can be custom strings or common patterns */ type PostbackPayload = string | typeof COMMON_POSTBACK_PAYLOADS[keyof typeof COMMON_POSTBACK_PAYLOADS]; /** * Type for referral sources */ type ReferralSource$1 = typeof POSTBACK_CONSTANTS.REFERRAL_SOURCES[keyof typeof POSTBACK_CONSTANTS.REFERRAL_SOURCES] | string; /** * Type for referral types */ type ReferralType$1 = typeof POSTBACK_CONSTANTS.REFERRAL_TYPES[keyof typeof POSTBACK_CONSTANTS.REFERRAL_TYPES] | string; /** * Facebook Messenger Platform - Customer Feedback Webhook Types * * These types represent the webhook event structure for messaging_feedback events. * Triggered when a user submits feedback through a Customer Feedback Template. * * @see https://developers.facebook.com/docs/messenger-platform/send-messages/templates/customer-feedback-template */ /** * Available feedback types for customer feedback templates */ declare enum FeedbackType { /** Customer Satisfaction - Score range 1-5 */ CSAT = "csat", /** Net Promoter Score - Score range 0-10 */ NPS = "nps", /** Customer Effort Score - Score range 1-7 */ CES = "ces" } /** * Available display options for CSAT feedback type */ declare enum CSATDisplayOption { /** Numeric scale from 1 to 5 */ ONE_TO_FIVE = "one_to_five", /** Five star rating display */ FIVE_STARS = "five_stars", /** Five emoji rating display */ FIVE_EMOJIS = "five_emojis" } /** * Available display options for NPS feedback type */ declare enum NPSDisplayOption { /** Numeric scale from 0 to 10 */ ZERO_TO_TEN = "zero_to_ten" } /** * Available display options for CES feedback type */ declare enum CESDisplayOption { /** Numeric scale from 1 to 7 */ ONE_TO_SEVEN = "one_to_seven" } /** * Follow-up feedback type for optional text input */ declare enum FollowUpType { /** Free-form text input (max 400 characters) */ FREE_FORM = "free_form" } /** * Represents optional follow-up feedback data */ interface FeedbackFollowUp { /** Type of follow-up feedback - currently only supports free_form */ type: FollowUpType.FREE_FORM; /** * User-provided text feedback. * Limited to 400 characters maximum. */ payload: string; } /** * Represents individual question feedback data within a screen */ interface FeedbackQuestion { /** * Type of feedback question (CSAT, NPS, or CES). * Determines the scoring range and display format. */ type: FeedbackType; /** * Numeric score provided by the user. * Range depends on feedback type: * - CSAT: 1-5 * - NPS: 0-10 * - CES: 1-7 */ payload: string; /** * Optional follow-up text feedback from the user. * Only present if the template included a text input field. */ follow_up?: FeedbackFollowUp; } /** * Represents a feedback screen containing questions and responses */ interface FeedbackScreen { /** * Screen identifier within the feedback template. * Typically 0 for single-screen templates. */ screen_id: number; /** * Map of question IDs to their corresponding feedback responses. * Question IDs are defined when creating the feedback template. */ questions: Record<string, FeedbackQuestion>; } /** * Main messaging feedback data structure */ interface MessagingFeedbackData { /** * Array of feedback screens with user responses. * Each screen contains questions and their answers. */ feedback_screens: FeedbackScreen[]; } /** * Main webhook event structure for messaging feedback with discriminator * * This event is triggered when a user submits feedback through a * Customer Feedback Template. The webhook provides the user's * scores and optional text feedback. * * @example * ```json * { * "type": "messaging_feedback", * "sender": { * "id": "1234567890123456" * }, * "recipient": { * "id": "9876543210987654" * }, * "timestamp": 1458668856463, * "messaging_feedback": { * "feedback_screens": [{ * "screen_id": 0, * "questions": { * "satisfaction_q1": { * "type": "csat", * "payload": "4", * "follow_up": { * "type": "free_form", * "payload": "Good service overall!" * } * } * } * }] * } * } * ``` */ interface MessagingFeedbackWebhookEvent extends BaseWebhookEvent { /** Discriminator for type narrowing */ type: WebhookEventType.MESSAGING_FEEDBACK; /** The actual feedback data containing user responses */ messaging_feedback: MessagingFeedbackData; } /** * Complete webhook payload structure that includes the messaging feedback event * along with other webhook metadata */ interface MessagingFeedbackWebhookPayload extends WebhookPayload<MessagingFeedbackWebhookEvent> { } /** * Type guard to check if a webhook event is a messaging feedback event * * @param event - The webhook event to check * @returns True if the event contains a messaging_feedback property * * @example * ```typescript * if (isMessagingFeedbackEvent(event)) { * // TypeScript now knows event has messaging_feedback property * console.log(`Received feedback with ${event.messaging_feedback.feedback_screens.length} screens`); * } * ``` */ declare function isMessagingFeedbackEvent(event: any): event is MessagingFeedbackWebhookEvent; /** * Utility type for common feedback properties that might be used in processing */ interface MessagingFeedbackProcessingContext { /** The user who submitted the feedback */ senderId: string; /** The page that received the feedback */ recipientId: string; /** When the feedback was submitted */ submissionTimestamp: number; /** Total number of feedback screens */ screenCount: number; /** All question responses flattened from all screens */ allResponses: Array<{ questionId: string; feedbackType: FeedbackType; score: number; textFeedback?: string; screenId: number; }>; } /** * Helper function to extract processing context from a messaging feedback event * * @param event - The messaging feedback webhook event * @returns Simplified processing context with flattened responses * * @example * ```typescript * const context = extractMessagingFeedbackContext(webhookEvent); * console.log(`User ${context.senderId} submitted ${context.allResponses.length} feedback responses`); * context.allResponses.forEach(response => { * console.log(`${response.questionId}: ${response.score}/10 (${response.feedbackType})`); * }); * ``` */ declare function extractMessagingFeedbackContext(event: MessagingFeedbackWebhookEvent): MessagingFeedbackProcessingContext; /** * Helper function to get feedback scores by type from an event * * @param event - The messaging feedback webhook event * @returns Map of feedback types to their scores * * @example * ```typescript * const scores = getFeedbackScoresByType(webhookEvent); * const csatScore = scores.get(FeedbackType.CSAT); // number | undefined * const npsScore = scores.get(FeedbackType.NPS); // number | undefined * ``` */ declare function getFeedbackScoresByType(event: MessagingFeedbackWebhookEvent): Map<FeedbackType, number[]>; /** * Helper function to extract all text feedback from an event * * @param event - The messaging feedback webhook event * @returns Array of text feedback strings * * @example * ```typescript * const textFeedback = extractTextFeedback(webhookEvent); * textFeedback.forEach(feedback => { * console.log(`User comment: "${feedback}"`); * }); * ``` */ declare function extractTextFeedback(event: MessagingFeedbackWebhookEvent): string[]; /** * Constants related to customer feedback constraints and limits */ declare const MESSAGING_FEEDBACK_CONSTANTS: { /** Maximum characters allowed in free-form text feedback */ readonly MAX_TEXT_FEEDBACK_LENGTH: 400; /** Score ranges for different feedback types */ readonly SCORE_RANGES: { readonly csat: { readonly min: 1; readonly max: 5; }; readonly nps: { readonly min: 0; readonly max: 10; }; readonly ces: { readonly min: 1; readonly max: 7; }; }; /** Template expiry constraints */ readonly TEMPLATE_EXPIRY: { /** Minimum expiry days */ readonly MIN_DAYS: 1; /** Maximum expiry days */ readonly MAX_DAYS: 7; /** Default expiry days */ readonly DEFAULT_DAYS: 1; }; /** Question ID constraints */ readonly QUESTION_ID: { /** Maximum length for question IDs */ readonly MAX_LENGTH: 80; /** Valid characters pattern (alphanumeric) */ readonly VALID_PATTERN: RegExp; }; /** Template limits */ readonly TEMPLATE_LIMITS: { /** Maximum number of titles per template */ readonly MAX_TITLES: 1; /** Maximum number of scoring components per template */ readonly MAX_SCORING_COMPONENTS: 1; }; /** Webhook event type identifier */ readonly EVENT_TYPE: "messaging_feedback"; }; /** * Validation helper to check if a score is valid for a given feedback type * * @param feedbackType - The type of feedback being validated * @param score - The score to validate * @returns True if the score is within the valid range for the feedback type * * @example * ```typescript * const isValid = isValidFeedbackScore(FeedbackType.CSAT, 4); // true * const isInvalid = isValidFeedbackScore(FeedbackType.NPS, 15); // false * ``` */ declare function isValidFeedbackScore(feedbackType: FeedbackType, score: number): boolean; /** * Validation helper to check if a question ID is valid * * @param questionId - The question ID to validate * @returns True if the question ID meets the format requirements * * @example * ```typescript * const isValid = isValidQuestionId('satisfaction_q1'); // true * const isInvalid = isValidQuestionId('invalid-id!'); // false * ``` */ declare function isValidQuestionId(questionId: string): boolean; /** * Validation helper to check if text feedback is within character limits * * @param textFeedback - The text feedback to validate * @returns True if the text is within the character limit * * @example * ```typescript * const isValid = isValidTextFeedback('Great service!'); // true * const isInvalid = isValidTextFeedback('a'.repeat(500)); // false * ``` */ declare function isValidTextFeedback(textFeedback: string): boolean; /** * Facebook Messenger Platform - Messages Webhook Types * * These types represent the webhook event structure for messages events. * Triggered when a user sends a message to your page. * * @see https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messages */ /** * Enumeration of attachment types supported by the Messenger Platform */ declare enum AttachmentType { AUDIO = "audio", FILE = "file", IMAGE = "image", VIDEO = "video", FALLBACK = "fallback", REEL = "reel", IG_REEL = "ig_reel" } /** * Enumeration of referral types for message referrals */ declare enum ReferralType { OPEN_THREAD = "OPEN_THREAD", PRODUCT = "product", ADS = "ads" } /** * Enumeration of referral sources */ declare enum ReferralSource { MESSENGER_CODE = "MESSENGER_CODE", DISCOVER_TAB = "DISCOVER_TAB", ADS = "ADS", SHORTLINK = "SHORTLINK", CUSTOMER_CHAT_PLUGIN = "CUSTOMER_CHAT_PLUGIN" } /** * Represents a quick reply payload in a message */ interface QuickReply { /** * The payload string that was defined when the quick reply was sent. * Maximum 1000 characters. */ payload: string; } /** * Represents the reply-to information when a message is a reply */ interface ReplyTo { /** * Message ID of the message being replied to */ mid: string; } /** * Base attachment payload interface */ interface BaseAttachmentPayload { /** URL to the attachment file */ url: string; } /** * Attachment payload for media files (audio, image, video, file) */ interface MediaAttachmentPayload extends BaseAttachmentPayload { /** URL to the attachment file */ url: string; /** Title of the attachment, if available */ title?: string; } /** * Attachment payload for sticker attachments */ interface StickerAttachmentPayload extends BaseAttachmentPayload { /** URL to the sticker image */ url: string; /** Sticker ID for the sent sticker */ sticker_id: number; } /** * Attachment payload for reel attachments (Instagram Reels, Facebook Reels) */ interface ReelAttachmentPayload extends BaseAttachmentPayload { /** URL to the reel */ url: string; /** Video ID of the reel */ reel_video_id?: number; } /** * Attachment payload for fallback attachments */ interface FallbackAttachmentPayload extends BaseAttachmentPayload { /** URL to the attachment */ url: string; /** Title of the fallback attachment */ title?: string; } /** * Union type for all possible attachment payload types */ type AttachmentPayload = MediaAttachmentPayload | StickerAttachmentPayload | ReelAttachmentPayload | FallbackAttachmentPayload; /** * Represents an attachment in a message */ interface MessageAttachment { /** The type of attachment */ type: AttachmentType; /** The attachment payload containing the actual attachment data */ payload: AttachmentPayload; } /** * Represents referral data in a message (for referral campaigns, ads, etc.) */ interface MessageReferral { /** The source of the referral */ source: ReferralSource; /** The type of referral */ type: ReferralType; /** * The optional ref parameter passed in the referral. * Maximum 250 characters. */ ref?: string; /** * URL of the website where the referral was triggered. * Only present for CUSTOMER_CHAT_PLUGIN source. */ referer_uri?: string; /** * Indicates whether the referral is from a gues