@warriorteam/messenger-sdk
Version:
TypeScript SDK for Facebook Messenger Platform API
1,633 lines (1,605 loc) • 70.9 kB
TypeScript
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